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

短视频、在线课程、影视剪辑等越来越多的内容需要字幕,手工添加字幕不仅耗时,还容易出错。腾讯云录音文件识别提供了字幕场景专用的返回格式(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_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.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}"

生成结果示例:

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 生成(遍历结果输出字幕)

十、相关链接

·录音文件识别请求 API 文档

·识别结果数据结构

·工程代码地址

赞 (0)
上一篇 4天前
下一篇 4天前