Как добавить данные websocket в watson речь в текстовую очередь - PullRequest
2 голосов
/ 09 апреля 2019

Я хочу иметь непрерывную двустороннюю транскрипцию звука, записанного в браузере, который отправляется через бэкэнд Python Flask в Watson Speech to Text. Я могу успешно отправить аудио на сервер и отправить результаты в браузер. Кроме того, код выдает сообщения, указывающие, что он успешно подключается к речи IBM Watson to text api. Однако я не могу добавить аудиоданные с сервера в очередь audio_source, необходимую для watson python sdk. То есть транскрипция не происходит.

Я основываю свой подход на речи к тексту, используя пример микрофона, найденный здесь: https://github.com/watson-developer-cloud/python-sdk/blob/master/examples/microphone-speech-to-text.py

Я использую подход, показанный здесь для соединения через веб-сокет Flask: https://github.com/diewland/Flask-SocketIO-Audio

Это просто пример для контекста:

from ibm_watson import SpeechToTextV1
from ibm_watson.websocket import RecognizeCallback, AudioSource
from threading import Thread, Lock
from Queue import Queue, Full

CHUNK = 1024
BUF_MAX_SIZE = CHUNK * 10
# Buffer to store audio
q = Queue(maxsize=int(round(BUF_MAX_SIZE / CHUNK)))
audio_source = AudioSource(q, True, True)

class MyRecognizeCallback(RecognizeCallback):
    def __init__(self):
        RecognizeCallback.__init__(self)

    def on_transcription(self, transcript):
        print('=======================')
        print(transcript)
        print('=======================')

    def on_connected(self):
        print('Connection was successful')

    def on_error(self, error):
        print('Error received: {}'.format(error))

    def on_inactivity_timeout(self, error):
        print('Inactivity timeout: {}'.format(error))

    def on_listening(self):
        print('Service is listening')

    def on_hypothesis(self, hypothesis):
        print(hypothesis)

    def on_data(self, data):
        print('=======================')
        print(data)
        print('=======================')

    def on_close(self):
        print("Connection closed")


def recognize_using_weboscket(*args):
    mycallback = MyRecognizeCallback()
    speech_to_text.recognize_using_websocket(audio=audio_source,
                                             content_type='audio/l16; rate=44100',
                                             recognize_callback=mycallback,
                                             interim_results=True)

Я думаю, что проблема может быть в том, где я запускаю ветку распознавания_using_websocket (ниже). Он подключается и дает мне сообщения, которые он слушает. Я пробовал несколько разных способов, чтобы запустить эту ветку признать_using_websockets, но это единственный, который 1), кажется, подключается к Уотсону, 2) не блокирует код в другом месте, и 3) по-прежнему выводит правильный звук запись в конце.

@socketio.on('connect', namespace='/transcription')
def test_connect():
    global thread
    with thread_lock:
       if thread is None:
            thread = socketio.start_background_task(target=recognize_using_weboscket)

    session['audio'] = []

    emit('my_response', {'data': 'Connected', 'count': 0})

Однако очередь (q) никогда не меняется, когда я добавляю в нее больше данных, используя q.put (data) (ниже). Я думаю, что контекст audio_source / queue может быть недоступен так, как я думаю.

@socketio.on('audio', namespace='/transcription')
def handle_my_custom_event(audio):
        values = OrderedDict(sorted(audio.items(), key=lambda t:int(t[0]))).values()
    session['audio'] += values
    q.put(list(values))
    print('queue size:', q.qsize())
    print(list(values)[-1])

Watson STT, использующий микрофон, использует обратный вызов pyaudio для добавления новых данных в очередь, который я заменяю обратным вызовом websocket выше, чтобы попытаться имитировать это поведение.

# define callback for pyaudio to store the recording in queue
def pyaudio_callback(in_data, frame_count, time_info, status):
    try:
        q.put(in_data)
    except Full:
        pass # discard
    return (None, pyaudio.paContinue)

Размер очереди никогда не изменяется, даже если полученные значения аудио изменяются надлежащим образом (приведенный выше пример Flask-SocketIO-Audio включает в себя запись файла, и даже с этим добавленным кодом выходной файл wav является правильным). Кажется, я неправильно изменяю очередь и / или источник звука для отправки данных в watson.

Я также совершенно не уверен относительно формата данных, которые отправляет браузер. Перед записью данных в волновой файл выполняется некоторая обработка, и пример STT-микрофона, похоже, предполагает, что это, вероятно, audio / l16, но я не уверен, нужно ли мне обрабатывать данные дальше, прежде чем отправлять их в очередь.

Спасибо

...