用 FunASR 自动生成字幕:从音频/视频一键导出 SRT 和 VTT

要给视频或音频配字幕,不一定要上传到云端或买 API。FunASR 可以在本地、免费地把语音转成带时间戳的 SRTVTT 字幕,还能标注说话人。中文尤其强,同时支持 50+ 语言。下面的命令和代码都已实测。

第一步(视频):先抽出音频

如果源文件是视频,用 ffmpeg 抽出 16kHz 单声道音频(FunASR 的标准输入):

ffmpeg -i video.mp4 -ar 16000 -ac 1 audio.wav

纯音频文件(wav/mp3/m4a 等)可跳过这步。

最快:一行命令出 SRT

pip install -U funasr
funasr audio.wav -f srt -o ./subs

./subs/audio.srt 生成标准 SRT 字幕,时间戳真实可用:

1
00:00:00,000 --> 00:00:05,546
欢迎大家来体验达摩院推出的语音识别模型

--spk 可以按说话人分句(适合访谈、会议):

funasr meeting.wav --spk -f srt -o ./subs

用 Python:同时导出 SRT 和 VTT(带说话人)

需要更多控制(比如同时要网页用的 VTT、自定义说话人前缀)时,用 Python 直接从识别结果里的 sentence_info 拼字幕:

from funasr import AutoModel
from funasr.utils.postprocess_utils import rich_transcription_postprocess

model = AutoModel(model="iic/SenseVoiceSmall", vad_model="fsmn-vad", spk_model="cam++", device="cuda")
res = model.generate(input="audio.wav")
segments = res[0]["sentence_info"]   # 每段含 start/end(毫秒)、spk、sentence

def ts(ms, sep):                     # 毫秒 -> HH:MM:SS,mmm(SRT 用 "," / VTT 用 ".")
    h, mm, ss, mmm = ms//3600000, (ms%3600000)//60000, (ms%60000)//1000, ms%1000
    return "%02d:%02d:%02d%s%03d" % (h, mm, ss, sep, mmm)

with open("subs.srt", "w", encoding="utf-8") as f:
    for i, s in enumerate(segments):
        text = rich_transcription_postprocess(s["sentence"])
        f.write("%d\n%s --> %s\nSpeaker %s: %s\n\n" % (i+1, ts(s["start"], ","), ts(s["end"], ","), s["spk"], text))

with open("subs.vtt", "w", encoding="utf-8") as f:
    f.write("WEBVTT\n\n")
    for s in segments:
        text = rich_transcription_postprocess(s["sentence"])
        f.write("%s --> %s\n<v Speaker %s>%s\n\n" % (ts(s["start"], "."), ts(s["end"], "."), s["spk"], text))

实测输出(SRT):

1
00:00:00,610 --> 00:00:05,530
Speaker 0: 欢迎大家来体验达摩院推出的语音识别模型

注意一定要用 rich_transcription_postprocess 清掉 SenseVoice 的 <|zh|> 等标签,否则标签会混进字幕。

最后(可选):把字幕烧进视频

ffmpeg -i video.mp4 -vf subtitles=subs.srt output.mp4

为什么用 FunASR 做字幕

FunASR 是通义实验室开源的工业级语音识别工具包。

在 GitHub 上 Star FunASR ★