|
@@ -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>
|