You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取VOSK语音识别中每个单词的时间戳详情?

如何用VOSK获取音频中每个单词的时间信息?

你的需求完全可以实现,核心是利用VOSK返回结果中的单词级时间戳数据——你已经调用了rec.SetWords(True),VOSK会在识别结果里包含每个单词的起始和结束时间,只是现有代码只提取了纯文本,忽略了时间相关字段。另外需要注意:分段处理音频时,每个片段的单词时间是相对于该片段的起始时间,所以要加上片段的全局起始时间偏移。

你的现有代码:

def voice_recognition(filename):
    model = Model(model_name="vosk-model-fa-0.5")
    rec = KaldiRecognizer(model, FRAME_RATE)
    rec.SetWords(True)

    mp3 = AudioSegment.from_mp3(filename)
    mp3 = mp3.set_channels(CHANNELS)
    mp3 = mp3.set_frame_rate(FRAME_RATE)

    step = 45000
    transcript = ""
    for i in range(0, len(mp3), step):
        segment = mp3[i:i+step]
        rec.AcceptWaveform(segment.raw_data)
        result = rec.Result()
        text = json.loads(result)["text"]
        transcript += text
    return transcript

修改后的实现代码

import json
from vosk import Model, KaldiRecognizer
from pydub import AudioSegment

FRAME_RATE = 16000  # 需与vosk-model-fa-0.5模型匹配,该模型为16kHz采样率
CHANNELS = 1

def voice_recognition_with_timestamps(filename):
    model = Model(model_name="vosk-model-fa-0.5")
    rec = KaldiRecognizer(model, FRAME_RATE)
    rec.SetWords(True)

    mp3 = AudioSegment.from_mp3(filename)
    mp3 = mp3.set_channels(CHANNELS)
    mp3 = mp3.set_frame_rate(FRAME_RATE)

    step = 45000  # 按45秒分段处理音频
    word_timestamps = []
    
    for i in range(0, len(mp3), step):
        # 将片段起始毫秒数转换为全局秒级时间
        segment_start_time = i / 1000.0
        segment = mp3[i:i+step]
        
        rec.AcceptWaveform(segment.raw_data)
        result = json.loads(rec.Result())
        
        # 提取单词级时间戳数据
        if "result" in result:
            for word_info in result["result"]:
                # 计算单词的全局起始/结束时间
                global_start = segment_start_time + word_info["start"]
                global_end = segment_start_time + word_info["end"]
                word = word_info["word"]
                word_timestamps.append((global_start, global_end, word))
    
    # 按需求格式输出
    print(f"{'time':<18} word")
    print("-" * 25)
    for start, end, word in word_timestamps:
        time_str = f"({start:.2f}, {end:.2f})"
        print(f"{time_str:<18} {word}")
    
    return word_timestamps

# 调用示例
voice_recognition_with_timestamps("file.mp3")

关键说明

  • rec.SetWords(True)是获取单词时间戳的必要前提,必须保留
  • 分段处理时,要将片段的起始毫秒数转换为秒,加到单词的相对时间上,得到全局时间
  • 从result["result"]数组中提取每个单词的start(起始时间)、end(结束时间)和word(单词内容)字段
  • 时间精度可通过:.2f调整,比如改成:.3f可以显示三位小数

运行后会输出你期望的格式:

time               word
-------------------------
(0.01, 0.20)       hi
(0.30, 0.40)       how
(0.40, 0.50)       are
(0.50, 0.60)       you

内容的提问来源于stack exchange,提问作者miladjurablu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 19:25:31