@@ -5,17 +5,26 @@ import { generateTTS } from '@/app/request/playground';
55import { IGenerateTTSProp } from '@/app/type' ;
66import { addLogEvent } from '@/app/utils/mitter' ;
77import { TRANSLATE_OPTIONS } from '@/app/const/translate_option' ;
8+ import { OPENAI_VOICE_OPTIONS , OPENAI_MODEL_OPTIONS } from '@/app/const/openai_voices' ;
89
910interface Props {
1011 onFinish : ( ) => void ;
1112 videoId : string ;
1213}
1314
15+ // Extended form type to include OpenAI-specific fields
16+ interface FormValues extends IGenerateTTSProp {
17+ openai_voice ?: string ;
18+ openai_model ?: string ;
19+ openai_instructions ?: string ;
20+ }
21+
1422const ChineseAudio : React . FC < Props > = ( { onFinish, videoId } ) => {
15- const [ form ] = Form . useForm < IGenerateTTSProp > ( ) ;
23+ const [ form ] = Form . useForm < FormValues > ( ) ;
1624
1725 const state = useReactive ( {
1826 translateSrtOk : false ,
27+ selectedVendor : 'openai' , // Default to OpenAI TTS
1928 } ) ;
2029
2130 const { run : generateTTSRun , loading : generateTTSLoading } = useRequest (
@@ -38,18 +47,48 @@ const ChineseAudio: React.FC<Props> = ({ onFinish, videoId }) => {
3847 ) ;
3948
4049 const handleGenerateTTS = async ( ) => {
41- const { tts_vendor, tts_key, tts_character } = form . getFieldsValue ( ) ;
50+ const formValues = form . getFieldsValue ( ) as any ; // Type assertion to handle form values
51+ const { tts_vendor, tts_key, tts_character, openai_voice, openai_model, openai_instructions } = formValues ;
52+
4253 const data : IGenerateTTSProp = {
4354 video_id : videoId ,
4455 tts_vendor,
45- tts_key,
46- tts_character,
56+ tts_key : tts_key || '' , // Only used for Edge TTS if needed
57+ tts_character : tts_character || '' ,
4758 } ;
59+
60+ // Add OpenAI-specific parameters if OpenAI vendor is selected
61+ if ( tts_vendor === 'openai' ) {
62+ data . tts_params = {
63+ voice : openai_voice || 'alloy' ,
64+ model : openai_model || 'tts-1' ,
65+ instructions : openai_instructions || undefined ,
66+ } ;
67+ }
68+
4869 generateTTSRun ( data ) ;
4970 } ;
5071
72+ const handleVendorChange = ( vendor : string ) => {
73+ state . selectedVendor = vendor ;
74+ // Clear form fields when changing vendor
75+ if ( vendor === 'openai' ) {
76+ form . setFieldsValue ( {
77+ tts_character : '' , // Clear Edge TTS character when switching to OpenAI
78+ openai_voice : 'alloy' , // Set default OpenAI voice
79+ openai_model : 'tts-1' , // Set default OpenAI model
80+ } ) ;
81+ } else {
82+ form . setFieldsValue ( {
83+ tts_character : 'zh-CN-XiaoyiNeural' , // Set default Edge TTS character
84+ } ) ;
85+ }
86+ } ;
87+
5188 useEffect ( ( ) => {
5289 form . setFieldValue ( 'videoId' , videoId ) ;
90+ // Initialize vendor state from form initial values
91+ state . selectedVendor = 'openai' ;
5392 } , [ videoId ] ) ;
5493
5594 return (
@@ -60,34 +99,78 @@ const ChineseAudio: React.FC<Props> = ({ onFinish, videoId }) => {
6099 layout = "horizontal"
61100 initialValues = { {
62101 videoId,
63- tts_vendor : 'edge' ,
102+ tts_vendor : 'openai' , // Default to OpenAI
64103 tts_key : '' ,
65104 tts_character : 'zh-CN-XiaoyiNeural' ,
105+ openai_voice : 'alloy' ,
106+ openai_model : 'tts-1' ,
107+ openai_instructions : '' ,
66108 } }
67109 onSubmitCapture = { onFinish }
68110 >
69111 < Form . Item label = "视频ID" name = { 'videoId' } >
70112 < Input disabled value = { videoId } />
71113 </ Form . Item >
72- < Form . Item label = { 'TTS vendor ' } >
114+ < Form . Item label = { 'TTS Vendor ' } >
73115 < Form . Item
74116 name = "tts_vendor"
75117 style = { { display : 'inline-block' , width : '200px' } }
76118 >
77119 < Select
78120 placeholder = "选择TTS vendor"
79- options = { [ { value : 'edge' , label : 'edge' } ] }
121+ onChange = { handleVendorChange }
122+ options = { [
123+ { value : 'openai' , label : 'OpenAI TTS (推荐)' } ,
124+ { value : 'edge' , label : 'Microsoft Edge TTS (已弃用)' }
125+ ] }
80126 />
81127 </ Form . Item >
82128 </ Form . Item >
83- < Form . Item label = { 'TTS Character' } >
84- < Form . Item name = "tts_character" >
85- < Select placeholder = "选择TTS Character" options = { TRANSLATE_OPTIONS } />
129+
130+ { /* Edge TTS Configuration */ }
131+ { state . selectedVendor === 'edge' && (
132+ < >
133+ < Form . Item label = { '注意' } >
134+ < div style = { { color : '#ff4d4f' , marginBottom : '10px' } } >
135+ ⚠️ Edge TTS 已弃用,建议使用 OpenAI TTS 获得更好的语音质量
136+ </ div >
137+ </ Form . Item >
138+ < Form . Item label = { 'Edge Character' } >
139+ < Form . Item name = "tts_character" >
140+ < Select placeholder = "选择Edge TTS角色" options = { TRANSLATE_OPTIONS } />
141+ </ Form . Item >
142+ </ Form . Item >
143+ </ >
144+ ) }
145+
146+ { /* OpenAI TTS Configuration */ }
147+ { state . selectedVendor === 'openai' && (
148+ < >
149+ < Form . Item label = { 'OpenAI Voice' } >
150+ < Form . Item name = "openai_voice" >
151+ < Select placeholder = "选择OpenAI语音" options = { OPENAI_VOICE_OPTIONS } />
152+ </ Form . Item >
153+ </ Form . Item >
154+ < Form . Item label = { 'OpenAI Model' } >
155+ < Form . Item name = "openai_model" >
156+ < Select placeholder = "选择OpenAI模型" options = { OPENAI_MODEL_OPTIONS } />
157+ </ Form . Item >
158+ </ Form . Item >
159+ < Form . Item label = { 'Voice Instructions' } name = "openai_instructions" >
160+ < Input . TextArea
161+ placeholder = "可选:语音指令,如'Speak in a cheerful and positive tone'"
162+ rows = { 2 }
163+ />
164+ </ Form . Item >
165+ </ >
166+ ) }
167+
168+ { /* Only show API key field for Edge TTS */ }
169+ { state . selectedVendor === 'edge' && (
170+ < Form . Item label = "Key" name = { 'tts_key' } >
171+ < Input placeholder = "密钥(Edge TTS可选)" />
86172 </ Form . Item >
87- </ Form . Item >
88- < Form . Item label = "key" name = { 'tts_key' } >
89- < Input />
90- </ Form . Item >
173+ ) }
91174 < Form . Item label = { '生成TTS' } >
92175 < Button
93176 type = "primary"
0 commit comments