文档中心>实践教程>语音识别>通过录音文件识别实现视频自动生成字幕

通过录音文件识别实现视频自动生成字幕

最近更新时间:2026-04-22 17:39:04

我的收藏

操作背景

短视频、在线课程、影视剪辑等越来越多的内容需要字幕,手工添加字幕不仅耗时,还容易出错。

腾讯云录音文件识别提供了字幕场景专用的返回格式(ResTextFormat=3),识别结果按标点自动分段,每段附带精确的起止时间戳,可以直接生成 SRT 字幕文件。配合 SentenceMaxLength 参数控制单行字幕字数,无需客户端自行断句。

本文基于 video-srt 开源工程进行改进,实现从视频到字幕的全自动流程。

总体流程





代码开发

以下代码为核心思路示意,为突出逻辑主线进行了精简。完整工程(含异常处理、日志、配置管理等)见 附录 的 GitHub 链接。

步骤一:格式判断与音频准备

录音文件识别直接支持以下格式,无需 ffmpeg 转换
wav、mp3、m4a、flv、mp4、wma、3gp、amr、aac、ogg-opus、flac。

如果输入文件是上述格式之一(如 mp4),直接上传到 COS 获取 URL 即可。如果是不支持的格式(如 mkv、avi、rmvb),则先用 ffmpeg 转为 wav:
# 录音文件识别直接支持的格式
SUPPORTED_FORMATS = {'.wav', '.mp3', '.m4a', '.flv', '.mp4', '.wma', '.3gp', '.amr', '.aac', '.ogg', '.flac'}

file_ext = os.path.splitext(input_path)[1].lower()

if file_ext in SUPPORTED_FORMATS:
# 直接上传,无需转换
upload_file(input_path, cos_file_path)
else:
# 不支持的格式,用 ffmpeg 转为 wav
extract_audio(input_path, audio_path)
upload_file(audio_path, cos_file_path)
ffmpeg 提取音频的命令(仅不支持格式时使用):
# 使用参数列表 + shell=False,避免路径含空格/特殊字符导致的注入风险
subprocess.run(
["ffmpeg", "-i", video_path, "-vn", "-ar", "16000", audio_path],
shell=False, check=True,
)
参数说明:
参数
说明
-i
输入文件
-vn
禁用视频流(只抽音频)
-ar 16000
采样率设为 16kHz(录音文件识别推荐采样率

步骤二:创建识别任务

调用 CreateRecTask 接口,关键参数如下:
req = models.CreateRecTaskRequest()
params = {
"ChannelNum": 1,
"ResTextFormat": 3, # 按标点分段,字幕场景专用
"SentenceMaxLength": 15, # 单行字幕最大字数
"SourceType": 0, # URL 方式
"ConvertNumMode": 1 # 智能数字转换
}
req._deserialize(params)
req.EngineModelType = "16k_zh"
req.Url = audio_cos_url

resp = client.CreateRecTask(req)
task_id = resp.Data.TaskId
ResTextFormat=3SentenceMaxLength 的配合:
ResTextFormat=3:服务端按标点符号(句号、逗号、问号等)对识别结果进行分段。
SentenceMaxLength=15:如果某段超过 15 个字,服务端会自动在合适的位置拆分,确保每行不超限。
这两个参数配合,服务端完成了所有断句工作,客户端不再需要任何分行逻辑。

步骤三:查询识别结果

轮询 DescribeTaskStatus 接口,等待识别完成:
while True:
resp = client.DescribeTaskStatus(req)
status = resp.Data.StatusStr
if status == "success":
result_detail = resp.Data.ResultDetail
break
elif status == "failed":
print(f"失败: {resp.Data.ErrorMsg}")
return
time.sleep(5)

步骤四:解析结果生成 SRT

识别成功后,ResultDetail 是一个 SentenceDetail 数组,每条直接对应一行字幕:
[
{
"FinalSentence": "大家好,欢迎来到今天的课程。",
"StartMs": 500,
"EndMs": 3200,
"SpeakerId": 0,
"SpeechSpeed": 4.2
},
{
"FinalSentence": "今天我们要讲的主题是机器学习。",
"StartMs": 3500,
"EndMs": 6800,
"SpeakerId": 0,
"SpeechSpeed": 4.5
}
]
字幕生成只需关注三个字段:
字段
说明
FinalSentence
字幕文本
StartMs
开始时间(毫秒)
EndMs
结束时间(毫秒)
生成 SRT 的代码非常简洁:
def to_srt(result_detail):
srt_lines = []
for i, sentence in enumerate(result_detail, 1):
start_time = ms_to_srt_time(sentence["StartMs"])
end_time = ms_to_srt_time(sentence["EndMs"])
text = sentence["FinalSentence"]
srt_lines.append(f"{i}\\n{start_time} --> {end_time}\\n{text}\\n")
return "\\n".join(srt_lines)


def ms_to_srt_time(ms):
"""毫秒转 SRT 时间格式 (HH:MM:SS,mmm)"""
hours = ms // 3600000
minutes = (ms % 3600000) // 60000
seconds = (ms % 60000) // 1000
millis = ms % 1000
return f"{hours:02d}:{minutes:02d}:{seconds:02d},{millis:03d}"
生成结果示例:
1
00:00:00,500 --> 00:00:03,200
大家好,欢迎来到今天的课程。

2
00:00:03,500 --> 00:00:06,800
今天我们要讲的主题是机器学习。

步骤五:加载字幕

将生成的 .srt 文件与视频文件放在同一目录,名称保持一致(如 video.mp4 + video.srt),使用 VLC、PotPlayer 等播放器打开视频即可自动加载字幕。

效果调优

场景
建议
字幕单行太长
调小 SentenceMaxLength(推荐 15-25)
字幕太碎、频繁换行
调大 SentenceMaxLength(如 30-40)
需要中英混合字幕
引擎改为 16k_zh_en
需要过滤语气词(“嗯”“啊”)
请求参数加 FilterModal=1
视频有背景音乐
尽量在剪辑阶段降低背景音乐音量
文件超过 1GB
URL 方式最大支持 1GB / 5 小时,超过需先分割

附录

完整工程结构

video-srt/
├── main.py # 主入口:格式判断 + 流程串联
├── common/
│ ├── config.py # 输出路径配置
│ └── logger.py # 日志模块
├── cos/
│ ├── config.py # COS 配置(密钥、桶名、区域)
│ └── cos_cli.py # COS 客户端(上传、获取URL)
├── ffmpeg/
│ └── ffmpeg.py # FFmpeg 音频提取(仅不支持格式时使用)
├── tencent/
│ ├── config.py # ASR 配置(密钥、引擎)
│ └── tencent_cli.py # ASR 客户端(创建任务、轮询结果)
└── tool/
├── time_format.py # 时间格式化(毫秒→SRT时间)
└── to_srt.py # SRT 生成(遍历结果输出字幕)


相关链接