用FunASR轻松实现音频转SRT字幕:完整脚本与解析

在视频创作、内容归档或多语言传播场景中,为音频生成字幕(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_indexend_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)

使用方法与注意事项

如何使用?

  1. 替换脚本中的input路径为你的音频文件(支持MP3、WAV、FLAC等格式)。
  2. 替换srt_output_path为你希望保存SRT的路径。
  3. 运行脚本,等待生成完成(首次运行会自动下载模型,耗时稍长)。

注意事项

  • 模型缓存 :如需指定模型缓存路径(避免重复下载),取消注释os.environ['MODELSCOPE_CACHE']并修改路径。
  • GPU加速 :若电脑有NVIDIA显卡,取消注释device="cuda:0"可大幅提升速度。
  • 字幕长度 :若觉得字幕过长/过短,可调整merge_length_s参数(如改为10秒或20秒)。
  • 多语言支持 :如需处理英文音频,可将language设为"en",识别更精准。

总结

借助FunASR的强大能力,我们只需几十行代码就能实现音频到SRT字幕的自动化转换,大幅提升视频创作、内容处理的效率。脚本中对中英文的差异化处理和时间戳关联逻辑,确保了字幕的准确性和可读性。

相关推荐
亿坊电商1 小时前
AI 数字人在处理音频时,如何确保声音的自然度?
人工智能·算法·音视频
金井PRATHAMA5 小时前
广泛分布于内侧内嗅皮层全层的速度细胞(speed cells)对NLP中的深层语义分析的积极影响和启示
人工智能·神经网络·自然语言处理·知识图谱
qq_429879676 小时前
qt webengine播放视频
开发语言·qt·音视频
开开心心就好6 小时前
Excel批量加密工具,一键保护多个文件
java·javascript·人工智能·安全·excel·音视频·语音识别
CodeShare6 小时前
RoD-TAL:罗马尼亚驾照考试问答基准
计算机视觉·自然语言处理·问答系统
培根芝士7 小时前
使用 Canvas 替代 <video> 标签加载并渲染视频
前端·javascript·音视频
LastWhisperw8 小时前
音频算法基础(语音识别 / 降噪 / 分离)
算法·音视频·语音识别
驱动小百科8 小时前
电脑没有声音了怎么恢复 快速解决音频故障
电脑·音视频·电脑没有声音·恢复电脑声音·电脑没有声音了怎么恢复
看兵马俑的程序员8 小时前
H.264视频的RTP有效载荷格式(翻译自:RFC6184 第5节 RTP有效载荷格式)
网络·音视频·h.264
生信宝典9 小时前
通用温度感知语言模型用于设计具备增强稳定性和活性的蛋白质
人工智能·语言模型·自然语言处理