myAudio.vue 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. <template>
  2. <view class="audio" v-if="url">
  3. <view class="audio-play" @click='start(audioId)'>
  4. <image class='audio-icon' :src='startPic' v-show='!status'></image>
  5. <image class='audio-icon' :src='endPic' v-show='status'></image>
  6. </view>
  7. <view class='audio-time mg18'>{{getTime(Math.round(currentTime))}}</view>
  8. <view class='audio-slider'>
  9. <slider @change='changeAudio' :activeColor='activeColor' :block-size="25" :min='0' :max='duration.toFixed(0)' :value='currentTime.toFixed(0)' :step='0.1'></slider>
  10. </view>
  11. <view class='audio-time'>{{getTime(Math.round(duration))}}</view>
  12. </view>
  13. </template>
  14. <script>
  15. export default {
  16. props: {
  17. url: String,
  18. activeColor: {
  19. type: String,
  20. default: '#FF5C03'
  21. },
  22. audioId: [String,Number]
  23. },
  24. data() {
  25. return {
  26. endPic: require("@/static/hall/hear_play_icon.png"),
  27. startPic: require("@/static/hall/hear_suspend_icon.png"),
  28. context: null,
  29. currentTime: 0,
  30. duration: 100,
  31. status: false
  32. }
  33. },
  34. created() {
  35. this.context = uni.createInnerAudioContext();
  36. this.context.src = this.url;
  37. this.onTimeUpdate();
  38. this.onCanplay();
  39. this.onEnded();
  40. uni.$on('stop',(id)=> {
  41. if(id && id != this.audioId) {
  42. this.context.stop();
  43. this.status = false;
  44. } else if(!id){
  45. this.context.stop();
  46. this.status = false;
  47. }
  48. })
  49. },
  50. methods: {
  51. start(id) { //点击播放
  52. let audioId = id;
  53. if(this.status) {
  54. this.context.pause();
  55. this.status = !this.status;
  56. }else {
  57. uni.$emit('stop',id)
  58. this.context.play()
  59. this.status = !this.status;
  60. }
  61. },
  62. onCanplay() { //进入可播放状态
  63. this.context.onCanplay(() => {
  64. this.context.duration;
  65. setTimeout(()=>{
  66. this.duration = this.context.duration;
  67. },1000)
  68. })
  69. },
  70. onTimeUpdate() { //音频播放进度
  71. this.context.onTimeUpdate(() => {
  72. if (!Number.isFinite( this.context.duration)) {
  73. this.duration = this.context.currentTime + 10;
  74. this.currentTime = this.context.currentTime;
  75. } else {
  76. this.duration = this.context.duration;
  77. this.currentTime = this.context.currentTime;
  78. }
  79. })
  80. },
  81. onEnded() { //播放结束
  82. this.context.onEnded(()=> {
  83. this.status = false;
  84. this.currentTime = 0;
  85. })
  86. },
  87. changeAudio(e) {
  88. let paused = this.context.paused;
  89. this.context.pause();
  90. this.context.seek(e.detail.value)
  91. if(!paused) {
  92. this.context.play();
  93. }
  94. },
  95. getTime(time) {
  96. let m = parseInt(time / 60);
  97. let s = time % 60;
  98. return this.towNum(m) + ':' + this.towNum(s);
  99. },
  100. towNum(num) {
  101. if(num >= 10) {
  102. return num;
  103. }else {
  104. return '0' + num;
  105. }
  106. }
  107. }
  108. }
  109. </script>
  110. <style lang="scss" scoped>
  111. .mg18 {
  112. margin: 0 18rpx;
  113. }
  114. .audio {
  115. display: flex;
  116. flex-direction: row;
  117. align-items: center;
  118. font-family: PingFang SC, PingFang SC;
  119. font-weight: 500;
  120. font-size: 24rpx;
  121. color: #757575;
  122. &-play {
  123. display: flex;
  124. flex-direction: row;
  125. align-items: center;
  126. }
  127. &-icon {
  128. width: 48rpx;
  129. height: 48rpx;
  130. }
  131. &-slider {
  132. flex: 1;
  133. }
  134. &-time {
  135. flex-shrink: 0;
  136. }
  137. }
  138. </style>