在视频创作、内容归档或多语言传播场景中,为音频生成字幕(SRT文件)是一项常见需求。借助开源语音识别工具FunASR,我们可以快速实现从音频到字幕的自动化转换。
FunASR能轻松的识别音频,并切分好句子,但是我试了几种方式,都不能生成srt字幕文件,所以我就自己写了一个脚本来生成,大家可以看看!
什么是FunASR?
FunASR是阿里巴巴达摩院推出的开源语音识别工具包,支持多语言语音识别、语音活动检测(VAD)、标点预测等功能,且模型轻量化、精度高,非常适合开发者快速搭建语音处理应用。
本文的脚本正是基于FunASR的能力,实现"音频输入→语音识别→时间戳提取→SRT字幕生成"的全流程自动化。
准备工作:环境搭建
在使用脚本前,需先安装FunASR。通过pip即可快速安装:
bash
pip install funasr # 基础版本
安装完成后,即可运行本文的脚本。
脚本完整解析
以下是基于FunASR生成SRT文件的完整脚本,我们将逐段解析其功能:
python
# -*- coding: utf-8 -*-
import os
# os.environ['MODELSCOPE_CACHE']='./models' # 可选:指定模型缓存路径
from funasr import AutoModel
from funasr.utils.postprocess_utils import rich_transcription_postprocess
1. 时间戳格式化函数
SRT字幕的时间戳格式为HH:MM:SS,mmm
(时:分:秒,毫秒),需要将FunASR返回的"毫秒"时间转换为该格式:
python
def format_time_ms(milliseconds):
"""将毫秒数格式化为SRT时间戳格式 (HH:MM:SS,mmm)"""
# 拆分毫秒为"秒"和"剩余毫秒"
seconds, ms = divmod(milliseconds, 1000)
# 拆分总秒数为"时、分、秒"
hours, remainder = divmod(seconds, 3600)
minutes, seconds = divmod(remainder, 60)
# 格式化输出(确保两位数/三位数)
return f"{hours:02d}:{minutes:02d}:{seconds:02d},{ms:03d}"
示例 :输入83456
毫秒(即83秒456毫秒),输出为00:01:23,456
。
2. 加载FunASR模型
FunASR的AutoModel
可以一键加载预训练模型,这里我们同时启用"语音识别+VAD+标点预测"功能:
python
model_dir = "damo/speech_paraformer-large-vad-punc_asr_nat-zh-cn-16k-common-vocab8404-pytorch"
model = AutoModel(
model=model_dir, # 语音识别主模型(支持中英文)
vad_model="fsmn-vad", # 语音活动检测模型(区分语音/非语音)
punc_model='ct-punc', # 标点预测模型(自动添加逗号、句号等)
vad_kwargs={"max_single_segment_time": 30000}, # VAD最大片段时长(30秒)
# device="cuda:0", # 可选:启用GPU加速(需安装CUDA)
)
- 主模型 :
speech_paraformer-large
是达摩院训练的大模型,支持中文普通话,识别精度高。 - VAD模型:用于分割音频中的"有效语音片段",避免非语音部分干扰。
- 标点模型:自动为识别结果添加标点,让字幕更符合阅读习惯。
3. 音频识别与结果生成
调用model.generate
对音频文件进行处理,获取带时间戳的识别结果:
python
res = model.generate(
input="C:\\Data\\CodeProject\\llm\\FunASR\\examples\\self\\111.mp3", # 音频文件路径
cache={},
language="auto", # 自动检测语言(支持中、英、粤、日、韩等)
use_itn=True, # 启用逆文本规范化(如"123"→"一百二十三")
batch_size_s=60, # 批量处理时长(60秒)
merge_vad=True, # 合并VAD分割的片段
merge_length_s=15, # 字幕合并最大时长(15秒,避免字幕过长)
)
关键参数说明:
input
:支持本地音频路径(如MP3、WAV)或URL。use_itn=True
:将数字、日期等转换为自然语言(如"2023年"而非"2023 nian")。merge_length_s=15
:控制单条字幕的最大时长(15秒),避免字幕停留过久。
调用后,res
将返回识别结果,包含文本内容(text
)和每个字符/单词的时间戳(timestamp
)。
4. 生成SRT文件核心逻辑
将识别结果转换为SRT格式,需要按时间戳分割文本,并添加序号和时间戳:
python
def save_as_srt_with_timestamp_array(res, srt_file_path):
if not res or len(res) == 0:
print("结果为空")
return
# 从结果中提取文本和时间戳
result = res[0]
text = result.get('text', '').replace('\t','').replace('\n','') # 去除换行和制表符
timestamps = result.get('timestamp', []) # 时间戳数组(每个元素为[开始毫秒, 结束毫秒])
with open(srt_file_path, 'w', encoding='utf-8') as f:
i = 0 # 文本字符索引
paragraph = 0 # 字幕序号
content_tmp = "" # 临时存储当前字幕内容
start_index = 0 # 当前字幕的时间戳起始索引
end_index = -1 # 当前字幕的时间戳结束索引
while i < len(text):
char = text[i]
# 处理英文字母(按单词分割,避免单词被截断)
if char.isalpha() and char.isascii():
word_start = i
# 找到整个英文单词的结束位置
while i < len(text) and text[i].isalpha() and text[i].isascii():
i += 1
word = text[word_start:i]
end_index += 1 # 英文单词整体对应一个时间戳索引
content_tmp += word
# 处理中文字符(单字分割)
elif '\u4e00' <= char <= '\u9fff': # 基本汉字范围
end_index += 1 # 每个汉字对应一个时间戳索引
i += 1
content_tmp += char
# 处理其他字符(标点、空格等,作为字幕分割点)
else:
# 写入当前字幕
start_ms = timestamps[start_index][0]
end_ms = timestamps[end_index][1]
paragraph += 1
f.write(f"{paragraph}\n")
f.write(f"{format_time_ms(int(start_ms))} --> {format_time_ms(int(end_ms))}\n")
f.write(f"{content_tmp}\n\n")
# 重置临时变量,准备下一段字幕
i += 1
content_tmp = ""
start_index = end_index + 1
核心逻辑:
- 区分中英文处理:英文按"单词"分割(避免"hel-lo"这样的截断),中文按"单字"分割。
- 以标点、空格等作为字幕分割点,确保每条字幕语义完整。
- 用
start_index
和end_index
关联文本与时间戳,保证字幕内容与时间匹配。
5. 执行与输出
最后指定输出路径,调用函数生成SRT文件:
python
# 生成SRT文件(与音频同名,路径自定义)
srt_output_path = "C:\\Data\\CodeProject\\llm\\FunASR\\examples\\self\\111.srt"
save_as_srt_with_timestamp_array(res, srt_output_path)
使用方法与注意事项
如何使用?
- 替换脚本中的
input
路径为你的音频文件(支持MP3、WAV、FLAC等格式)。 - 替换
srt_output_path
为你希望保存SRT的路径。 - 运行脚本,等待生成完成(首次运行会自动下载模型,耗时稍长)。
注意事项
- 模型缓存 :如需指定模型缓存路径(避免重复下载),取消注释
os.environ['MODELSCOPE_CACHE']
并修改路径。 - GPU加速 :若电脑有NVIDIA显卡,取消注释
device="cuda:0"
可大幅提升速度。 - 字幕长度 :若觉得字幕过长/过短,可调整
merge_length_s
参数(如改为10秒或20秒)。 - 多语言支持 :如需处理英文音频,可将
language
设为"en"
,识别更精准。
总结
借助FunASR的强大能力,我们只需几十行代码就能实现音频到SRT字幕的自动化转换,大幅提升视频创作、内容处理的效率。脚本中对中英文的差异化处理和时间戳关联逻辑,确保了字幕的准确性和可读性。