Explorar o código

自动生成音频配置音色

liuhaidi123 hai 3 semanas
pai
achega
92fbb991fc

+ 15 - 0
src/api/app.js

@@ -104,3 +104,18 @@ export function LearnWebSI(MethodName, data) {
 export function CreateBookPreviewURL(data) {
   return http.post(`${process.env.VUE_APP_EepServer}?MethodName=book_preview_manager-CreateBookPreviewURL`, data);
 }
+
+/**
+ * 文本转音频文件-有音色配置
+ * @param {object} data 请求数据
+ */
+export function TextToAudioFile(data) {
+  return http.post(`${process.env.VUE_APP_EepServer}?MethodName=tool-TextToAudioFile`, data);
+}
+
+/**
+ * 得到文本转音频的配置参数列表
+ */
+export function GetTextToAudioConfParamList() {
+  return http.post(`${process.env.VUE_APP_EepServer}?MethodName=tool-GetTextToAudioConfParamList`);
+}

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

@@ -254,6 +254,24 @@
         </el-select>
       </el-form-item>
 
+      <template v-if="data.property.audio_generation_method === 'auto'">
+        <el-form-item label="音色">
+          <el-select v-model="data.property.voice_type" placeholder="请选择">
+            <el-option
+              v-for="{ voice_type, name } in voice_type_list"
+              :key="voice_type"
+              :label="name"
+              :value="voice_type"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="风格情感">
+          <el-select v-model="data.property.emotion">
+            <el-option v-for="{ emotion, name } in emotion_list" :key="emotion" :label="name" :value="emotion" />
+          </el-select>
+        </el-form-item>
+      </template>
+
       <el-form-item label="拼音位置">
         <el-radio-group v-model="data.property.pinyin_position">
           <el-radio v-for="{ value, label } in pinyinPositionLists" :key="value" :label="value">
@@ -280,7 +298,7 @@ import UploadAudio from '@/views/book/courseware/create/components/question/fill
 import SelectUpload from '@/views/book/courseware/create/components/common/SelectUpload.vue';
 import UploadPicture from '../new_word/components/UploadPicture.vue';
 import { getWordTime, prepareTranscribe, fileToBase64Text, getWordTimes } from '@/api/article';
-import { GetStaticResources } from '@/api/app';
+import { GetStaticResources, TextToAudioFile, GetTextToAudioConfParamList } from '@/api/app';
 import RichText from '@/components/RichText.vue';
 import CheckSubtitles from '@/views/book/courseware/create/components/question/voice_matrix/CheckSubtitles.vue';
 import {
@@ -315,6 +333,8 @@ export default {
       switchOption,
       visible: false,
       subtitleList: [],
+      voice_type_list: [],
+      emotion_list: [],
     };
   },
   methods: {
@@ -469,8 +489,10 @@ export default {
     },
     // 自动生成音频
     handleMatic(index) {
-      GetStaticResources('tool-TextToVoiceFile', {
+      TextToAudioFile({
         text: this.data.new_word_list[index].new_word.replace(/<[^>]+>/g, ''),
+        voice_type: this.data.property.voice_type,
+        emotion: this.data.property.emotion,
       })
         .then(({ status, file_id }) => {
           if (status === 1) {
@@ -638,6 +660,20 @@ export default {
       });
       this.data.lrc_arr = lrc_list_res;
     },
+    // 得到文本转音频的配置参数列表
+    getTextToAudioConfParamList() {
+      GetTextToAudioConfParamList()
+        .then(({ status, voice_type_list, emotion_list }) => {
+          if (status === 1) {
+            this.voice_type_list = voice_type_list;
+            this.emotion_list = emotion_list;
+          }
+        })
+        .catch(() => {});
+    },
+  },
+  created() {
+    this.getTextToAudioConfParamList();
   },
 };
 </script>

+ 2 - 2
src/views/book/courseware/create/components/question/character/Character.vue

@@ -94,7 +94,7 @@
 import ModuleMixin from '../../common/ModuleMixin';
 
 import { getCharacterData, modelList, getOption } from '@/views/book/courseware/data/character';
-import { GetStaticResources } from '@/api/app';
+import { GetStaticResources, TextToAudioFile } from '@/api/app';
 import cnchar from 'cnchar';
 import UploadFile from '../../base/common/UploadFile.vue';
 
@@ -160,7 +160,7 @@ export default {
     },
     // 自动生成音频
     handleMatic(con, index) {
-      GetStaticResources('tool-TextToVoiceFile', {
+      TextToAudioFile({
         text: con.replace(/<[^>]+>/g, ''),
       })
         .then(({ status, file_id, file_url }) => {

+ 4 - 2
src/views/book/courseware/create/components/question/fill/Fill.vue

@@ -95,7 +95,7 @@ import PinyinText from '@/components/PinyinText.vue';
 import { getFillData, arrangeTypeList, fillFontList, fillTypeList } from '@/views/book/courseware/data/fill';
 import { addTone, handleToneValue } from '@/views/book/courseware/data/common';
 import { getRandomNumber } from '@/utils';
-import { GetStaticResources } from '@/api/app';
+import { TextToAudioFile } from '@/api/app';
 
 export default {
   name: 'FillPage',
@@ -261,8 +261,10 @@ export default {
     },
     // 自动生成音频
     handleMatic() {
-      GetStaticResources('tool-TextToVoiceFile', {
+      TextToAudioFile({
         text: this.data.content.replace(/<[^>]+>/g, ''),
+        voice_type: this.data.property.voice_type,
+        emotion: this.data.property.emotion,
       })
         .then(({ status, file_id }) => {
           if (status === 1) {

+ 38 - 1
src/views/book/courseware/create/components/question/fill/FillSetting.vue

@@ -30,6 +30,24 @@
           <el-option v-for="{ value, label } in audioGenerationMethodList" :key="value" :label="label" :value="value" />
         </el-select>
       </el-form-item>
+
+      <template v-if="property.audio_generation_method === 'auto'">
+        <el-form-item label="音色">
+          <el-select v-model="property.voice_type" placeholder="请选择">
+            <el-option
+              v-for="{ voice_type, name } in voice_type_list"
+              :key="voice_type"
+              :label="name"
+              :value="voice_type"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="风格情感">
+          <el-select v-model="property.emotion">
+            <el-option v-for="{ emotion, name } in emotion_list" :key="emotion" :label="name" :value="emotion" />
+          </el-select>
+        </el-form-item>
+      </template>
       <el-form-item label="填空字体">
         <el-select v-model="property.fill_font" placeholder="请选择">
           <el-option v-for="{ value, label } in fillFontList" :key="value" :label="label" :value="value" />
@@ -84,6 +102,8 @@ import {
   fillTypeList,
 } from '@/views/book/courseware/data/fill';
 
+import { GetTextToAudioConfParamList } from '@/api/app';
+
 export default {
   name: 'FillSetting',
   mixins: [SettingMixin],
@@ -96,9 +116,26 @@ export default {
       fillFontList,
       switchOption,
       fillTypeList,
+      voice_type_list: [],
+      emotion_list: [],
     };
   },
-  methods: {},
+  methods: {
+    // 得到文本转音频的配置参数列表
+    getTextToAudioConfParamList() {
+      GetTextToAudioConfParamList()
+        .then(({ status, voice_type_list, emotion_list }) => {
+          if (status === 1) {
+            this.voice_type_list = voice_type_list;
+            this.emotion_list = emotion_list;
+          }
+        })
+        .catch(() => {});
+    },
+  },
+  created() {
+    this.getTextToAudioConfParamList();
+  },
 };
 </script>
 

+ 1 - 1
src/views/book/courseware/create/components/question/fill/components/UploadAudio.vue

@@ -83,7 +83,7 @@ export default {
           this.file_id = file_id;
           this.file_url = file_url;
           this.file_name = file_name;
-          this.$emit('upload', file_id, this.itemIndex);
+          this.$emit('upload', file_id, this.itemIndex, file_url);
         }
       });
     },

+ 4 - 2
src/views/book/courseware/create/components/question/new_word/NewWord.vue

@@ -415,7 +415,7 @@ import CheckSubtitles from '@/views/book/courseware/create/components/question/v
 
 import { getNewWordData, getOption } from '@/views/book/courseware/data/newWord';
 import SelectUpload from '@/views/book/courseware/create/components/common/SelectUpload.vue';
-import { GetStaticResources } from '@/api/app';
+import { GetStaticResources, TextToAudioFile } from '@/api/app';
 import cnchar from 'cnchar';
 import { ChapterGetBookChapterStruct } from '@/api/book';
 import { getWordTime, prepareTranscribe, fileToBase64Text, getWordTimes } from '@/api/article';
@@ -581,8 +581,10 @@ export default {
     },
     // 自动生成音频
     handleMatic(index) {
-      GetStaticResources('tool-TextToVoiceFile', {
+      TextToAudioFile({
         text: this.data.new_word_list[index].new_word.replace(/<[^>]+>/g, ''),
+        voice_type: this.data.property.voice_type,
+        emotion: this.data.property.emotion,
       })
         .then(({ status, file_id }) => {
           if (status === 1) {

+ 36 - 2
src/views/book/courseware/create/components/question/new_word/NewWordSetting.vue

@@ -20,7 +20,23 @@
           <el-option v-for="{ value, label } in audioGenerationMethodList" :key="value" :label="label" :value="value" />
         </el-select>
       </el-form-item>
-
+      <template v-if="property.audio_generation_method === 'auto'">
+        <el-form-item label="音色">
+          <el-select v-model="property.voice_type" placeholder="请选择">
+            <el-option
+              v-for="{ voice_type, name } in voice_type_list"
+              :key="voice_type"
+              :label="name"
+              :value="voice_type"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="风格情感">
+          <el-select v-model="property.emotion">
+            <el-option v-for="{ emotion, name } in emotion_list" :key="emotion" :label="name" :value="emotion" />
+          </el-select>
+        </el-form-item>
+      </template>
       <el-form-item label="拼音位置">
         <el-radio-group v-model="property.pinyin_position">
           <el-radio v-for="{ value, label } in pinyinPositionList" :key="value" :label="value">
@@ -43,6 +59,7 @@ import {
   inforList,
   switchOption,
 } from '@/views/book/courseware/data/newWord';
+import { GetTextToAudioConfParamList } from '@/api/app';
 
 export default {
   name: 'NewWordSetting',
@@ -55,9 +72,26 @@ export default {
       wordShowList,
       inforList,
       switchOption,
+      voice_type_list: [],
+      emotion_list: [],
     };
   },
-  methods: {},
+  created() {
+    this.getTextToAudioConfParamList();
+  },
+  methods: {
+    // 得到文本转音频的配置参数列表
+    getTextToAudioConfParamList() {
+      GetTextToAudioConfParamList()
+        .then(({ status, voice_type_list, emotion_list }) => {
+          if (status === 1) {
+            this.voice_type_list = voice_type_list;
+            this.emotion_list = emotion_list;
+          }
+        })
+        .catch(() => {});
+    },
+  },
 };
 </script>
 

+ 26 - 12
src/views/book/courseware/create/components/question/pinyin_base/PinyinBase.vue

@@ -32,8 +32,7 @@
             style="width: 200px"
           />
         </div>
-        <span
-v-if="data.property.fun_type === 'input'" class="tips"
+        <span v-if="data.property.fun_type === 'input'" class="tips"
           >在需要加空的内容处插入 3 个或以上的下划线“_”。</span
         >
         <div v-if="data.audio_file_id">
@@ -84,7 +83,7 @@ import UploadAudio from '@/views/book/courseware/create/components/question/fill
 import { getPinyinBaseData, funList } from '@/views/book/courseware/data/pinyinBase';
 import { addTone, handleToneValue } from '@/views/book/courseware/data/common';
 import { getRandomNumber } from '@/utils';
-import { GetStaticResources } from '@/api/app';
+import { GetStaticResources, TextToAudioFile } from '@/api/app';
 
 export default {
   name: 'PinyinBasePage',
@@ -118,12 +117,14 @@ export default {
     'data.content': 'handleMindMap',
   },
   methods: {
-    uploads(file_id) {
+    uploads(file_id, index, file_url) {
       this.data.audio_file_id = file_id;
+      this.data.audio_file_url = file_url;
       this.data.file_id_list = [file_id];
     },
     deleteFiles() {
       this.data.audio_file_id = '';
+      this.data.audio_file_url = '';
       this.data.file_id_list = [];
     },
     // 自动生成音频
@@ -133,7 +134,18 @@ export default {
       if (this.data.character.trim() || this.data.content_hz) {
         data = {
           text: this.data.character.trim() || this.data.content_hz,
+          voice_type: this.data.property.voice_type,
+          emotion: this.data.property.emotion,
         };
+        TextToAudioFile(data)
+          .then(({ status, file_id, file_url }) => {
+            if (status === 1) {
+              this.data.audio_file_id = file_id;
+              this.data.audio_file_url = file_url;
+              this.data.file_id_list = [file_id];
+            }
+          })
+          .catch(() => {});
       } else if (this.data.content.trim()) {
         if (!this.matically_pinyin_obj[this.data.mark]) {
           this.handleItemAnswer(this.data);
@@ -142,15 +154,16 @@ export default {
         data = {
           pinyin: this.matically_pinyin_obj[this.data.mark],
         };
+        GetStaticResources(MethodName, data)
+          .then((res) => {
+            if (res.status === 1) {
+              this.data.audio_file_id = res.file_id;
+              this.data.audio_file_url = res.file_url;
+              this.data.file_id_list = [res.file_id];
+            }
+          })
+          .catch(() => {});
       }
-      GetStaticResources(MethodName, data)
-        .then((res) => {
-          if (res.status === 1) {
-            this.data.audio_file_id = res.file_id;
-            this.data.file_id_list = [res.file_id];
-          }
-        })
-        .catch(() => {});
     },
     handleReplaceTone(value, mark) {
       if (!value) return;
@@ -268,6 +281,7 @@ export default {
     changePinyin(item) {
       if (this.data.property.audio_generation_method === 'auto') {
         item.audio_file_id = '';
+        item.audio_file_url = '';
         this.data.file_id_list = [];
       }
     },

+ 37 - 1
src/views/book/courseware/create/components/question/pinyin_base/PinyinBaseSetting.vue

@@ -28,6 +28,23 @@
         </el-select>
       </el-form-item>
 
+      <template v-if="property.audio_generation_method === 'auto'">
+        <el-form-item label="音色">
+          <el-select v-model="property.voice_type" placeholder="请选择">
+            <el-option
+              v-for="{ voice_type, name } in voice_type_list"
+              :key="voice_type"
+              :label="name"
+              :value="voice_type"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="风格情感">
+          <el-select v-model="property.emotion">
+            <el-option v-for="{ emotion, name } in emotion_list" :key="emotion" :label="name" :value="emotion" />
+          </el-select>
+        </el-form-item>
+      </template>
       <el-form-item label="读音位置">
         <el-radio-group v-model="property.audio_position">
           <el-radio v-for="{ value, label } in audioPositionList" :key="value" :label="value">
@@ -60,6 +77,8 @@ import {
   markList,
 } from '@/views/book/courseware/data/pinyinBase';
 
+import { GetTextToAudioConfParamList } from '@/api/app';
+
 export default {
   name: 'PinyinBaseSetting',
   mixins: [SettingMixin],
@@ -72,9 +91,26 @@ export default {
       switchOption,
       funList,
       markList,
+      voice_type_list: [],
+      emotion_list: [],
     };
   },
-  methods: {},
+  methods: {
+    // 得到文本转音频的配置参数列表
+    getTextToAudioConfParamList() {
+      GetTextToAudioConfParamList()
+        .then(({ status, voice_type_list, emotion_list }) => {
+          if (status === 1) {
+            this.voice_type_list = voice_type_list;
+            this.emotion_list = emotion_list;
+          }
+        })
+        .catch(() => {});
+    },
+  },
+  created() {
+    this.getTextToAudioConfParamList();
+  },
 };
 </script>
 

+ 4 - 0
src/views/book/courseware/data/article.js

@@ -97,6 +97,8 @@ export function getArticleData() {
         pinyin_position: pinyinPositionLists[0].value,
         auto_wrap: switchOption[0].value, // 自动换行
         is_has_infor: inforList[0].value,
+        voice_type: '', // 音色
+        emotion: '', // 风格,情感
       },
       new_word_list: [],
       lrc_arr: [], // lrc 文件解析后的数据
@@ -147,6 +149,8 @@ export function getArticleData() {
         pinyin_position: pinyinPositionLists[0].value,
         auto_wrap: switchOption[0].value, // 自动换行
         is_has_infor: inforList[0].value,
+        voice_type: '', // 音色
+        emotion: '', // 风格,情感
       },
       new_word_list: [],
       lrc_arr: [], // lrc 文件解析后的数据

+ 4 - 0
src/views/book/courseware/data/dialogueArticle.js

@@ -137,6 +137,8 @@ export function getArticleData() {
         pinyin_position: pinyinPositionLists[0].value,
         auto_wrap: switchOption[0].value, // 自动换行
         is_has_infor: inforList[0].value,
+        voice_type: '', // 音色
+        emotion: '', // 风格,情感
       },
       new_word_list: [],
       lrc_arr: [], // lrc 文件解析后的数据
@@ -186,6 +188,8 @@ export function getArticleData() {
         pinyin_position: pinyinPositionLists[0].value,
         auto_wrap: switchOption[0].value, // 自动换行
         is_has_infor: inforList[0].value,
+        voice_type: '', // 音色
+        emotion: '', // 风格,情感
       },
       new_word_list: [],
       lrc_arr: [], // lrc 文件解析后的数据

+ 2 - 0
src/views/book/courseware/data/fill.js

@@ -61,6 +61,8 @@ export function getFillProperty() {
     view_pinyin: 'false', // 显示拼音
     pinyin_position: pinyinPositionList[0].value,
     is_first_sentence_first_hz_pinyin_first_char_upper_case: displayList[0].value, // 句首大写
+    voice_type: '', // 音色
+    emotion: '', // 风格,情感
   };
 }
 

+ 2 - 0
src/views/book/courseware/data/newWord.js

@@ -72,6 +72,8 @@ export function getNewWordProperty() {
     pinyin_position: pinyinPositionList[0].value,
     auto_wrap: switchOption[0].value, // 自动换行
     is_has_infor: inforList[0].value,
+    voice_type: '', // 音色
+    emotion: '', // 风格,情感
   };
 }
 

+ 4 - 0
src/views/book/courseware/data/pinyinBase.js

@@ -72,6 +72,9 @@ export function getPinyinBaseProperty() {
 
     fun_type: 'mark',
     answer_mode: 'select',
+
+    voice_type: '', // 音色
+    emotion: '', // 风格,情感
   };
 }
 
@@ -86,6 +89,7 @@ export function getPinyinBaseData() {
     content_hz: '',
     matically_pinyin_str: {},
     audio_file_id: '',
+    audio_file_url: '',
     file_id_list: [], // 文件 id
     mark: getRandomNumber(),
     record_list: [],

+ 2 - 3
src/views/book/courseware/preview/components/article/components/WordPhraseDetail.vue

@@ -291,7 +291,7 @@
 <script>
 import Strockplayredline from './Strockplayredline.vue';
 import Audio from './AudioRed.vue';
-import { GetStaticResources } from '@/api/app';
+import { TextToAudioFile } from '@/api/app';
 import { getCoursewareWordExampleSentenceList } from '@/api/article';
 
 export default {
@@ -832,8 +832,7 @@ export default {
               items.attrs.forEach((itemss) => {
                 if (itemss.key === 'pronunciation') {
                   // 音频
-                  let Mname = 'tool-TextToVoiceFile';
-                  GetStaticResources(Mname, {
+                  TextToAudioFile({
                     text: this.word.detail.new_word,
                   }).then((res) => {
                     _this.mp3Url = res.file_url;

+ 2 - 3
src/views/book/courseware/preview/components/article/components/Wordcard.vue

@@ -223,7 +223,7 @@ import Audio from './AudioRed.vue';
 import Strockplayredline from './Strockplayredline.vue';
 import Practice from './Practice.vue';
 import WordPhraseDetail from './WordPhraseDetail.vue';
-import { GetStaticResources, LearnWebSI } from '@/api/app';
+import { GetStaticResources, LearnWebSI, TextToAudioFile } from '@/api/app';
 
 export default {
   name: 'Wordcard',
@@ -431,8 +431,7 @@ export default {
             items.attrs.forEach((itemss) => {
               if (itemss.key === 'pronunciation') {
                 // 音频
-                let Mname = 'tool-TextToVoiceFile';
-                GetStaticResources(Mname, { text: this.word.detail.new_word }).then((res) => {
+                TextToAudioFile({ text: this.word.detail.new_word }).then((res) => {
                   // _this.mp3Url = res.file_url;
                   _this.word.detail.mp3Url = res.file_url;
                   this.loading = false;

+ 1 - 1
src/views/book/courseware/preview/components/character/CharacterPreview.vue

@@ -178,7 +178,7 @@
               <div class="words-left" :style="{}">
                 <AudioPlay
                   v-if="isEnable(data.property.is_enable_voice)"
-                  :file-id="item.audio_file_id ? item.audio_file_id : ''"
+                  :file-id="item.audio_file_id ? item.audio_file_id.file_url : ''"
                   :theme-color="
                     data.unified_attrib && data.unified_attrib.topic_color ? data.unified_attrib.topic_color : ''
                   "

+ 4 - 5
src/views/book/courseware/preview/components/pinyin_base/PinyinBasePreview.vue

@@ -11,7 +11,7 @@
         <div class="first-con">
           <AudioPlay
             v-if="data.audio_file_id && data.property.audio_position === 'front'"
-            :file-id="data.file_list[0].file_url"
+            :file-id="data.audio_file_url"
             :theme-color="data.unified_attrib && data.unified_attrib.topic_color ? data.unified_attrib.topic_color : ''"
           />
           <div
@@ -99,7 +99,7 @@
           </div>
           <AudioPlay
             v-if="data.audio_file_id && data.property.audio_position === 'back'"
-            :file-id="data.audio_file_id"
+            :file-id="data.audio_file_url"
           />
         </div>
         <div v-if="data.property.fun_type === 'mark'" class="tone-box">
@@ -159,7 +159,7 @@
           <div class="first-con">
             <AudioPlay
               v-if="data.audio_file_id && data.property.audio_position === 'front'"
-              :file-id="data.file_list[0].file_url"
+              :file-id="data.audio_file_url"
               :theme-color="
                 data.unified_attrib && data.unified_attrib.topic_color ? data.unified_attrib.topic_color : ''
               "
@@ -191,7 +191,7 @@
             </div>
             <AudioPlay
               v-if="data.audio_file_id && data.property.audio_position === 'back'"
-              :file-id="data.audio_file_id"
+              :file-id="data.audio_file_url"
             />
           </div>
         </div>
@@ -207,7 +207,6 @@ import PreviewMixin from '../common/PreviewMixin';
 import AudioPlay from '../character_base/components/AudioPlay.vue';
 import SoundRecord from '../../common/SoundRecord.vue';
 import { addTone, handleToneValue } from '@/utils/common';
-import { data } from 'jquery';
 
 export default {
   name: 'PinyinBasePreview',