操作背景
短视频、在线课程、影视剪辑等越来越多的内容需要字幕,手工添加字幕不仅耗时,还容易出错。
腾讯云录音文件识别提供了字幕场景专用的返回格式(
ResTextFormat=3),识别结果按标点自动分段,每段附带精确的起止时间戳,可以直接生成 SRT 字幕文件。配合 SentenceMaxLength 参数控制单行字幕字数,无需客户端自行断句。
总体流程

代码开发
步骤一:格式判断与音频准备
录音文件识别直接支持以下格式,无需 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 转为 wavextract_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_urlresp = client.CreateRecTask(req)task_id = resp.Data.TaskId
ResTextFormat=3 与 SentenceMaxLength 的配合:ResTextFormat=3:服务端按标点符号(句号、逗号、问号等)对识别结果进行分段。SentenceMaxLength=15:如果某段超过 15 个字,服务端会自动在合适的位置拆分,确保每行不超限。这两个参数配合,服务端完成了所有断句工作,客户端不再需要任何分行逻辑。
步骤三:查询识别结果
轮询
DescribeTaskStatus 接口,等待识别完成:while True:resp = client.DescribeTaskStatus(req)status = resp.Data.StatusStrif status == "success":result_detail = resp.Data.ResultDetailbreakelif status == "failed":print(f"失败: {resp.Data.ErrorMsg}")returntime.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 // 3600000minutes = (ms % 3600000) // 60000seconds = (ms % 60000) // 1000millis = ms % 1000return f"{hours:02d}:{minutes:02d}:{seconds:02d},{millis:03d}"
生成结果示例:
100:00:00,500 --> 00:00:03,200大家好,欢迎来到今天的课程。200: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 生成(遍历结果输出字幕)
相关链接
识别结果数据结构
工程代码地址