Explorar o código

语音矩阵自动生成字幕节点

dsy hai 2 días
pai
achega
f73e574390

+ 12 - 12
src/views/book/courseware/create/components/question/article/NewWord.vue

@@ -218,7 +218,7 @@
         </span>
       </div>
       <SvgIcon icon-class="delete-black" size="12" @click="removeFile('audio')" />
-      <ResourcesOperate :data="data.audio_data"></ResourcesOperate>
+      <ResourcesOperate :data="data.audio_data" />
     </div>
     <SelectUpload label="音频字幕(lrc)文件" :limit="1" type="lrc" @uploadSuccess="uploadLrcSuccess" />
     <div v-if="data.lrc_data.url.length > 0" class="upload-file">
@@ -229,7 +229,7 @@
         </span>
       </div>
       <SvgIcon icon-class="delete-black" size="12" @click="removeFile('lrc')" />
-      <ResourcesOperate :data="data.lrc_data"></ResourcesOperate>
+      <ResourcesOperate :data="data.lrc_data" />
     </div>
     <div class="lrc-box" style="margin: 5px 0">
       <div v-if="data.lrc_arr && data.lrc_arr.length > 0" class="lrc-box">
@@ -343,8 +343,8 @@ export default {
     CheckSubtitles,
     ResourcesOperate,
   },
-  props: ['dataNewWord', 'unifiedAttrib'],
   mixins: [ModuleMixin],
+  props: ['dataNewWord', 'unifiedAttrib'],
   data() {
     return {
       data: this.dataNewWord,
@@ -363,6 +363,9 @@ export default {
       autoLoading: false,
     };
   },
+  created() {
+    this.getTextToAudioConfParamList();
+  },
   methods: {
     getOption() {
       return {
@@ -565,7 +568,7 @@ export default {
         this.data.new_word_list.length > 0 ? this.data.new_word_list[this.data.new_word_list.length - 1].number : '0';
       this.data.new_word_list.push(this.getOption());
       if (!isNaN(number) && !isNaN(parseFloat(number))) {
-        this.data.new_word_list[this.data.new_word_list.length - 1].number = number * 1 + 1;
+        this.data.new_word_list[this.data.new_word_list.length - 1].number = Number(number) + 1;
       }
     },
     // 获取数据
@@ -608,7 +611,7 @@ export default {
     // 自动生成拼音
     handlePinyin(text) {
       let data = {
-        text: text,
+        text,
         is_rich_text: 'false',
         is_first_sentence_first_hz_pinyin_first_char_upper_case: 'false',
         is_fill_space: 'false',
@@ -621,7 +624,7 @@ export default {
             res.parsed_text.paragraph_list.map((outerArr, i) =>
               outerArr.map((innerArr, j) =>
                 innerArr.map((newItem, k) => {
-                  mergedData += newItem.pinyin + ' ';
+                  mergedData += `${newItem.pinyin} `;
                 }),
               ),
             );
@@ -635,13 +638,13 @@ export default {
         let text = '';
         this.data.new_word_list.forEach((sItem, index) => {
           // item.forEach((sItem, sIndex) => {
-          text += sItem.new_word + '。';
+          text += `${sItem.new_word}。`;
           // });
         });
         this.isWordTime = true;
         let data = {
           audio_file_id: this.data.audio_data.file_id,
-          text: text,
+          text,
           text_type: 'text',
         };
         getWordTimes(data)
@@ -749,7 +752,7 @@ export default {
         // });
       });
       TextToAudioFile({
-        text: text,
+        text,
         voice_type: this.data.property.voice_type,
         emotion: this.data.property.emotion,
         speed_ratio: this.data.property.speed_ratio,
@@ -772,9 +775,6 @@ export default {
         });
     },
   },
-  created() {
-    this.getTextToAudioConfParamList();
-  },
 };
 </script>
 <style lang="scss" scoped>

+ 56 - 0
src/views/book/courseware/create/components/question/voice_matrix/VoiceMatrix.vue

@@ -69,6 +69,17 @@
           <el-button size="small" type="primary" @click="openCheckSubtitles">校对字幕</el-button>
         </div>
 
+        <div class="lrc-box" style="margin: 5px 0">
+          <div v-if="data.lrc_arr && data.lrc_arr.length > 0" class="lrc-box">
+            <span>已有字幕时间节点</span>
+            <el-button type="text" @click="rebuildWordTime">重新生成</el-button>
+          </div>
+          <template v-else>
+            <el-button v-if="!isWordTime" size="medium" @click="autoWordTime"> 自动生成字幕节点 </el-button>
+            <p v-else>字幕节点生成中...请等待</p>
+          </template>
+        </div>
+
         <div v-if="data.lrc_data.url.length > 0" class="upload-file">
           <div class="file-name">
             <span>
@@ -117,6 +128,7 @@ import ResourcesOperate from '../../common/ResourcesOperate.vue';
 import { getVoiceMatrixData, getOption } from '@/views/book/courseware/data/voiceMatrix';
 import { GetStaticResources } from '@/api/app';
 import { fontList, fontSizeList } from '@/views/book/courseware/data/common';
+import { getWordTimes } from '@/api/article';
 
 export default {
   name: 'VoiceMatrix',
@@ -137,6 +149,7 @@ export default {
       font: '楷体,微软雅黑',
       fontSize: '12pt',
       color: '#1d2129',
+      isWordTime: false, // 是否正在生成字幕节点
     };
   },
   watch: {
@@ -300,6 +313,49 @@ export default {
       this.curSelectColumn = -1;
       this.curSelectRow = -1;
     },
+    /**
+     * 重新生成字幕节点
+     */
+    rebuildWordTime() {
+      this.isWordTime = false;
+      this.$set(this.data, 'lrc_arr', []);
+    },
+    /**
+     * 自动生成字幕节点
+     */
+    autoWordTime() {
+      if (this.data.audio_data.url.length === 0) {
+        return this.$message.warning('请先上传音频文件');
+      }
+      const text = this.data.option_list
+        .map((item) =>
+          item.map(({ content = '' }) => {
+            const plainText = content.replace(/<[^>]+>/g, '').trim();
+            return plainText;
+          }),
+        )
+        .flat()
+        .filter((item) => item.length > 0)
+        .join('。');
+      this.isWordTime = true;
+      getWordTimes({
+        audio_file_id: this.data.audio_data.file_id,
+        text,
+        text_type: 'text',
+      })
+        .then(({ data }) => {
+          const lrcArr = data.result.map(({ bg, ed, onebest }) => ({
+            begin_time: bg,
+            end_time: ed,
+            text: onebest,
+          }));
+          this.$set(this.data, 'lrc_arr', lrcArr);
+          this.distribution();
+        })
+        .finally(() => {
+          this.isWordTime = false;
+        });
+    },
   },
 };
 </script>