Jelajahi Sumber

语音矩阵修改问题、增加跟读功能、循环播放
双击播放改为单击播放,不同区域高亮互斥且只有播放的内容显示高亮

dusenyao 3 tahun lalu
induk
melakukan
9bbfd7420b

+ 137 - 0
src/components/Adult/preview/AudioCompareMatrix.vue

@@ -0,0 +1,137 @@
+<template>
+  <div class="compara-content">
+    <template v-if="wavblob">
+      <div v-if="!isRecord" style="width: 16px; height: 16px; margin-left: 8px" @click.stop.capture="playAudio">
+        <audio-line
+          ref="audioLine"
+          :mp3="url"
+          :get-cur-time="getCurTime"
+          audio-id="audioCompareMatrix"
+          :stop-audio="stopAudio"
+          :hide-slider="true"
+          @handleChangeStopAudio="handleChangeStopAudio"
+          @sentPause="sentPause"
+          @playChange="playChange"
+        />
+      </div>
+      <div v-else style="width: 16px; height: 16px; margin-left: 8px">
+        <audio-red
+          ref="audioRed"
+          :mp3="wavblob"
+          :is-compare="true"
+          :theme-color="themeColor"
+          @sentPause="sentPause"
+        />
+      </div>
+    </template>
+    <template v-else>
+      <img
+        src="../../../assets/NPC/compare-disable.png"
+        class="compare-disable"
+      >
+    </template>
+  </div>
+</template>
+
+<script>
+import AudioLine from "./AudioLine.vue";
+import AudioRed from "./components/AudioRed.vue";
+
+export default {
+  components: {
+    AudioLine,
+    AudioRed
+  },
+  props: [
+    "themeColor",
+    "isRecord",
+    "wavblob",
+    "url",
+    "sentPause",
+    "matrixSelectLrc",
+    "getCurTime",
+    "curTime"
+  ],
+  data() {
+    return {
+      playing: false,
+      stopAudio: true,
+      unWatch: null
+    };
+  },
+  watch: {
+    matrixSelectLrc() {
+      if (this.unWatch) {
+        this.unWatch();
+        this.unWatch = null;
+      }
+      this.handleParentPlay();
+      this.playChange(false);
+      if (this.isRecord) this.$refs.audioRed.stopAudio();
+    },
+    isRecord(newVal) {
+      if (!newVal) this.unWatch = null;
+    },
+    wavblob(newVal) {
+      if (!newVal) {
+        this.playChange(false);
+      }
+    }
+  },
+  methods: {
+    playAudio() {
+      if (this.playing) return this.handleParentPlay();
+      if (this.unWatch) return this.$refs.audioLine.PlayAudio();
+      if (this.matrixSelectLrc.length <= 0) return;
+
+      this.lrcPlay(this.matrixSelectLrc[0], 0);
+    },
+
+    lrcPlay({ begin_time, end_time }, index) {
+      this.handleParentPlay();
+      this.$nextTick(() => {
+        this.$refs.audioLine.onTimeupdateTime(begin_time / 1000);
+        this.$refs.audioLine.PlayAudio();
+        if (end_time === -1) return;
+        let end = end_time / 1000 - 0.01;
+        this.unWatch = this.$watch("curTime", val => {
+          if (val >= end) {
+            this.unWatch();
+            this.handleParentPlay();
+            this.$refs.audioLine.onTimeupdateTime(end);
+            let i = index + 1;
+            if (i < this.matrixSelectLrc.length) {
+              return this.lrcPlay(this.matrixSelectLrc[i], i);
+            }
+            this.sentPause(true);
+            this.playChange(false);
+          }
+        });
+      });
+    },
+
+    playChange(playing) {
+      this.playing = playing;
+      this.$emit('playing', playing);
+    },
+
+    // 暂停音频播放
+    handleParentPlay() {
+      this.stopAudio = true;
+    },
+    // 音频播放时改变布尔值
+    handleChangeStopAudio() {
+      this.stopAudio = false;
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+.compare-disable {
+  display: block;
+  width: 16px;
+  height: 16px;
+  margin-left: 8px;
+}
+</style>

+ 18 - 19
src/components/Adult/preview/AudioLine.vue

@@ -1,6 +1,6 @@
 <template>
   <div :class="['Audio', mp3Source && mp3Source == 'tts' ? 'Audio-tts' : '']">
-    <div class="audioLine" v-if="!hideSlider">
+    <div v-if="!hideSlider" class="audioLine">
       <div
         class="play"
         :class="[
@@ -15,37 +15,34 @@
           :format-tooltip="formatProcessToolTip"
           @change="changeCurrentTime"
         />
-        <span
-          ><template v-if="audio.playing">-</template
-          >{{
-            audio.maxTime
-              ? realFormatSecond(audio.maxTime - audio.currentTime)
-              : ""
-          }}</span
-        >
+        <span><template v-if="audio.playing">-</template>{{
+          audio.maxTime
+            ? realFormatSecond(audio.maxTime - audio.currentTime)
+            : ""
+        }}</span>
       </template>
     </div>
-    <div class="audioLine2" v-else>
+    <div v-else class="audioLine2">
       <div
         class="play-icon"
         :class="
           audio.loading
             ? 'loadBtn'
             : audio.playing
-            ? 'playBtn-icon'
-            : 'pauseBtn-icon'
+              ? 'playBtn-icon'
+              : 'pauseBtn-icon'
         "
         @click="PlayAudio"
       />
     </div>
     <audio
+      :id="audioId"
       :ref="audioId"
       :src="mp3"
+      preload="meta"
       @loadedmetadata="onLoadedmetadata"
       @timeupdate="onTimeupdate"
       @canplaythrough="oncanplaythrough"
-      preload="meta"
-      :id="audioId"
     />
   </div>
 </template>
@@ -174,7 +171,7 @@ export default {
     PlayAudio() {
       let audioId = this.audioId;
       let audio = document.getElementsByTagName("audio");
-      audio.forEach((item) => {
+      audio.forEach(item => {
         if (item.src == this.mp3) {
           if (item.id !== audioId) {
             item.pause();
@@ -184,7 +181,7 @@ export default {
         }
       });
       let video = document.getElementsByTagName("video");
-      video.forEach((vItem) => {
+      video.forEach(vItem => {
         vItem.pause();
       });
 
@@ -209,12 +206,12 @@ export default {
     },
     oncanplaythrough() {
       let _this = this;
-      //setTimeout(() => {
+      // setTimeout(() => {
       console.log("音频加载完成");
       _this.audio.loading = false;
       _this.loading.close();
 
-      //}, 10000);
+      // }, 10000);
     },
     // 点击 拖拽播放音频
     changeCurrentTime(value) {
@@ -251,12 +248,13 @@ export default {
       }
     },
     onTimeupdateTime(res, playFlag) {
+      if (!res) return;
       let audioId = this.audioId;
       this.$refs[audioId].currentTime = res;
       this.playValue = (res / this.audio.maxTime) * 100;
       if (playFlag) {
         let audio = document.getElementsByTagName("audio");
-        audio.forEach((item) => {
+        audio.forEach(item => {
           if (item.id !== audioId) {
             item.pause();
           }
@@ -328,6 +326,7 @@ export default {
       margin-right: 12px;
       margin-left: 8px;
       width: 16px;
+      min-width: 16px;
       height: 16px;
       cursor: pointer;
       display: block;

+ 66 - 66
src/components/Adult/preview/Soundrecord.vue

@@ -5,18 +5,17 @@
       <div
         :class="['record', microphoneStatus ? 'active' : '']"
         @click="microphone"
-      ></div>
+      />
       <span
+        v-if="type && type == 'normal'"
         :class="[
           'record-time',
           microphoneStatus ? 'record-ing' : '',
           selectIndex || selectIndex == 0 ? 'record-black' : '',
           type && type == 'normal' ? 'record-time-flex' : '',
         ]"
-        v-if="type && type == 'normal'"
-        >{{ isPlaying ? "-" : "" }}{{ handleDateTime(recordtime) }}</span
-      >
-      <div class="line" v-if="type && type == 'normal'"></div>
+      >{{ isPlaying ? "-" : "" }}{{ handleDateTime(recordtime) }}</span>
+      <div v-if="type && type == 'normal'" class="line" />
       <div
         :class="['playBack', hasMicro]"
         @click="
@@ -26,26 +25,25 @@
               : ''
           )
         "
-      ></div>
+      />
     </template>
     <template v-else-if="type && type == 'pro'">
       <div
         :class="['record', microphoneStatus ? 'active' : '']"
         @click="microphone"
-      ></div>
+      />
       <el-select
         v-model="selectIndex"
         placeholder="无录音"
-        @change="handleChangeRecord"
         class="proSelect"
+        @change="handleChangeRecord"
       >
         <el-option
           v-for="(item, index) in recordList"
           :key="item.id"
           :label="item.name"
           :value="index"
-        >
-        </el-option>
+        />
       </el-select>
       <div
         :class="['playBack', hasMicro]"
@@ -56,25 +54,24 @@
               : ''
           )
         "
-      ></div>
+      />
       <a
         :class="['record-delete', hasMicro ? 'record-delete-has' : '']"
         @click="handleDelete"
-      ></a>
+      />
     </template>
     <template v-else>
       <div
         :class="['record', microphoneStatus ? 'active' : '']"
         @click="microphone"
-      ></div>
+      />
       <span
         :class="[
           'record-time',
           microphoneStatus ? 'record-ing' : '',
           selectIndex || selectIndex == 0 ? 'record-black' : '',
         ]"
-        >{{ isPlaying ? "-" : "" }}{{ handleDateTime(recordtime) }}</span
-      >
+      >{{ isPlaying ? "-" : "" }}{{ handleDateTime(recordtime) }}</span>
       <el-select
         v-model="selectIndex"
         placeholder="无录音"
@@ -85,8 +82,7 @@
           :key="item.id"
           :label="item.name"
           :value="index"
-        >
-        </el-option>
+        />
       </el-select>
       <div
         :class="['playBack', hasMicro]"
@@ -97,20 +93,20 @@
               : ''
           )
         "
-      ></div>
+      />
       <a
         :class="['record-delete', hasMicro ? 'record-delete-has' : '']"
         @click="handleDelete"
-      ></a>
+      />
     </template>
   </div>
 </template>
 
 <script>
-import Recorder from "js-audio-recorder"; //录音插件
+import Recorder from "js-audio-recorder"; // 录音插件
 export default {
   components: {},
-  props: ["wavData", "type", "fileName"],
+  props: ["wavData", "type", "fileName", "selectData"],
   data() {
     return {
       recorder: new Recorder({
@@ -122,10 +118,10 @@ export default {
       hasMicro: "", // 录音后的样式class
       wavblob: null,
       audio: new window.Audio(),
-      recordList: [], //录音文件数组
+      recordList: [], // 录音文件数组
       recordtime: 0, // 录音时长
       timer: null, // 计时器
-      recordFile: 1, //录音文件名
+      recordFile: 1, // 录音文件名
       selectIndex: null, // 选中的录音索引
       oldIndex: null, // 存储播放录音索引
       playtime: 0, // 播放时间
@@ -134,14 +130,47 @@ export default {
   },
   computed: {},
   watch: {},
-  //方法集合
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  created() {
+    this.handleActive();
+    let that = this;
+    window.stopAudioSound = function () {
+      if (that.audio) {
+        that.audio.pause();
+      }
+    };
+  },
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted() {
+    let _this = this;
+    _this.audio.addEventListener("play", function () {
+      _this.changeStatus("active");
+      _this.isPlaying = true;
+    });
+    _this.audio.addEventListener("pause", function () {
+      _this.changeStatus("normal");
+    });
+    _this.audio.addEventListener("ended", function () {
+      _this.changeStatus("normal");
+      _this.isPlaying = false;
+    });
+  },
+  beforeCreate() {}, // 生命周期 - 创建之前
+  beforeMount() {}, // 生命周期 - 挂载之前
+  beforeUpdate() {}, // 生命周期 - 更新之前
+  updated() {}, // 生命周期 - 更新之后
+  beforeDestroy() {}, // 生命周期 - 销毁之前
+  destroyed() {}, // 生命周期 - 销毁完成
+  activated() {},
+  // 方法集合
   methods: {
     // 开始录音
     microphone() {
       let _this = this;
       if (!this.microphoneStatus) {
         _this.$emit("getWavblob", null);
-        //开始录音
+        this.$emit("getSelectData", { type: '' });
+        // 开始录音
         this.recorder.start();
         this.microphoneStatus = true;
         this.recordtime = 0;
@@ -157,6 +186,7 @@ export default {
             : "新录音" + _this.recordFile,
           id: _this.recordFile + Math.round(Math.random() * 10),
         };
+        if (this.selectData) obj.selectData = this.selectData;
         _this.recordList.push(obj);
         _this.recordFile++;
         _this.selectIndex = _this.recordList.length - 1;
@@ -172,16 +202,16 @@ export default {
         // } else {
         //   this.recordtime = 0;
         // }
-        let toltime = this.recorder.duration; //录音总时长
-        let fileSize = this.recorder.fileSize; //录音总大小
-        //录音结束,获取取录音数据
-        let PCMBlob = this.recorder.getPCMBlob(); //获取 PCM 数据
-        let wav = this.recorder.getWAVBlob(); //获取 WAV 数据
+        let toltime = this.recorder.duration; // 录音总时长
+        let fileSize = this.recorder.fileSize; // 录音总大小
+        // 录音结束,获取取录音数据
+        let PCMBlob = this.recorder.getPCMBlob(); // 获取 PCM 数据
+        let wav = this.recorder.getWAVBlob(); // 获取 WAV 数据
         // this.wavblob = wav;
         this.microphoneStatus = false;
-        var reader = new window.FileReader();
+        let reader = new window.FileReader();
         reader.readAsDataURL(wav);
-        reader.onloadend = function () {
+        reader.onloadend = () => {
           _this.recordList[_this.selectIndex].wavData = reader.result;
           _this.recordList[_this.selectIndex].toltime = Math.floor(toltime);
           _this.recordList[_this.selectIndex].fileSize = fileSize;
@@ -191,6 +221,7 @@ export default {
           //   ) {
           _this.wavblob = _this.recordList[_this.selectIndex].wavData;
           _this.$emit("getWavblob", _this.wavblob);
+          if (this.recordList[this.selectIndex].selectData) this.$emit("getSelectData", this.recordList[this.selectIndex].selectData);
           //   }
         };
       }
@@ -273,6 +304,7 @@ export default {
       this.audio.pause();
       this.oldIndex = null;
       this.$emit("getWavblob", this.wavblob);
+      if (this.recordList[index].selectData) this.$emit("getSelectData", this.recordList[index].selectData);
       this.$emit("sentPause", false);
     },
     handleDelete() {
@@ -296,39 +328,7 @@ export default {
         clearInterval(this.timer);
       }
     },
-  },
-  //生命周期 - 创建完成(可以访问当前this实例)
-  created() {
-    this.handleActive();
-    var that = this;
-    window.stopAudioSound = function () {
-      if (that.audio) {
-        that.audio.pause();
-      }
-    };
-  },
-  //生命周期 - 挂载完成(可以访问DOM元素)
-  mounted() {
-    let _this = this;
-    _this.audio.addEventListener("play", function () {
-      _this.changeStatus("active");
-      _this.isPlaying = true;
-    });
-    _this.audio.addEventListener("pause", function () {
-      _this.changeStatus("normal");
-    });
-    _this.audio.addEventListener("ended", function () {
-      _this.changeStatus("normal");
-      _this.isPlaying = false;
-    });
-  },
-  beforeCreate() {}, //生命周期 - 创建之前
-  beforeMount() {}, //生命周期 - 挂载之前
-  beforeUpdate() {}, //生命周期 - 更新之前
-  updated() {}, //生命周期 - 更新之后
-  beforeDestroy() {}, //生命周期 - 销毁之前
-  destroyed() {}, //生命周期 - 销毁完成
-  activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
+  }, // 如果页面有keep-alive缓存功能,这个函数会触发
 };
 </script>
 <style lang='scss' scoped>
@@ -456,4 +456,4 @@ export default {
     }
   }
 }
-</style>
+</style>

+ 152 - 44
src/components/Adult/preview/VoiceMatrix.vue

@@ -14,6 +14,10 @@
       </div>
       <div v-show="hasSelectedCell" class="audio-simple">
         <img :src="playing ? voicePlaySrc : voicePauseSrc" @click="playAudio">
+        <span
+          :class="['Repeat-16', isRepeat ? '' : 'disabled']"
+          @click="isRepeat = !isRepeat"
+        />
       </div>
       <audio-line
         v-show="!hasSelectedCell"
@@ -135,15 +139,15 @@
                     (selectedLine.type === 'row' && selectedLine.index === i)
                     ? 'selected'
                     : '',
-                  column.lrc_data.begin_time / 1000 <= curTime &&
+                  playing &&
+                    column.lrc_data.begin_time / 1000 <= curTime &&
                     (curTime < column.lrc_data.end_time / 1000 ||
                       column.lrc_data.end_time === -1)
                     ? 'playing'
                     : '',
                   column.isTitle ? 'title' : ''
                 ]"
-                @click="cellClickTimeout(i, j)"
-                @dblclick="matrixCelDblClick(i, j)"
+                @click="matrixCellClick(i, j)"
               >
                 <span>{{ column.text }}</span>
               </div>
@@ -170,7 +174,8 @@
                     (selectedLine.type === 'row' && selectedLine.index === i)
                     ? 'selected'
                     : '',
-                  column.lrc_data.begin_time / 1000 <= curTime &&
+                  playing &&
+                    column.lrc_data.begin_time / 1000 <= curTime &&
                     (curTime < column.lrc_data.end_time / 1000 ||
                       column.lrc_data.end_time === -1)
                     ? 'playing'
@@ -180,8 +185,7 @@
                 :style="{
                   'grid-template-columns': `repeat(${column.sentence_data.wordsList.length}, auto)`
                 }"
-                @click="cellClickTimeout(i, j)"
-                @dblclick="matrixCelDblClick(i, j)"
+                @click="matrixCellClick(i, j)"
               >
                 <template v-for="(word, w) in column.sentence_data.wordsList">
                   <span
@@ -220,15 +224,15 @@
                     (selectedLine.type === 'row' && selectedLine.index === i)
                     ? 'selected'
                     : '',
-                  column.lrc_data.begin_time / 1000 <= curTime &&
+                  playing &&
+                    column.lrc_data.begin_time / 1000 <= curTime &&
                     (curTime < column.lrc_data.end_time / 1000 ||
                       column.lrc_data.end_time === -1)
                     ? 'playing'
                     : '',
                   column.isTitle ? 'title' : ''
                 ]"
-                @click="cellClickTimeout(i, j)"
-                @dblclick="matrixCelDblClick(i, j)"
+                @click="matrixCellClick(i, j)"
               >
                 <div class="inside-wrapper">
                   <div class="pinyin">
@@ -274,12 +278,30 @@
       </div>
     </div>
 
-    <soundrecord
-      type="promax"
-      class="luyin-box"
-      :file-name="fileName"
-      @handleWav="handleWav"
-    />
+    <div class="voice-luyin">
+      <soundrecord
+        type="promax"
+        class="luyin-box"
+        :file-name="fileName"
+        :select-data="selectData"
+        @getWavblob="getWavblob"
+        @getSelectData="getSelectData"
+        @handleParentPlay="handleParentPlay"
+        @sentPause="sentPause"
+      />
+      <audio-compare
+        :theme-color="themeColor"
+        :wavblob="wavblob"
+        :url="mp3Url"
+        :is-record="isRecord"
+        :sent-pause="sentPause"
+        :matrix-select-lrc="matrixSelectLrc"
+        :get-cur-time="getCurTime"
+        :cur-time="curTime"
+        :handle-change-stop-audio="handleChangeStopAudio"
+        @playing="playChange"
+      />
+    </div>
   </div>
 </template>
 
@@ -287,11 +309,13 @@
 import Bus from "./components/Bus.js";
 import AudioLine from "./AudioLine.vue";
 import Soundrecord from "./Soundrecord.vue";
+import AudioCompare from "./AudioCompareMatrix.vue";
 
 export default {
   components: {
     AudioLine,
-    Soundrecord
+    Soundrecord,
+    AudioCompare
   },
   props: ["curQue", "themeColor"],
   data() {
@@ -315,7 +339,12 @@ export default {
       selectCell: {
         row: -1,
         column: -1
-      }
+      },
+      isRepeat: false,
+      // 跟读所需属性
+      wavblob: null,
+      isRecord: false,
+      matrixSelectLrc: null
     };
   },
   computed: {
@@ -336,11 +365,23 @@ export default {
       if (mp3_list === undefined) return 0;
       return mp3_list.media_duration * 1000;
     },
+
     hasSelectedCell() {
       let { type, index } = this.selectedLine;
       let { row, column } = this.selectCell;
       return (type.length > 0 && index >= 0) || (row >= 0 && column >= 0);
     },
+    selectData() {
+      let { type, index } = this.selectedLine;
+      let { row, column } = this.selectCell;
+      return {
+        type: type.length > 0 && index >= 0 ? type : "cell",
+        index,
+        row,
+        column
+      };
+    },
+
     voicePauseSrc() {
       let themeColor = this.themeColor;
       if (themeColor.length === 0 || themeColor === "red") {
@@ -383,13 +424,7 @@ export default {
       this.selectColumn = -1;
     },
 
-    cellClickTimeout(row, column) {
-      clearTimeout(this.cellTimer);
-      this.cellTimer = setTimeout(() => {
-        this.matrixCellClick(row, column);
-      }, 200);
-    },
-
+    // 单击单元格
     matrixCellClick(row, column) {
       if (this.playing) this.handleParentPlay();
       if (this.unWatch) this.unWatch();
@@ -400,15 +435,6 @@ export default {
       }
       this.selectedLine = { type: "", index: -1 };
       this.selectCell = { row, column };
-      // 设置录音文件名
-      this.setRecordingFileName(row, column);
-      if (!this.hasSelectedCell) this.handleParentPlay();
-    },
-
-    matrixCelDblClick(row, column) {
-      clearTimeout(this.cellTimer);
-      this.selectedLine = { type: "", index: -1 };
-      this.selectCell = { row, column };
       this.handleChangeTime(
         this.curQue.voiceMatrix.matrix[row][column].lrc_data
       );
@@ -462,6 +488,8 @@ export default {
       if (!this.hasSelectedCell) return;
       if (this.playing) return this.handleParentPlay();
       if (this.lrcArray.length > 0) return this.$refs.audioLine.PlayAudio();
+      if (this.unWatch) this.unWatch();
+
       this.lrcArray = [];
       let { type, index } = this.selectedLine;
       if (type.length > 0 && index >= 0 && type === "row") {
@@ -534,10 +562,12 @@ export default {
             this.unWatch();
             let i = index + 1;
             if (i < this.lrcArray.length) {
-              this.lrcPlay(this.lrcArray[i], i);
-            } else {
-              this.lrcArray = [];
+              return this.lrcPlay(this.lrcArray[i], i);
+            }
+            if (this.isRepeat) {
+              return this.lrcPlay(this.lrcArray[0], 0);
             }
+            this.lrcArray = [];
           }
         });
       });
@@ -562,8 +592,69 @@ export default {
       this.curTime = curTime;
     },
 
-    handleWav(data) {
-      console.log(data);
+    getWavblob(wavblob) {
+      this.wavblob = wavblob;
+    },
+
+    getSelectData({ type, index, row, column }) {
+      if (type === '') return;
+      let arr = [];
+      if (type.length > 0 && index >= 0 && type === "row") {
+        this.curQue.voiceMatrix.matrix[index].forEach(
+          ({ type, text, lrc_data }) => {
+            if (
+              type === "SentenceSegwordChs" ||
+              type === "PinyinEnglish" ||
+              (type === "text" && text.length > 0)
+            ) {
+              if (lrc_data.end_time === -1) {
+                arr.push({
+                  begin_time: lrc_data.begin_time,
+                  end_time: this.mp3Duration,
+                  text: lrc_data.text
+                });
+                return;
+              }
+              arr.push(lrc_data);
+            }
+          }
+        );
+        this.matrixSelectLrc = arr;
+        return;
+      }
+
+      if (type.length > 0 && index >= 0 && type === "column") {
+        this.curQue.voiceMatrix.matrix.forEach(item => {
+          let { type, text, lrc_data } = item[index];
+          if (
+            type === "SentenceSegwordChs" ||
+            type === "PinyinEnglish" ||
+            (type === "text" && text.length > 0)
+          ) {
+            if (lrc_data.end_time === -1) {
+              arr.push({
+                begin_time: lrc_data.begin_time,
+                end_time: this.mp3Duration,
+                text: lrc_data.text
+              });
+              return;
+            }
+            arr.push(lrc_data);
+          }
+        });
+        this.matrixSelectLrc = arr;
+        return;
+      }
+
+      if (type === "cell" && row >= 0 && column >= 0) {
+        let lrcData = this.curQue.voiceMatrix.matrix[row][column].lrc_data;
+        if (lrcData.end_time === -1) lrcData.end_time = this.mp3Duration;
+        this.matrixSelectLrc = [lrcData];
+      }
+    },
+
+    sentPause(isRecord) {
+      this.isRecord = isRecord;
     },
 
     handleChangeTime({ begin_time, end_time }) {
@@ -646,14 +737,27 @@ $select-color-brown-active: #a37557;
     }
 
     .audio-simple {
+      flex-grow: 1;
       line-height: 46px;
       height: 100%;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
 
       img {
         cursor: pointer;
         width: 16px;
+        height: 16px;
         margin-left: 12px;
       }
+
+      .Repeat-16 {
+        display: inline-block;
+        width: 16px;
+        height: 16px;
+        margin-right: 12px;
+        cursor: pointer;
+      }
     }
   }
   // 语音矩阵
@@ -791,6 +895,7 @@ $select-color-brown-active: #a37557;
           border-radius: 8px;
           transition: 0.2s;
           cursor: pointer;
+          user-select: none;
 
           &:hover {
             border-color: #8c8c8c;
@@ -812,7 +917,8 @@ $select-color-brown-active: #a37557;
 
           > span {
             display: inline-block;
-            padding: 7px 16px;
+            padding: 4px 12px;
+            line-height: 24px;
           }
         }
 
@@ -827,7 +933,6 @@ $select-color-brown-active: #a37557;
           &::before {
             display: inline-block;
             content: "";
-            height: 100%;
             vertical-align: middle;
           }
         }
@@ -864,7 +969,8 @@ $select-color-brown-active: #a37557;
           @extend %column;
 
           display: inline-grid;
-          padding: 7px 16px;
+          padding: 4px 12px;
+          line-height: 24px;
           column-gap: 8px;
           justify-items: center;
           justify-content: start;
@@ -998,11 +1104,13 @@ $select-color-brown-active: #a37557;
     }
   }
 
-  .luyin-box {
-    padding: 8px 16px;
-    height: 40px;
+  .voice-luyin {
+    display: flex;
     border: 1px solid $border-color;
     border-radius: 0 0 8px 8px;
+    align-items: center;
+    padding: 3px 16px;
+    height: 40px;
   }
 }
 </style>

+ 34 - 42
src/components/Adult/preview/components/AudioRed.vue

@@ -1,7 +1,7 @@
 <!--  -->
 <template>
-  <div @click="handlePlayVoice" class="content-voices" v-if="mp3">
-    <img :src="voiceSrc" />
+  <div v-if="mp3" class="content-voices" @click="handlePlayVoice">
+    <img :src="voiceSrc">
   </div>
 </template>
 
@@ -17,15 +17,15 @@ export default {
         ? this.themeColor == "green"
           ? require("../../../../assets/NPC/play-green.png")
           : this.themeColor == "brown"
-          ? require("../../../../assets/NPC/play-brown.png")
-          : require("../../../../assets/NPC/play-red.png")
+            ? require("../../../../assets/NPC/play-brown.png")
+            : require("../../../../assets/NPC/play-red.png")
         : require("../../../../assets/NPC/play-red.png"),
       voicePlaySrc: this.themeColor
         ? this.themeColor == "green"
           ? require("../../../../assets/NPC/icon-voice-play-green.png")
           : this.themeColor == "brown"
-          ? require("../../../../assets/NPC/icon-voice-play-brown.png")
-          : require("../../../../assets/NPC/icon-voice-play-red.png")
+            ? require("../../../../assets/NPC/icon-voice-play-brown.png")
+            : require("../../../../assets/NPC/icon-voice-play-red.png")
         : require("../../../../assets/NPC/icon-voice-play-red.png"),
     };
   },
@@ -56,41 +56,16 @@ export default {
     },
   },
   watch: {},
-  //方法集合
-  methods: {
-    handlePlayVoice() {
-      let _this = this;
-      if (!_this.audio.paused) {
-        _this.audio.pause();
-      } else {
-        if (_this.isCompare) {
-          _this.audio.pause();
-          _this.audio.play();
-        } else {
-          _this.audio.pause();
-          _this.audio.load();
-          _this.audio.src = _this.mp3;
-          _this.audio.loop = false;
-          _this.audio.play();
-        }
-      }
-    },
-    stopAudio() {
-      if (this.audio) {
-        this.audio.pause();
-      }
-    },
-  },
-  //生命周期 - 创建完成(可以访问当前this实例)
+  // 生命周期 - 创建完成(可以访问当前this实例)
   created() {
-    var that = this;
+    let that = this;
     window.stopAudioVoice = function () {
       if (that.audio) {
         that.audio.pause();
       }
     };
   },
-  //生命周期 - 挂载完成(可以访问DOM元素)
+  // 生命周期 - 挂载完成(可以访问DOM元素)
   mounted() {
     let _this = this;
     _this.voiceSrc = _this.isCompare
@@ -120,13 +95,30 @@ export default {
       _this.$emit("sentPause", false);
     });
   },
-  beforeCreate() {}, //生命周期 - 创建之前
-  beforeMount() {}, //生命周期 - 挂载之前
-  beforeUpdate() {}, //生命周期 - 更新之前
-  updated() {}, //生命周期 - 更新之后
-  beforeDestroy() {}, //生命周期 - 销毁之前
-  destroyed() {}, //生命周期 - 销毁完成
-  activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
+  // 方法集合
+  methods: {
+    handlePlayVoice() {
+      let _this = this;
+      console.log(this.audio.paused);
+      if (!_this.audio.paused) {
+        _this.audio.pause();
+      } else if (_this.isCompare) {
+        _this.audio.pause();
+        _this.audio.play();
+      } else {
+        _this.audio.pause();
+        _this.audio.load();
+        _this.audio.src = _this.mp3;
+        _this.audio.loop = false;
+        _this.audio.play();
+      }
+    },
+    stopAudio() {
+      if (this.audio) {
+        this.audio.pause();
+      }
+    },
+  }
 };
 </script>
 <style lang='scss' scoped>
@@ -153,4 +145,4 @@ export default {
     float: left;
   }
 }
-</style>
+</style>