audioBox.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  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="" 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. audioTime:0,
  133. currentTime:0,
  134. play:false,
  135. showBig:false
  136. }
  137. },
  138. methods: {
  139. init(type){
  140. let curAudio=this.$store.state.report.audioData.list[this.$store.state.report.audioData.index]
  141. if(this.globalBgMusic.src!=curAudio.video_url){
  142. this.globalBgMusic.src=curAudio.video_url
  143. this.globalBgMusic.title=curAudio.video_name
  144. }
  145. this.title=curAudio.video_name
  146. this.audioTime=curAudio.video_play_seconds
  147. this.currentTime=parseInt(this.globalBgMusic.currentTime)
  148. this.play=!this.globalBgMusic.paused
  149. this.handleAudioFun()
  150. },
  151. // 音频事件
  152. handleAudioFun(){
  153. this.globalBgMusic.onPlay(()=>{
  154. this.play=true
  155. this.$store.commit('updateAudioPause',false)
  156. })
  157. this.globalBgMusic.onPause(()=>{
  158. this.play=false
  159. this.$store.commit('updateAudioPause',true)
  160. })
  161. this.globalBgMusic.onStop(()=>{
  162. this.$store.commit('removeAudio')
  163. })
  164. this.globalBgMusic.onEnded(()=>{
  165. console.log('onEnded');
  166. // this.play=false
  167. let index=this.$store.state.report.audioData.index
  168. if(index==this.$store.state.report.audioData.list.length-1){
  169. this.$store.commit('removeAudio')
  170. }else{
  171. this.handleAudioChange('next')
  172. }
  173. })
  174. this.globalBgMusic.onError((e)=>{
  175. console.log('onError',e);
  176. uni.showToast({
  177. title: '音频播放错误',
  178. icon: 'none'
  179. })
  180. })
  181. this.globalBgMusic.onTimeUpdate(()=>{
  182. // console.log('时间更新');
  183. this.currentTime=parseInt(this.globalBgMusic.currentTime)
  184. })
  185. },
  186. //音频点击暂停播放
  187. handleChangePlayStatus(){
  188. if(this.play){
  189. this.globalBgMusic.pause()
  190. }else{
  191. this.globalBgMusic.play()
  192. }
  193. },
  194. //音频切换
  195. handleAudioChange(type){
  196. let temIndex=this.$store.state.report.audioData.index
  197. if(type=='before'){
  198. if(temIndex>0){
  199. let index=temIndex-1
  200. this.$store.commit('updateAudioIndex', index)
  201. this.init()
  202. }
  203. }else{
  204. if(temIndex<this.$store.state.report.audioData.list.length-1){
  205. let index=temIndex+1
  206. this.$store.commit('updateAudioIndex', index)
  207. this.init()
  208. }
  209. }
  210. },
  211. //拖动进度条
  212. handleAudioSliderChange(e){
  213. const value=e.detail.value
  214. this.globalBgMusic.seek(value)
  215. },
  216. //关闭弹窗
  217. handleClosePopAudio(){
  218. this.$store.commit('closePopAudio')
  219. },
  220. //点击展开
  221. handleOpenBig(){
  222. this.showBig=true
  223. }
  224. }
  225. }
  226. </script>
  227. <style>
  228. .bot-progress{
  229. position: absolute;
  230. bottom: 0;
  231. left: 0;
  232. right: 0;
  233. }
  234. .big-arrow-down{
  235. position: absolute;
  236. left: 25rpx;
  237. top: 25rpx;
  238. }
  239. .big-cross{
  240. position: absolute;
  241. top: 25rpx;
  242. right: 25rpx;
  243. }
  244. </style>
  245. <style lang="scss" scoped>
  246. .pop-audio-wrap{
  247. .small-box{
  248. position: fixed;
  249. z-index: 99;
  250. height: 120rpx;
  251. left: 50%;
  252. width: calc(100vw - 40rpx);
  253. bottom: 67rpx;
  254. transform: translateX(-50%);
  255. background: #FFFFFF;
  256. box-shadow: 0px 0px 40rpx 1px rgba(50,35,17,0.25);
  257. border: 1px solid #E4E4E4;
  258. overflow: hidden;
  259. .bg-img{
  260. width: 90rpx;
  261. height: 100%;
  262. background-color: #ccc;
  263. flex-shrink: 0;
  264. margin-right: 20rpx;
  265. }
  266. .con{
  267. flex: 1;
  268. padding-right: 40rpx;
  269. overflow: hidden;
  270. align-items: center;
  271. .name{
  272. font-size: 28rpx;
  273. margin-bottom: 11rpx;
  274. }
  275. .time{
  276. font-size: 24rpx;
  277. color: #666;
  278. }
  279. .pause-img{
  280. width: 60rpx;
  281. height: 60rpx;
  282. flex-shrink: 0;
  283. margin-right: 44rpx;
  284. }
  285. }
  286. }
  287. .big-box{
  288. position: fixed;
  289. z-index: 100;
  290. left: 50%;
  291. width: calc(100vw - 40rpx);
  292. bottom: 67rpx;
  293. transform: translateX(-50%);
  294. background: #FFFFFF;
  295. box-shadow: 0px 0px 33rpx 1px rgba(50,35,17,0.25);
  296. border: 1px solid #E4E4E4;
  297. overflow: hidden;
  298. padding: 25rpx;
  299. .name{
  300. padding: 0 35rpx;
  301. font-size: 23rpx;
  302. text-align: center;
  303. margin-bottom: 20rpx;
  304. }
  305. .center-box{
  306. align-items: center;
  307. text{
  308. flex-shrink: 0;
  309. font-size: 20rpx;
  310. color: #666;
  311. }
  312. .slider{
  313. flex: 1;
  314. margin: 0 20rpx;
  315. }
  316. }
  317. .btn{
  318. display: flex;
  319. justify-content: center;
  320. align-items: center;
  321. margin-top: 20rpx;
  322. image{
  323. display: block;
  324. }
  325. .aside{
  326. width: 49rpx;
  327. height: 49rpx;
  328. }
  329. .center{
  330. width: 49rpx;
  331. height: 49rpx;
  332. margin: 0 49rpx;
  333. }
  334. }
  335. }
  336. }
  337. .pop-audio-box{
  338. position: fixed;
  339. width: 90vw;
  340. min-height: 50rpx;
  341. left: 5vw;
  342. bottom: 30rpx;
  343. z-index: 99;
  344. background-color: #fff;
  345. border: 2px solid rgba(240, 234, 226, 0.32);
  346. border-radius: 8rpx;
  347. padding: 10rpx 15rpx;
  348. .name{
  349. text-align: center;
  350. font-size: 24rpx;
  351. }
  352. .flex{
  353. align-items: center;
  354. text{
  355. flex-shrink: 0;
  356. font-size: 20rpx;
  357. }
  358. .slider{
  359. flex: 1;
  360. margin: 0 20rpx;
  361. }
  362. .small-img{
  363. width: 36rpx;
  364. height: 36rpx;
  365. display: block;
  366. margin-left: 10rpx;
  367. flex-shrink: 0;
  368. }
  369. }
  370. .btn{
  371. display: flex;
  372. justify-content: center;
  373. align-items: center;
  374. image{
  375. display: block;
  376. }
  377. .aside{
  378. width: 36rpx;
  379. height: 36rpx;
  380. }
  381. .center{
  382. width: 44rpx;
  383. height: 44rpx;
  384. margin: 0 20rpx;
  385. }
  386. }
  387. }
  388. </style>