在视频创作、内容归档或多语言传播场景中,为音频生成字幕(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字幕的自动化转换,大幅提升视频创作、内容处理的效率。脚本中对中英文的差异化处理和时间戳关联逻辑,确保了字幕的准确性和可读性。