Python中使用Vosk获取音频文件中转录文本对应时间位置的方法
解决方案
Vosk 的 KaldiRecognizer 原生就支持输出单词级时间戳,不需要自行通过采样点推算,操作方法如下:
- 初始化识别器后开启单词详情输出开关
在你创建识别器实例的代码后新增一行调用SetWords(True):
sample_rate=16000 model = Model("model") rec = KaldiRecognizer(model, sample_rate) # 新增这行开启单词时间戳输出 rec.SetWords(True)
- 读取返回结果中的单词详情
开启开关后,rec.Result()和rec.FinalResult()返回的 JSON 结构中会多出result字段,该字段是数组格式,每个元素对应一个识别到的单词,包含四个属性:
word:单词文本内容start:单词在音频中的开始时间,单位为秒end:单词在音频中的结束时间,单位为秒conf:该单词的识别置信度,取值0-1,数值越高准确度越高
你可以参考如下修改后的写入逻辑,同时保存文本和时间戳信息:
while True: data = process.stdout.read(4000) if len(data) == 0: break if rec.AcceptWaveform(data): res = json.loads(rec.Result()) # 先写入每个单词的时间信息 if 'result' in res: for word_item in res['result']: file.write(f"{word_item['word']} | 开始:{word_item['start']:.2f}s | 结束:{word_item['end']:.2f}s | 置信度:{word_item['conf']:.2f}\n") # 再写入整段识别结果 file.write(f"整段结果:{res['text']}\n\n") # 处理最后一段识别结果,推荐使用 FinalResult 替代 Result 确保返回完整信息 final_res = json.loads(rec.FinalResult()) if 'result' in final_res: for word_item in final_res['result']: file.write(f"{word_item['word']} | 开始:{word_item['start']:.2f}s | 结束:{word_item['end']:.2f}s | 置信度:{word_item['conf']:.2f}\n") file.write(f"整段结果:{final_res['text']}") file.close()
注意事项
- 如果调用
SetWords时报错,可先升级 vosk 库到最新版本,旧版本未开放该接口 rec.PartialResult()返回的是未稳定的中间识别结果,即使开启了单词开关,返回的时间戳和内容也可能后续调整,最终结果请以Result()和FinalResult()的返回为准
内容的提问来源于stack exchange,提问作者chrisroode
相关产品推荐
相关产品推荐

