audioBox.vue 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. <template>
  2. <view class="global-voice-box">
  3. <view class="flex small-box" v-if="!showBig" @click.prevent="showBig=true">
  4. <view style="flex:1;overflow: hidden;">
  5. <view class="van-ellipsis">{{title}}</view>
  6. <view class="time" style="font-size:24rpx;color:#666">时长 {{audioTime|formatVoiceTime}}</view>
  7. </view>
  8. <image
  9. class="pause-img"
  10. :src="play?require('@/static/audio-doing.png'):require('@/static/audio-pause-3.png')"
  11. mode="aspectFill"
  12. @click.stop="handleChangePlayStatus"
  13. />
  14. <van-icon @click.stop="handleClosePopAudio" name="cross" size="18" color="#BBC3C9"/>
  15. <van-progress
  16. color="#D4AC78"
  17. track-color="#fff"
  18. :show-pivot="false"
  19. stroke-width="2px"
  20. custom-class="bot-progress"
  21. :percentage="percentage"
  22. />
  23. </view>
  24. <view class="big-box" v-else>
  25. <view class="flex top" style="overflow: hidden;">
  26. <van-icon name="arrow-down" size="18" color="#BBC3C9" @click="showBig=false" />
  27. <view class="van-ellipsis" style="flex:1;margin:0 10rpx;text-align:center">{{title}}</view>
  28. <van-icon @click.stop="handleClosePopAudio" name="cross" size="18" color="#BBC3C9"/>
  29. </view>
  30. <view class="flex center">
  31. <image
  32. class="pause-img"
  33. :src="play?require('@/static/audio-doing.png'):require('@/static/audio-pause-3.png')"
  34. mode="aspectFill"
  35. @click.stop="handleChangePlayStatus"
  36. />
  37. <text class="time">{{curTime|formatVoiceTime}}</text>
  38. <slider
  39. activeColor="#e3b377"
  40. :max="audioTime"
  41. :value="curTime"
  42. @change="handleAudioSliderChange($event)"
  43. block-size="16"
  44. class="slider"
  45. />
  46. <text class="time">{{audioTime|formatVoiceTime}}</text>
  47. </view>
  48. </view>
  49. </view>
  50. </template>
  51. <script>
  52. export default {
  53. filters:{
  54. formatVoiceTime(e){
  55. let m=parseInt(e/60)
  56. let s=parseInt(e%60)
  57. return `${m>9?m:'0'+m}:${s>9?s:'0'+s}`
  58. }
  59. },
  60. computed: {
  61. audioData(){
  62. return this.$store.state.audio
  63. },
  64. //用户监听音频是否变化了 是否需要初始化
  65. audioInit(){
  66. return {
  67. reportId:this.$store.state.audio.reportId,
  68. voiceId:this.$store.state.audio.voiceId,
  69. }
  70. },
  71. percentage(){
  72. return parseInt((this.curTime/this.audioTime)*100)
  73. },
  74. reportAudioShow(){
  75. return this.$store.state.report.audioData.show
  76. }
  77. },
  78. watch:{
  79. audioInit:{
  80. handler(nval){
  81. console.log(nval);
  82. this.init()
  83. },
  84. immediate:true
  85. },
  86. showBig:{
  87. handler(nval){
  88. this.$store.commit('audio/showBig',nval)
  89. },
  90. immediate:true
  91. }
  92. },
  93. data() {
  94. return {
  95. showBig:false,
  96. curTime:0,
  97. audioTime:0,//当前音频总时长
  98. title:'',//当前音频标题
  99. play:false
  100. }
  101. },
  102. methods: {
  103. init(){
  104. console.log('audioBox init');
  105. let delyTime=0
  106. if(this.$store.state.report.audioData.show){
  107. this.globalBgMusic.stop()
  108. delyTime=300
  109. }
  110. console.log('audioBox init',delyTime);
  111. const curAudio=this.$store.state.audio.list[this.$store.state.audio.index]
  112. setTimeout(() => {
  113. if(this.globalBgMusic.src!=curAudio.url){
  114. this.globalBgMusic.src=curAudio.url
  115. this.globalBgMusic.title=curAudio.title
  116. }
  117. this.audioTime=curAudio.time
  118. this.title=curAudio.title
  119. this.curTime=parseInt(this.globalBgMusic.currentTime)
  120. this.play=!this.globalBgMusic.paused
  121. this.listenAudio()
  122. }, delyTime);
  123. },
  124. //音频播放事件
  125. listenAudio(){
  126. console.log('设置监听事件');
  127. this.globalBgMusic.onPlay(()=>{
  128. console.log('开始播放');
  129. this.play=true
  130. this.$store.commit('audio/updateAudioPause',false)
  131. })
  132. this.globalBgMusic.onPause(()=>{
  133. console.log('音频暂停');
  134. this.play=false
  135. this.$store.commit('audio/updateAudioPause',true)
  136. })
  137. this.globalBgMusic.onStop(()=>{
  138. console.log('音频停止');
  139. this.$store.commit('audio/removeAudio')
  140. })
  141. this.globalBgMusic.onEnded(()=>{
  142. console.log('音频onEnded');
  143. const index=this.$store.state.audio.index
  144. if(index==this.$store.state.audio.list.length-1){
  145. this.$store.commit('audio/removeAudio')
  146. }else{
  147. this.handleAudioChange('next')
  148. }
  149. })
  150. this.globalBgMusic.onError((e)=>{
  151. console.log('音频onError',e);
  152. this.$store.commit('audio/removeAudio')
  153. uni.showToast({
  154. title: '音频播放错误',
  155. icon: 'none'
  156. })
  157. })
  158. this.globalBgMusic.onTimeUpdate(()=>{
  159. // console.log('时间更新');
  160. this.curTime=parseInt(this.globalBgMusic.currentTime)
  161. this.$store.commit('audio/updateAudioTime',this.curTime)
  162. })
  163. },
  164. //关闭弹窗停止播放的音频
  165. handleClosePopAudio(){
  166. this.globalBgMusic.stop()
  167. },
  168. //音频切换(暂时没有用到因为都是一个音频 如果后期有多个 直接在页面dom调用此方法即可)
  169. handleAudioChange(type){
  170. let temIndex=this.$store.state.report.audioData.index
  171. if(type=='before'){
  172. if(temIndex>0){
  173. let index=temIndex-1
  174. this.$store.commit('audio/updateAudioIndex', index)
  175. this.init()
  176. }
  177. }else{
  178. if(temIndex<this.$store.state.report.audioData.list.length-1){
  179. let index=temIndex+1
  180. this.$store.commit('audio/updateAudioIndex', index)
  181. this.init()
  182. }
  183. }
  184. },
  185. //拖动进度条
  186. handleAudioSliderChange(e){
  187. const value=e.detail.value
  188. this.globalBgMusic.seek(value)
  189. },
  190. //音频点击暂停播放
  191. handleChangePlayStatus(){
  192. if(!this.globalBgMusic.paused){
  193. this.globalBgMusic.pause()
  194. }else{
  195. this.globalBgMusic.play()
  196. }
  197. },
  198. },
  199. }
  200. </script>
  201. <style>
  202. .bot-progress{
  203. position: absolute;
  204. bottom: 0;
  205. left: 0;
  206. right: 0;
  207. }
  208. </style>
  209. <style lang="scss" scoped>
  210. .global-voice-box{
  211. position: fixed;
  212. background: #FFFFFF;
  213. border: 1px solid #E4E4E4;
  214. box-shadow: 0px 0px 40rpx rgba(50, 35, 17, 0.25);
  215. left: 20rpx;
  216. right: 20rpx;
  217. bottom: calc(130rpx + constant(safe-area-inset-bottom));
  218. bottom: calc(130rpx + env(safe-area-inset-bottom));
  219. z-index: 99;
  220. .small-box{
  221. padding: 18rpx 48rpx 18rpx 20rpx;
  222. position: relative;
  223. align-items: center;
  224. .pause-img{
  225. width: 60rpx;
  226. height: 60rpx;
  227. margin-right: 44rpx;
  228. margin-left: 30rpx;
  229. flex-shrink: 0;
  230. }
  231. }
  232. .big-box{
  233. padding: 33rpx 30rpx;
  234. .center{
  235. align-items: center;
  236. margin-top: 20rpx;
  237. .time{
  238. font-size: 24rpx;
  239. }
  240. .pause-img{
  241. width: 60rpx;
  242. height: 60rpx;
  243. margin-right: 34rpx;
  244. }
  245. .slider{
  246. flex: 1;
  247. }
  248. }
  249. }
  250. }
  251. </style>