воск на python: получить расположение транскрибированного текста в аудиофайле

#python #speech-recognition #speech-to-text #vosk

Вопрос:

Использование файла, очень похожего на test_ffmpeg.py в репозитории Vosk я изучаю, какую текстовую информацию я могу получить из аудиофайла.

Вот код всего сценария, который я использую.

 #!/usr/bin/env python3

from vosk import Model, KaldiRecognizer, SetLogLevel
import sys
import os
import wave
import subprocess
import json

SetLogLevel(0)

if not os.path.exists("model"):
    print ("Please download the model from https://alphacephei.com/vosk/models and unpack as 'model' in the current folder.")
    exit (1)

sample_rate=16000
model = Model("model")
rec = KaldiRecognizer(model, sample_rate)

process = subprocess.Popen(['ffmpeg', '-loglevel', 'quiet', '-i',
                            sys.argv[1],
                            '-ar', str(sample_rate) , '-ac', '1', '-f', 's16le', '-'],
                            stdout=subprocess.PIPE)

file = open(sys.argv[1] ".txt","w ")

while True:
    data = process.stdout.read(4000)
    if len(data) == 0:
        break
    if rec.AcceptWaveform(data):
        file.write(json.loads(rec.Result())['text'] "nn")
        #print(rec.Result())
    #else:
        #print(rec.PartialResult())
#print(json.loads(rec.Result())['text'])
file.write(json.loads(rec.Result())['text'])
file.close()
 

Этот пример хорошо работает, однако единственное, что я могу получить из rec.PartialResult() и rec.Result (), — это словарь строк с результатом. Есть ли способ запросить распознаватель каталогов о времени, когда отдельные слова были найдены в аудиофайле?

Когда я печатаю это, я уже думаю, что уточнение результата и обнаружение изменений в частичном результате по сравнению с текущими образцами даст мне то, что я хочу, но я вставляю это здесь на случай, если это уже реализовано.

Ответ №1:

После некоторого тестирования стало довольно ясно, что вывод ffmpeg казался достаточно стабильным по сравнению с определенной частотой дискретизации (16000), а считанные байты 4000 оказались 8-мя долями секунды. Я создал счетчик в цикле while и разделил его на константу в зависимости от частоты дискретизации. Если вы измените параметры на ffmpeg, это, вероятно, сбросит это.

Я использовал сравнение строк каменного века, чтобы печатать только при изменении частичного результата и содержать только добавленные новые символы.

 counter = 0
countinc = 2000/sample_rate
lastPR = ""
thisPR = ""
while True:
    data = process.stdout.read(4000)
    counter  = 1
    if len(data) == 0:
        break
    rec.AcceptWaveform(data)
    thisPR = json.loads(rec.PartialResult())['partial']
    if lastPR != thisPR:
        print(counter*countinc,thisPR[len(lastPR):len(thisPR)])
        lastPR = thisPR