建材商城系统20241014
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

188 lines
3.9 KiB

  1. <template>
  2. <view class="voice-content">
  3. <view class="voice-item">
  4. <view class="voice-icon">
  5. <uv-icon name="mic" size="40rpx" color="#D03F25"></uv-icon>
  6. </view>
  7. <view class="voice-info">
  8. <text class="voice-desc">通过语音识别下单</text>
  9. <text class="voice-tip">点击播放语音内容</text>
  10. </view>
  11. <view class="voice-play" @click="playVoice">
  12. <uv-icon :name="isPlaying ? 'pause-circle-fill' : 'play-circle-fill'" size="50rpx" color="#D03F25"></uv-icon>
  13. </view>
  14. </view>
  15. </view>
  16. </template>
  17. <script>
  18. export default {
  19. name: 'VoicePlayer',
  20. props: {
  21. voiceUrl: {
  22. type: String,
  23. default: ''
  24. },
  25. autoPlay: {
  26. type: Boolean,
  27. default: false
  28. }
  29. },
  30. data() {
  31. return {
  32. innerAudioContext: null, // 音频播放器
  33. isPlaying: false // 是否正在播放语音
  34. };
  35. },
  36. mounted() {
  37. this.initAudioPlayer();
  38. },
  39. beforeDestroy() {
  40. this.destroyAudioPlayer();
  41. },
  42. methods: {
  43. // 初始化音频播放器
  44. initAudioPlayer() {
  45. this.innerAudioContext = uni.createInnerAudioContext();
  46. // 监听播放结束事件
  47. this.innerAudioContext.onEnded(() => {
  48. console.log('播放结束');
  49. this.isPlaying = false;
  50. this.$emit('playEnded');
  51. });
  52. // 监听播放开始事件
  53. this.innerAudioContext.onPlay(() => {
  54. console.log('开始播放');
  55. this.isPlaying = true;
  56. this.$emit('playStarted');
  57. });
  58. // 监听播放暂停事件
  59. this.innerAudioContext.onPause(() => {
  60. console.log('播放暂停');
  61. this.isPlaying = false;
  62. this.$emit('playPaused');
  63. });
  64. // 监听播放停止事件
  65. this.innerAudioContext.onStop(() => {
  66. console.log('播放停止');
  67. this.isPlaying = false;
  68. this.$emit('playStopped');
  69. });
  70. // 监听播放错误事件
  71. this.innerAudioContext.onError((err) => {
  72. console.error('播放错误', err);
  73. uni.showToast({
  74. title: '播放失败',
  75. icon: 'none'
  76. });
  77. this.isPlaying = false;
  78. this.$emit('playError', err);
  79. });
  80. },
  81. // 销毁音频播放器
  82. destroyAudioPlayer() {
  83. if (this.innerAudioContext) {
  84. this.innerAudioContext.destroy();
  85. this.innerAudioContext = null;
  86. }
  87. },
  88. // 播放语音
  89. playVoice() {
  90. if (!this.voiceUrl) {
  91. uni.showToast({
  92. title: '语音文件不存在',
  93. icon: 'none'
  94. });
  95. return;
  96. }
  97. if (this.isPlaying) {
  98. // 如果正在播放,则停止播放
  99. this.innerAudioContext.stop();
  100. this.isPlaying = false;
  101. return;
  102. }
  103. // 设置音频源并播放
  104. this.innerAudioContext.src = this.voiceUrl;
  105. this.innerAudioContext.play();
  106. uni.showToast({
  107. title: '正在播放语音',
  108. icon: 'none'
  109. });
  110. },
  111. // 停止播放
  112. stopPlay() {
  113. if (this.innerAudioContext && this.isPlaying) {
  114. this.innerAudioContext.stop();
  115. }
  116. },
  117. // 暂停播放
  118. pausePlay() {
  119. if (this.innerAudioContext && this.isPlaying) {
  120. this.innerAudioContext.pause();
  121. }
  122. }
  123. }
  124. }
  125. </script>
  126. <style scoped lang="scss">
  127. .voice-content {
  128. padding: 30rpx;
  129. .voice-item {
  130. display: flex;
  131. align-items: center;
  132. padding: 30rpx;
  133. background-color: #f9f9f9;
  134. border-radius: 12rpx;
  135. .voice-icon {
  136. width: 80rpx;
  137. height: 80rpx;
  138. background-color: rgba(208, 63, 37, 0.1);
  139. border-radius: 40rpx;
  140. display: flex;
  141. align-items: center;
  142. justify-content: center;
  143. margin-right: 30rpx;
  144. }
  145. .voice-info {
  146. flex: 1;
  147. .voice-desc {
  148. display: block;
  149. font-size: 30rpx;
  150. color: #333;
  151. margin-bottom: 8rpx;
  152. }
  153. .voice-tip {
  154. font-size: 24rpx;
  155. color: #999;
  156. }
  157. }
  158. .voice-play {
  159. width: 80rpx;
  160. height: 80rpx;
  161. display: flex;
  162. align-items: center;
  163. justify-content: center;
  164. background-color: rgba(208, 63, 37, 0.1);
  165. border-radius: 40rpx;
  166. }
  167. }
  168. }
  169. </style>