소스 검색

音频加倍速

zq 1 주 전
부모
커밋
437fd31e32

+ 4 - 2
src/views/book/courseware/preview/components/audio/AudioPreview.vue

@@ -66,8 +66,9 @@
         </el-carousel>
         <div :style="{ height: elementHeight - 140 + 'px', overflowY: viewScroll }">
           <ul class="view-list-bottom">
-            <li v-for="(file, i) in data.file_list" :key="i" @click="handleAudioClick(i)">
+            <li v-for="(file, i) in data.file_list" :key="i" @click="handleAudioClick(i, file.file_id)">
               <AudioPlay
+                :ref="file.file_id"
                 view-size="list"
                 :file-id="file.file_id"
                 :file-name="file.file_name.slice(0, file.file_name.lastIndexOf('.'))"
@@ -181,12 +182,13 @@ export default {
     });
   },
   methods: {
-    handleAudioClick(index) {
+    handleAudioClick(index, id) {
       // 获取 Carousel 实例
       const carousel = this.$refs.audio_carousel;
       // 切换到对应索引的文件
       carousel.setActiveItem(index);
       this.curAudioIndex = index;
+      if (this.$refs[id]&&this.$refs[id][0]) this.$refs[id][0].changeAudio(id);
     },
     changeFile(type) {
       // 获取 Carousel 实例

+ 75 - 29
src/views/book/courseware/preview/components/common/AudioPlay.vue

@@ -13,6 +13,17 @@
             @change="changeCurrentTime"
           />
           <span class="audio-time">{{ audio_allTime }}</span>
+          <el-select v-model="audio.playbackRate" @change="onSpeedChange" style="width: 100px">
+            <el-option
+              v-for="speed in playbackRateList.split(' ')"
+              :key="speed"
+              :value="speed"
+              :selected="speed === 1.0"
+              :label="`${speed}x`"
+            >
+              {{ speed }}x
+            </el-option>
+          </el-select>
         </div>
         <div class="audio-icon">
           <SvgIcon icon-class="pre" size="12" :color="topicColor" @click="changeFile('prev')" />
@@ -33,6 +44,17 @@
             @change="changeCurrentTime"
           />
           <span class="audio-time">{{ audio_allTime }}</span>
+          <el-select v-model="audio.playbackRate" style="width: 100px" @change="onSpeedChange">
+            <el-option
+              v-for="speed in playbackRateList.split(' ')"
+              :key="speed"
+              :value="speed"
+              :selected="speed === 1.0"
+              :label="`${speed}x`"
+            >
+              {{ speed }}x
+            </el-option>
+          </el-select>
         </div>
       </div>
     </div>
@@ -69,8 +91,8 @@
         icon-class="sound"
         size="20"
         :color="topicColor"
-        @click="playAudio"
         :class="{ 'sound-icon--playing': !audio.paused }"
+        @click="playAudio"
       />
     </div>
     <div v-else :class="['audio-list', { active: audioIndex === curAudioIndex }]" :style="cssVars">
@@ -164,7 +186,9 @@ export default {
         max_time: 0,
         isPlaying: false,
         loading: false,
+        playbackRate: '1.0',
       },
+      playbackRateList: '0.25 0.5 0.75 1.0 1.25 1.5 1.75 2.0 3.0',
       play_value: 0,
       audio_allTime: null, // 展示总时间
     };
@@ -191,16 +215,17 @@ export default {
     },
   },
   mounted() {
-    if (!this.fileId) return;
-    this.$refs[this.fileId].addEventListener('ended', () => {
-      this.audio.paused = true;
-    });
-    this.$refs[this.fileId].addEventListener('pause', () => {
-      this.audio.paused = true;
-    });
-    this.$refs[this.fileId].addEventListener('play', () => {
-      this.audio.paused = false;
-    });
+    if (this.fileId) {
+      this.$refs[this.fileId].addEventListener('ended', () => {
+        this.audio.paused = true;
+      });
+      this.$refs[this.fileId].addEventListener('pause', () => {
+        this.audio.paused = true;
+      });
+      this.$refs[this.fileId].addEventListener('play', () => {
+        this.audio.paused = false;
+      });
+    }
   },
   methods: {
     getCurTime(curTime) {
@@ -208,21 +233,15 @@ export default {
     },
     playAudio() {
       if (!this.url) return;
-      const audio = this.$refs[this.fileId];
-      let audioArr = document.getElementsByTagName('audio');
-      if (audioArr && audioArr.length > 0) {
-        for (let i = 0; i < audioArr.length; i++) {
-          if (audioArr[i].src === this.url) {
-            if (audioArr[i].id !== this.fileId) {
-              audioArr[i].pause();
-            }
-          } else {
-            audioArr[i].pause();
-          }
-        }
-      }
+      const audio = this.$refs[this.fileId] || {};
+      this.pauseAll();
+      audio.playbackRate = this.audio.playbackRate;
       audio.paused ? audio.play() : audio.pause();
     },
+    onSpeedChange(speed) {
+      const audio = this.$refs[this.fileId] || {};
+      audio.playbackRate = this.audio.playbackRate;
+    },
     // 进度条格式化toolTip
     formatProcessToolTip(index) {
       let _index = parseInt((this.audio.max_time / 100) * index);
@@ -230,10 +249,10 @@ export default {
     },
     // 点击 拖拽播放音频
     changeCurrentTime(value) {
-      let audioId = this.fileId;
-      this.$refs[audioId].play();
+      this.pauseAll();
+      this.$refs[this.fileId].play();
       this.audio.playing = true;
-      this.$refs[audioId].currentTime = parseInt((value / 100) * this.audio.max_time);
+      this.$refs[this.fileId].currentTime = parseInt((value / 100) * this.audio.max_time);
     },
     // 音频加载完之后
     onLoadedmetadata(res) {
@@ -242,11 +261,10 @@ export default {
     },
     // 当音频当前时间改变后,进度条也要改变
     onTimeupdate(res) {
-      let audioId = this.fileId;
       this.audio.current_time = res.target.currentTime;
       this.play_value = (this.audio.current_time / this.audio.max_time) * 100;
       if (this.audio.current_time * 1000 > this.ed) {
-        this.$refs[audioId].pause();
+        this.$refs[this.fileId].pause();
       }
     },
     onTimeupdateTime(res, playFlag) {
@@ -267,9 +285,28 @@ export default {
     oncanplaythrough() {
       this.audio.loading = false;
     },
+    pauseAll() {
+      let audioArr = document.getElementsByTagName('audio');
+      if (audioArr && audioArr.length > 0) {
+        for (let i = 0; i < audioArr.length; i++) {
+          audioArr[i].pause();
+          // if (audioArr[i].src === this.url) {
+          //   if (audioArr[i].id !== this.fileId) {
+          //     audioArr[i].pause();
+          //   }
+          // } else {
+          //   audioArr[i].pause();
+          // }
+        }
+      }
+    },
     changeFile(type) {
+      this.pauseAll();
       this.$emit('changeFile', type);
     },
+    changeAudio(id) {
+      this.pauseAll();
+    },
   },
 };
 </script>
@@ -425,6 +462,15 @@ export default {
       }
     }
   }
+
+  :deep .el-input .el-input__inner {
+    background-color: rgba(255, 255, 255, 0%);
+    border: none;
+
+    span {
+      display: none !important;
+    }
+  }
 }
 
 .sound-icon--playing {