如何借助已知转录文本通过Vosk获取音频中单词的起止时间?
如何用Vosk结合已知准确转录文本获取单词起止时间
Vosk本身并不支持直接传入自定义转录文本并强制对齐音频以生成单词时间戳的功能——它的核心是自动语音识别(ASR),会基于模型输出最匹配的转录结果,而非严格对齐外部给定的文本。不过你可以通过以下几种方案实现需求:
方案1:使用专门的强制对齐工具
这类工具的设计目标就是将已知文本与音频对齐,生成精准的单词起止时间,比强行用Vosk适配更可靠。推荐两个常用工具:
Montreal Forced Aligner (MFA)
这是目前主流的开源对齐工具,支持多语言,步骤如下:
- 通过pip或conda安装MFA
- 准备WAV格式的音频文件,以及对应准确转录的纯文本文件(每行对应一段音频内容)
- 运行对齐命令,输出包含单词时间戳的TextGrid文件,之后可通过Python的
praatio库解析提取时间信息。
aeneas
轻量级Python库,无需训练模型,适合快速处理短音频:
from aeneas.executetask import ExecuteTask from aeneas.task import Task import json # 配置对齐任务 config_string = u"task_language=en|os_task_file_format=json|is_text_type=plain" task = Task(config_string=config_string) task.audio_file_path_absolute = "/path/to/your/audio.wav" task.text_file_path_absolute = "/path/to/your/accurate_transcript.txt" task.sync_map_file_path_absolute = "/path/to/output_timecodes.json" # 执行对齐 ExecuteTask(task).execute() # 读取并输出结果 with open("/path/to/output_timecodes.json", "r") as f: sync_map = json.load(f) for segment in sync_map["fragments"]: print(f"单词: {segment['lines'][0]}, 开始时间: {segment['begin']}, 结束时间: {segment['end']}")
方案2:基于Vosk识别结果修正对齐
如果你一定要依托Vosk的生态,可以先获取Vosk带时间戳的识别结果,再与准确转录文本做匹配映射:
- 从Vosk输出中提取所有带时间标记的单词列表
- 用编辑距离算法(比如
difflib库)找到Vosk识别文本与准确文本的对应关系 - 匹配对应单词的时间戳,对差异部分(漏识别、错识别)自定义处理逻辑(适合文本差异较小的场景)
示例代码片段:
import json import difflib # 从你的Vosk结果中提取单词列表 vosk_words = [] for res in results: if 'alternatives' in res: vosk_words.extend(res['alternatives'][0].get('words', [])) vosk_transcript_words = [w['word'] for w in vosk_words] # 你的准确转录文本(拆分为单词列表) accurate_transcript_words = "your exact transcript content here".split() # 匹配对齐 seq_matcher = difflib.SequenceMatcher(None, vosk_transcript_words, accurate_transcript_words) aligned_timecodes = [] for tag, i1, i2, j1, j2 in seq_matcher.get_opcodes(): if tag == 'equal': # 完全匹配的单词直接复用Vosk的时间戳 for idx in range(i1, i2): aligned_timecodes.append({ 'word': vosk_words[idx]['word'], 'start': vosk_words[idx]['start'], 'end': vosk_words[idx]['end'] }) # 可自定义处理插入、删除、替换等差异场景
方案3:尝试Vosk语法约束(效果有限)
Vosk支持设置语法规则引导识别,但这不是强制对齐,仅能让模型优先匹配给定文本,仍可能出现偏差:
# 初始化KaldiRecognizer后添加语法约束 grammar = '["your exact transcript here", "[unk]"]' rec.SetGrammar(grammar)
这种方法仅当准确文本与音频高度匹配时可能有用,无法保证完全对齐,时间戳准确性仍依赖Vosk的识别结果。
内容的提问来源于stack exchange,提问作者Jason Maldonis
相关产品推荐
相关产品推荐

