如何让TTS生成的MP3匹配SRT/VTT时间戳或直接将SRT转语音?
解决带时间戳的多语言配音生成问题
方案一:直接基于翻译后的SRT生成符合时间戳的语音
这种方法能从根源上保证音频严格匹配时间戳,操作步骤如下:
解析翻译后的SRT文件
用Python提取每一条字幕的开始时间、结束时间和对应文本。示例代码:import re def parse_srt(srt_path): with open(srt_path, 'r', encoding='utf-8') as f: content = f.read() # 正则匹配SRT格式的条目 pattern = re.compile(r'(\d+)\n(\d{2}:\d{2}:\d{2},\d{3}) --> (\d{2}:\d{2}:\d{2},\d{3})\n(.+?)\n\n', re.DOTALL) matches = pattern.findall(content) subtitles = [] for match in matches: start_time = match[1].replace(',', '.') # 转换为ffmpeg兼容的时间格式 end_time = match[2].replace(',', '.') text = match[3].strip() subtitles.append({'start': start_time, 'end': end_time, 'text': text}) return subtitles逐段生成TTS音频
调用ElevenLabs API,为每一段字幕文本单独生成音频文件。示例代码(需替换你的API密钥和语音ID):import requests ELEVENLABS_API_KEY = "你的API密钥" VOICE_ID = "选择的语音ID" def generate_tts(text, output_path): url = f"https://api.elevenlabs.io/v1/text-to-speech/{VOICE_ID}" headers = { "Accept": "audio/mpeg", "Content-Type": "application/json", "xi-api-key": ELEVENLABS_API_KEY } data = { "text": text, "model_id": "eleven_multilingual_v2", "voice_settings": { "stability": 0.5, "similarity_boost": 0.5 } } response = requests.post(url, json=data) with open(output_path, 'wb') as f: f.write(response.content) # 遍历字幕生成单段音频 subtitles = parse_srt("翻译后的字幕.srt") for idx, sub in enumerate(subtitles): generate_tts(sub['text'], f"segment_{idx}.mp3")用FFmpeg拼接音频并匹配时间戳
计算每段音频之间需要的静音时长,然后用FFmpeg把所有小段音频和静音拼接成最终音频。示例命令:# 先创建拼接列表文件 echo "file 'segment_0.mp3'" > concat_list.txt # 遍历字幕,计算相邻片段间的静音时长并生成静音文件 for ((i=1; i<${#subtitles[@]}; i++)); do # 转换时间为秒数 prev_end=$(echo "${subtitles[i-1]['end']}" | awk -F: '{ print ($1*3600)+($2*60)+$3 }') curr_start=$(echo "${subtitles[i]['start']}" | awk -F: '{ print ($1*3600)+($2*60)+$3 }') silence_duration=$(echo "$curr_start - $prev_end" | bc) # 若需要静音则生成并添加到列表 if (( $(echo "$silence_duration > 0" | bc -l) )); then ffmpeg -f lavfi -i anullsrc=r=44100:cl=stereo -t $silence_duration -q:a 9 -acodec libmp3lame silence_${i}.mp3 echo "file 'silence_${i}.mp3'" >> concat_list.txt fi echo "file 'segment_${i}.mp3'" >> concat_list.txt done # 拼接所有片段得到最终音频 ffmpeg -f concat -safe 0 -i concat_list.txt -c copy final_audio.mp3
方案二:调整已生成的整段MP3匹配时间戳
如果已经有基于完整文本生成的TTS音频,可通过以下步骤调整:
- 拆分音频并匹配文本:用WhisperX识别整段MP3的语音时间戳,将其与SRT中的文本段落一一对应,得到每段文本在MP3中的实际起止位置。
- 调整时长或插入静音:对比SRT要求的时间戳和音频实际分段时间,对每段音频进行变速(保持音调不变)或在段落间插入静音,最后用FFmpeg拼接成符合要求的音频。示例变速命令:
# 假设某段音频实际时长4秒,需拉长至5秒,调整语速为原速的80% ffmpeg -i segment.mp3 -filter:a "atempo=0.8" adjusted_segment.mp3
内容的提问来源于stack exchange,提问作者Charles Skorsky
相关产品推荐
相关产品推荐

