|
@@ -13,6 +13,36 @@
|
|
|
@blur="onBlur(curQue, 'title')"
|
|
|
></el-input>
|
|
|
</div>
|
|
|
+ <div class="adult-book-input-item">
|
|
|
+ <span class="adult-book-lable">题目音频:</span>
|
|
|
+ <Upload
|
|
|
+ :changeFillId="timuchangeMp3"
|
|
|
+ :datafileList="curQue.mp3_list"
|
|
|
+ :filleNumber="mp3Number"
|
|
|
+ :uploadType="'mp3'"
|
|
|
+ :handleMp3Base64="handleChange"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <div class="adult-book-input-item">
|
|
|
+ <span class="adult-book-lable">题目lrc:</span>
|
|
|
+ <Upload
|
|
|
+ :changeFillId="changeLrc"
|
|
|
+ :datafileList="curQue.lrc_list"
|
|
|
+ :filleNumber="mp3Number"
|
|
|
+ :uploadType="'lrc'"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <div class="adult-book-input-item">
|
|
|
+ <span class="adult-book-lable"></span>
|
|
|
+ <el-button
|
|
|
+ type="primary"
|
|
|
+ size="small"
|
|
|
+ class="distribution"
|
|
|
+ @click="parseLrcFile"
|
|
|
+ >
|
|
|
+ 分配lrc
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
<div
|
|
|
v-for="(curQueItem, index) in curQue.option"
|
|
|
:key="'curQueItem' + index"
|
|
@@ -30,6 +60,7 @@
|
|
|
:class="'tinydemo' + index"
|
|
|
v-model="curQueItem.con"
|
|
|
:init="init"
|
|
|
+ @change="changeCon(curQueItem)"
|
|
|
/>
|
|
|
<img
|
|
|
@click="deleteGroup"
|
|
@@ -39,6 +70,15 @@
|
|
|
/>
|
|
|
</div>
|
|
|
<div class="adult-book-input-item">
|
|
|
+ <span class="adult-book-lable"></span>
|
|
|
+ <span v-if="curQue.wordTime.length > 0" class="lrc">
|
|
|
+ <el-input v-model="curQue.wordTime[index].bg" size="small" />
|
|
|
+ <span> ~ </span>
|
|
|
+ <el-input v-model="curQue.wordTime[index].ed" size="small" />
|
|
|
+ {{ curQue.wordTime[index].text }}
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ <div class="adult-book-input-item">
|
|
|
<span class="adult-book-lable">答案:</span>
|
|
|
<div class="toneList">
|
|
|
<div
|
|
@@ -76,6 +116,28 @@
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="addoption" @click="addoption">增加拼音</div>
|
|
|
+ <div class="adult-book-input-item">
|
|
|
+ <span class="adult-book-lable">文字类型</span>
|
|
|
+ <el-radio-group v-model="curQue.sentenceType">
|
|
|
+ <el-radio label="chinese">中文</el-radio>
|
|
|
+ <el-radio label="pinyin">拼音</el-radio>
|
|
|
+ </el-radio-group>
|
|
|
+ </div>
|
|
|
+ <div class="lrc-box">
|
|
|
+ <div
|
|
|
+ v-if="this.curQue.wordTime && this.curQue.wordTime.length > 0"
|
|
|
+ class="lrc-box"
|
|
|
+ >
|
|
|
+ <span>已有字幕时间节点</span>
|
|
|
+ <el-button type="text" @click="againWordTime">重新生成</el-button>
|
|
|
+ </div>
|
|
|
+ <template v-else>
|
|
|
+ <el-button v-if="!isWordTime" size="medium" @click="createWordTime"
|
|
|
+ >自动生成字幕节点</el-button
|
|
|
+ >
|
|
|
+ <p v-else>字幕节点生成中...请等待</p>
|
|
|
+ </template>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</template>
|
|
@@ -105,6 +167,14 @@ import "tinymce/plugins/preview";
|
|
|
import "tinymce/plugins/contextmenu";
|
|
|
import "tinymce/plugins/textcolor";
|
|
|
import "tinymce/plugins/colorpicker";
|
|
|
+import {
|
|
|
+ segSentences,
|
|
|
+ BatchSegContent,
|
|
|
+ createPinyin,
|
|
|
+ prepareTranscribe,
|
|
|
+ getWordTime,
|
|
|
+ getContentFile,
|
|
|
+} from "@/api/ajax";
|
|
|
export default {
|
|
|
name: "ToneSelect",
|
|
|
props: ["curQue", "changeCurQue"],
|
|
@@ -143,6 +213,12 @@ export default {
|
|
|
type: "toneSelect_chs",
|
|
|
name: "音调选择",
|
|
|
title: "",
|
|
|
+ mp3_list: [],
|
|
|
+ lrc_list: [],
|
|
|
+ wordTime: [],
|
|
|
+ taskId: "",
|
|
|
+ sentenceType: "pinyin",
|
|
|
+ detail: [],
|
|
|
option: [
|
|
|
{
|
|
|
con: "", //内容
|
|
@@ -162,12 +238,127 @@ export default {
|
|
|
toolbar: " forecolor",
|
|
|
branding: false,
|
|
|
}, //富文本初始化
|
|
|
+ isWordTime: false,
|
|
|
};
|
|
|
},
|
|
|
computed: {},
|
|
|
watch: {},
|
|
|
//方法集合
|
|
|
methods: {
|
|
|
+ changeCon(item) {
|
|
|
+ console.log(item);
|
|
|
+ },
|
|
|
+ createWordTime() {
|
|
|
+ this.curQue.option.forEach((item) => {
|
|
|
+ let node = document.createElement("p");
|
|
|
+ node.innerHTML = item.con;
|
|
|
+ let text = node.innerText;
|
|
|
+ item.pinyin = text;
|
|
|
+ });
|
|
|
+
|
|
|
+ this.curQue.detail = [];
|
|
|
+ this.curQue.option.forEach((item) => {
|
|
|
+ this.curQue.detail.push(item);
|
|
|
+ });
|
|
|
+
|
|
|
+ if (this.curQue.taskId) {
|
|
|
+ let verseList = [];
|
|
|
+ let numberArr = [];
|
|
|
+ this.curQue.detail.forEach((item, i) => {
|
|
|
+ numberArr.push(this.numberToChinese(i + 1));
|
|
|
+ });
|
|
|
+ for (let i = 0; i < this.curQue.detail.length; i++) {
|
|
|
+ verseList = verseList.concat(
|
|
|
+ `${numberArr[i]} ` + this.curQue.detail[i].pinyin
|
|
|
+ );
|
|
|
+ }
|
|
|
+ if (verseList.length > 0) {
|
|
|
+ this.isWordTime = true;
|
|
|
+ let data = {
|
|
|
+ taskId: this.curQue.taskId,
|
|
|
+ verseList: JSON.stringify(verseList),
|
|
|
+ matchType: this.curQue.sentenceType,
|
|
|
+ language: "ch",
|
|
|
+ };
|
|
|
+ getWordTime(data).then((res) => {
|
|
|
+ this.curQue.wordTime = res.data.result;
|
|
|
+ this.isWordTime = false;
|
|
|
+ });
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ this.$message.warning("请先上传音频");
|
|
|
+ }
|
|
|
+ },
|
|
|
+ againWordTime() {
|
|
|
+ this.isWordTime = false;
|
|
|
+ this.$set(this.curQue, "wordTime", []);
|
|
|
+ },
|
|
|
+ numberToChinese(num) {
|
|
|
+ var AA = new Array(
|
|
|
+ "ling",
|
|
|
+ "yi",
|
|
|
+ "er",
|
|
|
+ "san",
|
|
|
+ "si",
|
|
|
+ "wu",
|
|
|
+ "liu",
|
|
|
+ "qi",
|
|
|
+ "ba",
|
|
|
+ "jiu",
|
|
|
+ "shi"
|
|
|
+ );
|
|
|
+ var BB = new Array("", "shi", "bai", "qian", "wan", "yi", "dian", "");
|
|
|
+ var a = ("" + num).replace(/(^0*)/g, "").split("."),
|
|
|
+ k = 0,
|
|
|
+ re = "";
|
|
|
+ for (var i = a[0].length - 1; i >= 0; i--) {
|
|
|
+ switch (k) {
|
|
|
+ case 0:
|
|
|
+ re = BB[7] + re;
|
|
|
+ break;
|
|
|
+ case 4:
|
|
|
+ if (
|
|
|
+ !new RegExp("0{4}//d{" + (a[0].length - i - 1) + "}$").test(a[0])
|
|
|
+ )
|
|
|
+ re = BB[4] + re;
|
|
|
+ break;
|
|
|
+ case 8:
|
|
|
+ re = BB[5] + re;
|
|
|
+ BB[7] = BB[5];
|
|
|
+ k = 0;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if (k % 4 == 2 && a[0].charAt(i + 2) != 0 && a[0].charAt(i + 1) == 0)
|
|
|
+ re = AA[0] + re;
|
|
|
+ if (a[0].charAt(i) != 0) re = AA[a[0].charAt(i)] + BB[k % 4] + re;
|
|
|
+ k++;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (a.length > 1) {
|
|
|
+ // 加上小数部分(如果有小数部分)
|
|
|
+ re += BB[6];
|
|
|
+ for (var i = 0; i < a[1].length; i++) re += AA[a[1].charAt(i)];
|
|
|
+ }
|
|
|
+ if (re == "yishi") re = "shi";
|
|
|
+ if (re.match(/^一/) && re.length == 3) re = re.replace("yi", "");
|
|
|
+ return re;
|
|
|
+ },
|
|
|
+ changeLrc(fileList) {
|
|
|
+ let lrc_list = [];
|
|
|
+ fileList.forEach(({ response, name }) => {
|
|
|
+ if (response) {
|
|
|
+ let fileList = response.file_info_list[0];
|
|
|
+ lrc_list.push({
|
|
|
+ name,
|
|
|
+ duration: fileList.media_duration,
|
|
|
+ url: fileList.file_url,
|
|
|
+ id: "[FID##" + fileList.file_id + "##FID]",
|
|
|
+ file_id: fileList.file_id,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ this.curQue.lrc_list = lrc_list;
|
|
|
+ },
|
|
|
ConInput(e) {},
|
|
|
// 选择声调
|
|
|
selectTone(oindex, aindex) {
|
|
@@ -202,6 +393,22 @@ export default {
|
|
|
JSON.stringify(articleImgRes)
|
|
|
);
|
|
|
},
|
|
|
+ timuchangeMp3(fileList, item) {
|
|
|
+ const articleImgList = JSON.parse(JSON.stringify(fileList));
|
|
|
+ const articleImgRes = [];
|
|
|
+ articleImgList.forEach((item) => {
|
|
|
+ if (item.response) {
|
|
|
+ const obj = {
|
|
|
+ name: item.name,
|
|
|
+ url: item.response.file_info_list[0].file_url,
|
|
|
+ id: "[FID##" + item.response.file_info_list[0].file_id + "##FID]",
|
|
|
+ media_duration: item.response.file_info_list[0].media_duration, //音频时长
|
|
|
+ };
|
|
|
+ articleImgRes.push(obj);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ this.curQue.mp3_list = JSON.parse(JSON.stringify(articleImgRes));
|
|
|
+ },
|
|
|
addoption() {
|
|
|
let leg = this.curQue.option.length;
|
|
|
let last = this.curQue.option[leg - 1];
|
|
@@ -220,6 +427,58 @@ export default {
|
|
|
}
|
|
|
this.curQue.option.splice(index, 1);
|
|
|
},
|
|
|
+ // 上传音频文件
|
|
|
+ handleChange(file, fileList) {
|
|
|
+ let _this = this;
|
|
|
+ _this.getBase64(file.raw).then((res) => {
|
|
|
+ let base_res = res.split("base64,");
|
|
|
+ let data = {
|
|
|
+ fileName: file.raw.name,
|
|
|
+ speechBase64: base_res[1],
|
|
|
+ language: "ch",
|
|
|
+ };
|
|
|
+ prepareTranscribe(data).then((res) => {
|
|
|
+ _this.$set(_this.curQue, "taskId", res.data.taskId);
|
|
|
+ });
|
|
|
+ });
|
|
|
+ },
|
|
|
+ // 根据lrc文件id 获取内容和起始和结束时间
|
|
|
+ parseLrcFile() {
|
|
|
+ let lrcList = this.curQue.lrc_list;
|
|
|
+ if (lrcList.length === 0) {
|
|
|
+ return this.$message.warning("请先上传lrc文件");
|
|
|
+ }
|
|
|
+ getContentFile("tool-ParseLRCFile", {
|
|
|
+ content_type: "FILE",
|
|
|
+ file_id: this.curQue.lrc_list[0].file_id,
|
|
|
+ }).then(({ lrc_list }) => {
|
|
|
+ let lrc_list_res = [];
|
|
|
+ lrc_list.forEach((item) => {
|
|
|
+ let obj = {
|
|
|
+ bg: item.begin_time,
|
|
|
+ ed: item.end_time,
|
|
|
+ };
|
|
|
+ lrc_list_res.push(obj);
|
|
|
+ });
|
|
|
+ this.curQue.wordTime = lrc_list_res;
|
|
|
+ });
|
|
|
+ },
|
|
|
+ getBase64(file) {
|
|
|
+ return new Promise(function (resolve, reject) {
|
|
|
+ let reader = new FileReader();
|
|
|
+ let imgResult = "";
|
|
|
+ reader.readAsDataURL(file);
|
|
|
+ reader.onload = function () {
|
|
|
+ imgResult = reader.result;
|
|
|
+ };
|
|
|
+ reader.onerror = function (error) {
|
|
|
+ reject(error);
|
|
|
+ };
|
|
|
+ reader.onloadend = function () {
|
|
|
+ resolve(imgResult);
|
|
|
+ };
|
|
|
+ });
|
|
|
+ },
|
|
|
},
|
|
|
//生命周期 - 创建完成(可以访问当前this实例)
|
|
|
created() {},
|
|
@@ -239,6 +498,18 @@ export default {
|
|
|
editor_selector: `tinydemo${i}`,
|
|
|
});
|
|
|
});
|
|
|
+ if (!this.curQue.lrc_list) {
|
|
|
+ this.curQue.lrc_list = [];
|
|
|
+ }
|
|
|
+ if (!this.curQue.sentenceType) {
|
|
|
+ this.curQue.sentenceType = "pinyin";
|
|
|
+ }
|
|
|
+ if (!this.curQue.taskId) {
|
|
|
+ this.curQue.taskId = "";
|
|
|
+ }
|
|
|
+ if (!this.curQue.wordTime) {
|
|
|
+ this.curQue.wordTime = [];
|
|
|
+ }
|
|
|
}
|
|
|
},
|
|
|
beforeCreate() {}, //生命周期 - 创建之前
|
|
@@ -291,6 +562,10 @@ export default {
|
|
|
margin-left: 10px;
|
|
|
}
|
|
|
}
|
|
|
+ .lrc {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ }
|
|
|
}
|
|
|
</style>
|
|
|
<style lang="scss">
|