audioBox.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  1. <template>
  2. <!-- <view class="pop-audio-box">
  3. <view class="name">{{title}}</view>
  4. <view class="flex">
  5. <text>{{currentTime|formatVoiceTime}}</text>
  6. <slider
  7. activeColor="#e3b377"
  8. :max="audioTime"
  9. :value="currentTime"
  10. @change="handleAudioSliderChange($event)"
  11. block-size="16"
  12. class="slider"
  13. />
  14. <text>{{audioTime|formatVoiceTime}}</text>
  15. <image
  16. class="small-img"
  17. :src="play?'../static/audio-play.png':'../static/audio-pause.png'"
  18. mode="aspectFill"
  19. v-if="audioData.list.length==1"
  20. @click="handleChangePlayStatus"
  21. />
  22. </view>
  23. <view class="btn" v-if="audioData.list.length>1">
  24. <image
  25. :src="audioData.index==0?'../static/audio-change-grey.png':'../static/audio-change.png'"
  26. mode="aspectFill"
  27. class="aside"
  28. @click="handleAudioChange('before')"
  29. />
  30. <image
  31. :src="play?'../static/audio-play.png':'../static/audio-pause.png'"
  32. mode="aspectFill"
  33. class="center"
  34. @click="handleChangePlayStatus"
  35. />
  36. <image
  37. :src="audioData.index==audioData.list.length-1?'../static/audio-change-grey.png':'../static/audio-change.png'"
  38. mode="aspectFill"
  39. class="aside"
  40. style="transform: rotate(180deg)"
  41. @click="handleAudioChange('next')"
  42. />
  43. </view>
  44. </view> -->
  45. <view class="pop-audio-wrap">
  46. <view class="flex small-box" @click="handleOpenBig">
  47. <image class="bg-img" :src="img" mode="aspectFill" />
  48. <view class="flex con">
  49. <view style="flex:1;overflow: hidden;">
  50. <view class="van-ellipsis name">{{title}}</view>
  51. <view class="time">时长 {{audioTime|formatVoiceTime}}</view>
  52. </view>
  53. <image
  54. class="pause-img"
  55. :src="play?'../static/audio-play.png':'../static/audio-pause.png'"
  56. mode="aspectFill"
  57. @click.stop="handleChangePlayStatus"
  58. />
  59. <van-icon @click.stop="handleClosePopAudio" name="cross" size="18" color="#BBC3C9" />
  60. </view>
  61. <van-progress
  62. color="#D4AC78"
  63. track-color="#fff"
  64. :show-pivot="false"
  65. stroke-width="2px"
  66. custom-class="bot-progress"
  67. :percentage="percentage"
  68. />
  69. </view>
  70. <view class="big-box" v-if="showBig">
  71. <van-icon class="big-arrow-down" name="arrow-down" size="18" color="#BBC3C9" @click="showBig=false" />
  72. <van-icon class="big-cross" @click.stop="handleClosePopAudio" name="cross" size="18" color="#BBC3C9"/>
  73. <view class="name">{{title}}</view>
  74. <view class="flex center-box">
  75. <text>{{currentTime|formatVoiceTime}}</text>
  76. <slider
  77. activeColor="#e3b377"
  78. :max="audioTime"
  79. :value="currentTime"
  80. @change="handleAudioSliderChange($event)"
  81. block-size="16"
  82. class="slider"
  83. />
  84. <text>{{audioTime|formatVoiceTime}}</text>
  85. </view>
  86. <view class="btn">
  87. <image
  88. :src="audioData.index==0?'../static/audio-change-grey.png':'../static/audio-change.png'"
  89. mode="aspectFill"
  90. class="aside"
  91. @click="handleAudioChange('before')"
  92. />
  93. <image
  94. :src="play?'../static/audio-play.png':'../static/audio-pause.png'"
  95. mode="aspectFill"
  96. class="center"
  97. @click="handleChangePlayStatus"
  98. />
  99. <image
  100. :src="audioData.index==audioData.list.length-1?'../static/audio-change-grey.png':'../static/audio-change.png'"
  101. mode="aspectFill"
  102. class="aside"
  103. style="transform: rotate(180deg)"
  104. @click="handleAudioChange('next')"
  105. />
  106. </view>
  107. </view>
  108. </view>
  109. </template>
  110. <script>
  111. export default {
  112. computed: {
  113. audioData(){
  114. return this.$store.state.report.audioData
  115. },
  116. percentage(){
  117. return parseInt((this.currentTime/this.audioTime)*100)
  118. }
  119. },
  120. watch: {
  121. 'audioData.reportId':{
  122. handler(nval,oval){
  123. console.log('音频的报告id:',nval,oval);
  124. this.init()
  125. },
  126. immediate:true
  127. }
  128. },
  129. data () {
  130. return {
  131. title:'',
  132. img:'',
  133. audioTime:0,
  134. currentTime:0,
  135. play:false,
  136. showBig:false
  137. }
  138. },
  139. methods: {
  140. init(type){
  141. let curAudio=this.$store.state.report.audioData.list[this.$store.state.report.audioData.index]
  142. if(this.globalBgMusic.src!=curAudio.video_url){
  143. this.globalBgMusic.src=curAudio.video_url
  144. this.globalBgMusic.title=curAudio.video_name
  145. }
  146. this.title=curAudio.video_name
  147. this.img=curAudio.video_img
  148. this.audioTime=curAudio.video_play_seconds
  149. this.currentTime=parseInt(this.globalBgMusic.currentTime)
  150. this.play=!this.globalBgMusic.paused
  151. this.handleAudioFun()
  152. },
  153. // 音频事件
  154. handleAudioFun(){
  155. this.globalBgMusic.onPlay(()=>{
  156. this.play=true
  157. this.$store.commit('updateAudioPause',false)
  158. })
  159. this.globalBgMusic.onPause(()=>{
  160. this.play=false
  161. this.$store.commit('updateAudioPause',true)
  162. })
  163. this.globalBgMusic.onStop(()=>{
  164. this.$store.commit('removeAudio')
  165. })
  166. this.globalBgMusic.onEnded(()=>{
  167. console.log('onEnded');
  168. // this.play=false
  169. let index=this.$store.state.report.audioData.index
  170. if(index==this.$store.state.report.audioData.list.length-1){
  171. this.$store.commit('removeAudio')
  172. }else{
  173. this.handleAudioChange('next')
  174. }
  175. })
  176. this.globalBgMusic.onError((e)=>{
  177. console.log('onError',e);
  178. uni.showToast({
  179. title: '音频播放错误',
  180. icon: 'none'
  181. })
  182. })
  183. this.globalBgMusic.onTimeUpdate(()=>{
  184. // console.log('时间更新');
  185. this.currentTime=parseInt(this.globalBgMusic.currentTime)
  186. })
  187. },
  188. //音频点击暂停播放
  189. handleChangePlayStatus(){
  190. if(this.play){
  191. this.globalBgMusic.pause()
  192. }else{
  193. this.globalBgMusic.play()
  194. }
  195. },
  196. //音频切换
  197. handleAudioChange(type){
  198. let temIndex=this.$store.state.report.audioData.index
  199. if(type=='before'){
  200. if(temIndex>0){
  201. let index=temIndex-1
  202. this.$store.commit('updateAudioIndex', index)
  203. this.init()
  204. }
  205. }else{
  206. if(temIndex<this.$store.state.report.audioData.list.length-1){
  207. let index=temIndex+1
  208. this.$store.commit('updateAudioIndex', index)
  209. this.init()
  210. }
  211. }
  212. },
  213. //拖动进度条
  214. handleAudioSliderChange(e){
  215. const value=e.detail.value
  216. this.globalBgMusic.seek(value)
  217. },
  218. //关闭弹窗
  219. handleClosePopAudio(){
  220. this.globalBgMusic.stop()
  221. },
  222. //点击展开
  223. handleOpenBig(){
  224. this.showBig=true
  225. }
  226. }
  227. }
  228. </script>
  229. <style>
  230. .bot-progress{
  231. position: absolute;
  232. bottom: 0;
  233. left: 0;
  234. right: 0;
  235. }
  236. .big-arrow-down{
  237. position: absolute;
  238. left: 25rpx;
  239. top: 25rpx;
  240. }
  241. .big-cross{
  242. position: absolute;
  243. top: 25rpx;
  244. right: 25rpx;
  245. }
  246. </style>
  247. <style lang="scss" scoped>
  248. .pop-audio-wrap{
  249. .small-box{
  250. position: fixed;
  251. z-index: 99;
  252. height: 120rpx;
  253. left: 50%;
  254. width: calc(100vw - 40rpx);
  255. bottom: 67rpx;
  256. transform: translateX(-50%);
  257. background: #FFFFFF;
  258. box-shadow: 0px 0px 40rpx 1px rgba(50,35,17,0.25);
  259. border: 1px solid #E4E4E4;
  260. overflow: hidden;
  261. .bg-img{
  262. width: 90rpx;
  263. height: 100%;
  264. // background-color: #ccc;
  265. flex-shrink: 0;
  266. margin-right: 20rpx;
  267. }
  268. .con{
  269. flex: 1;
  270. padding-right: 40rpx;
  271. overflow: hidden;
  272. align-items: center;
  273. .name{
  274. font-size: 28rpx;
  275. margin-bottom: 11rpx;
  276. }
  277. .time{
  278. font-size: 24rpx;
  279. color: #666;
  280. }
  281. .pause-img{
  282. width: 60rpx;
  283. height: 60rpx;
  284. flex-shrink: 0;
  285. margin-right: 44rpx;
  286. }
  287. }
  288. }
  289. .big-box{
  290. position: fixed;
  291. z-index: 100;
  292. left: 50%;
  293. width: calc(100vw - 40rpx);
  294. bottom: 67rpx;
  295. transform: translateX(-50%);
  296. background: #FFFFFF;
  297. box-shadow: 0px 0px 33rpx 1px rgba(50,35,17,0.25);
  298. border: 1px solid #E4E4E4;
  299. overflow: hidden;
  300. padding: 25rpx;
  301. .name{
  302. padding: 0 35rpx;
  303. font-size: 23rpx;
  304. text-align: center;
  305. margin-bottom: 20rpx;
  306. }
  307. .center-box{
  308. align-items: center;
  309. text{
  310. flex-shrink: 0;
  311. font-size: 20rpx;
  312. color: #666;
  313. }
  314. .slider{
  315. flex: 1;
  316. margin: 0 20rpx;
  317. }
  318. }
  319. .btn{
  320. display: flex;
  321. justify-content: center;
  322. align-items: center;
  323. margin-top: 20rpx;
  324. image{
  325. display: block;
  326. }
  327. .aside{
  328. width: 49rpx;
  329. height: 49rpx;
  330. }
  331. .center{
  332. width: 49rpx;
  333. height: 49rpx;
  334. margin: 0 49rpx;
  335. }
  336. }
  337. }
  338. }
  339. .pop-audio-box{
  340. position: fixed;
  341. width: 90vw;
  342. min-height: 50rpx;
  343. left: 5vw;
  344. bottom: 30rpx;
  345. z-index: 99;
  346. background-color: #fff;
  347. border: 2px solid rgba(240, 234, 226, 0.32);
  348. border-radius: 8rpx;
  349. padding: 10rpx 15rpx;
  350. .name{
  351. text-align: center;
  352. font-size: 24rpx;
  353. }
  354. .flex{
  355. align-items: center;
  356. text{
  357. flex-shrink: 0;
  358. font-size: 20rpx;
  359. }
  360. .slider{
  361. flex: 1;
  362. margin: 0 20rpx;
  363. }
  364. .small-img{
  365. width: 36rpx;
  366. height: 36rpx;
  367. display: block;
  368. margin-left: 10rpx;
  369. flex-shrink: 0;
  370. }
  371. }
  372. .btn{
  373. display: flex;
  374. justify-content: center;
  375. align-items: center;
  376. image{
  377. display: block;
  378. }
  379. .aside{
  380. width: 36rpx;
  381. height: 36rpx;
  382. }
  383. .center{
  384. width: 44rpx;
  385. height: 44rpx;
  386. margin: 0 20rpx;
  387. }
  388. }
  389. }
  390. </style>