Как исправить None Exception, повторяющиеся запросы! вопрос - PullRequest
0 голосов
/ 14 октября 2019

Я новичок в теме распознавания речи

Я работаю над проектом, в котором я могу найти несколько примеров использования бота Pepper в рабочей области. Играя с Pepper, мы выяснили некоторые проблемы с его способностью распознавания речи. Я обнаружил, что мы можем попытаться связать его с внешними движками для этого, и я выбрал DialogFlow из GCP. Кроме того, потому что я нашел некоторые интеграции с этим сервисом. Я использовал код из этого проекта

import traceback
from naoqi import qi


# [START dialogflow_detect_intent_streaming]
def detect_intent_stream(project_id, session_id, audio_file_path,
                         language_code,ip):

    """Returns the result of detect intent with streaming audio as input.
    Using the same `session_id` between requests allows continuation
    of the conversation."""
    import dialogflow_v2 as dialogflow

    session_client = dialogflow.SessionsClient()

    # Note: hard coding audio_encoding and sample_rate_hertz for simplicity.
    audio_encoding = dialogflow.enums.AudioEncoding.AUDIO_ENCODING_LINEAR_16
    sample_rate_hertz = 44100

    session_path = session_client.session_path(project_id, session_id)
    print('Session path: {}\n'.format(session_path))

    def request_generator(audio_config, audio_file_path):
        query_input = dialogflow.types.QueryInput(audio_config=audio_config)
        # The first request contains the configuration.
        yield dialogflow.types.StreamingDetectIntentRequest(
            session=session_path, query_input=query_input)
        # Here we are reading small chunks of audio data from a local
        # audio file.  In practice these chunks should come from
        # an audio input device.
        try:
            with open(audio_file_path, 'rb') as audio_file:
                while True:
                    chunk = audio_file.read(4096)
                    print(chunk)
                    if not chunk:
                        break
        except:
                traceback.print_exc()

                # The later requests contains audio data.

                yield dialogflow.types.StreamingDetectIntentRequest(input_audio=chunk)


    audio_config = dialogflow.types.InputAudioConfig(audio_encoding=audio_encoding, language_code=language_code, sample_rate_hertz=sample_rate_hertz)

    requests = request_generator(audio_config, audio_file_path)
    responses = session_client.streaming_detect_intent(requests)


    print('=' * 20)
    for response in responses:
        print('Intermediate transcript: "{}".'.format(response.recognition_result.transcript))

    # Note: The result from the last response is the final transcript along
    # with the detected content.
    query_result = response.query_result
    session = qi.Session()
    try:
        tts = session.service("ALTextToSpeech")
        tts.say(query_result.fulfillment_text)
    except:
        traceback.print_exc()
        raise Exception("session.connect failed.")
    finally:
        session.close()
    print('=' * 20)
    print('Query text: {}'.format(query_result.query_text))
    print('Detected intent: {} (confidence: {})\n'.format(
        query_result.intent.display_name,
        query_result.intent_detection_confidence))
    print('Fulfillment text: {}\n'.format(
        query_result.fulfillment_text))
# [END dialogflow_detect_intent_streaming]



РЕДАКТИРОВАНИЕ: (добавление кода pepper_recorder.py) Приведенный ниже код берет любой звук из Pepper и отправляет только с пиком желания в поток диалога detect_intent_stream

import StringIO
from Queue import Queue
from naoqi import ALModule, ALProxy
import numpy as np
import time
import logging
import uuid
import traceback



from detect_intent_stream import detect_intent_stream

LISTEN_RETRIES = 10
DIALOG_FLOW_GCP_PROJECT_ID = "XXXXXXXXXXXXXXXXXXXX"

class SoundProcessingModule(ALModule):
    def __init__( self, name, ip, stop_recognition):
        try:
            ALModule.__init__( self, name );
        except Exception as e:
            logging.error(str(e))
            pass
        print("connected")
        self.ip = ip
        self.BIND_PYTHON( name, "processRemote")
        self.ALAudioDevice = ALProxy("ALAudioDevice", self.ip, 9559)
        self.framesCount=0
        self.count = LISTEN_RETRIES
        self.recordingInProgress = False
        self.stopRecognition = stop_recognition
        self.uuid = uuid.uuid4()
        self.previous_sound_data = None

    def startProcessing(self):
        """init sound processing, set microphone and stream rate"""
        print("startProcessing")
        self.ALAudioDevice.setClientPreferences(self.getName(), 16000, 4, 0)
        self.ALAudioDevice.subscribe(self.getName())
        while not self.stopRecognition.is_set():
            time.sleep(1)

        self.ALAudioDevice.unsubscribe(self.getName())

    def processRemote(self, nbOfChannels, nbOfSamplesByChannel, timeStamp, inputBuffer):

        """audio stream callback method with simple silence detection"""
        self.framesCount = self.framesCount + 1
        sound_data_interlaced = np.fromstring(str(inputBuffer), dtype=np.int16)
        sound_data = np.reshape(sound_data_interlaced, (nbOfChannels, nbOfSamplesByChannel), 'F')
        peak_value = np.max(sound_data)
        # detect sound
        if peak_value > 10000:
            print("Peak:", peak_value)
            self.count = LISTEN_RETRIES
            if not self.recordingInProgress:
                self.startRecording(self.previous_sound_data)
        # if there is no sound for a few seconds we end the current recording and start audio processing
        if self.count <= 0 and self.recordingInProgress:
            self.stopRecording()
        # if recording is in progress we save the sound to an in-memory file
        if self.recordingInProgress:
            self.count -= 1
            self.previous_data = sound_data
            self.procssingQueue.put(sound_data[0].tostring())
            self.outfile.write(sound_data[0].tostring())



    def startRecording(self, previous_sound_data):
        """init a in memory file object and save the last raw sound buffer to it."""
        self.outfile = StringIO.StringIO()
        self.procssingQueue = Queue()
        self.recordingInProgress = True
        if not previous_sound_data is None:
            self.procssingQueue.put(previous_sound_data[0].tostring())
            self.outfile.write(previous_sound_data[0].tostring())


        print("start recording")

    def stopRecording(self):
        """saves the recording to memory"""
        print("stopped recording")
        self.previous_sound_data = None
        self.outfile.seek(0)
        try:
            detect_intent_stream(DIALOG_FLOW_GCP_PROJECT_ID, self.uuid,
                                 self.outfile, "en-US", self.ip)
        except:
            traceback.print_exc()
        self.recordingInProgress = False

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

('Peak:', 14023)

начать запись

остановил запись

Путь сеанса: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX *

===================================

И затем ошибка ...

Трассировка (последний последний вызов):

>   File
> "C:\Users\marwloda\PycharmProjects\Pepper\scripts\pepper_recorder.py",
> line 83, in stopRecording    self.outfile, "en-US", self.ip)   File
> "C:\Users\marwloda\PycharmProjects\Pepper\scripts\detect_intent_stream.py",
> line 76, in detect_intent_stream    for response in responses:   File
> "C:\Users\marwloda\PycharmProjects\Pepper\venv\lib\site-packages\google\api_core\grpc_helpers.py",
> line 81, in next
>     six.raise_from(exceptions.from_grpc_error(exc), exc)   File "C:\Users\marwloda\PycharmProjects\Pepper\venv\lib\site-packages\six.py",
> line 737, in raise_from
>     raise value Unknown: None Exception iterating requests!

Если как аудиофайл, записанный с робота, был пустым. Но я сделал несколько распечаток речевых данных и создал некоторую необработанную нечитаемую строку

Чтобы доказать, что у меня есть какое-то соединение с API - когда я открываю консоль API и службы GCP, я вижу это представление

Что может вызвать эту ошибку? Где я должен искать причины?

Ответы [ 2 ]

0 голосов
/ 17 октября 2019

Итак, очевидно, вы передаете StringIO в detect_intent_stream как audio_file_path, где:

with open(audio_file_path, 'rb') as audio_file:

вы пытаетесь открыть StringIO как файл

Но:

Экземпляр StringIO уже является открытым файлом. Команда open, с другой стороны, принимает только имена файлов, чтобы вернуть открытый файл. Экземпляр StringIO не подходит в качестве имени файла. ссылка

Так что функция request_generator в detect_intent_stream должна выглядеть следующим образом:

def request_generator(audio_config, audio_file_path):
        query_input = dialogflow.types.QueryInput(audio_config=audio_config)        
        yield dialogflow.types.StreamingDetectIntentRequest(
            session=session_path, query_input=query_input)        
        while True:
            chunk = audio_file_path.read(4096)
            if not chunk:
                break
            yield dialogflow.types.StreamingDetectIntentRequest(
            input_audio=chunk)
0 голосов
/ 15 октября 2019

Привет! Возможно, проблема связана с вашим аудиофайлом или сетевым подключением. Вы пытались отправить простой текст или предварительно записанный WAV-файл в качестве входных данных для диалогового потока?

Этот скрипт хорошо работает на моем перце: (мой WAV-файл - Mono, 44100Hz, 32Bit)

import os
import time
import sys
import uuid
import google

def printResponse(response):
    print('=' * 20)
    print('Query text: {}'.format(response.query_result.query_text.encode('utf-8')))
    print('Detected intent: {} (confidence: {})'.format(
        response.query_result.intent.display_name.encode('utf-8'),
        response.query_result.intent_detection_confidence))
    print('Fulfillment text: {}'.format(
        response.query_result.fulfillment_text.encode('utf-8')))


def detect_intent_audio(project_id, session_id, audio_file_path,
                        language_code, sample_rate_hertz):

    import dialogflow_v2 as dialogflow

    session_client = dialogflow.SessionsClient()

    # Note: hard coding audio_encoding and sample_rate_hertz for simplicity.
    audio_encoding = dialogflow.enums.AudioEncoding.AUDIO_ENCODING_LINEAR_16

    session = session_client.session_path(project_id, session_id)

    with open(audio_file_path, 'rb') as audio_file:
        input_audio = audio_file.read()

    audio_config = dialogflow.types.InputAudioConfig(
        audio_encoding=audio_encoding, language_code=language_code,
        sample_rate_hertz=sample_rate_hertz)
    query_input = dialogflow.types.QueryInput(audio_config=audio_config)

    response = session_client.detect_intent(
        session=session, query_input=query_input,
        input_audio=input_audio)

    printResponse(response)

def detect_intent_stream(project_id, session_id, audio_file_path,
                         language_code, sample_rate_hertz):

    import dialogflow_v2 as dialogflow
    session_client = dialogflow.SessionsClient()

    # Note: hard coding audio_encoding and sample_rate_hertz for simplicity.
    audio_encoding = dialogflow.enums.AudioEncoding.AUDIO_ENCODING_LINEAR_16

    session_path = session_client.session_path(project_id, session_id)

    def request_generator(audio_config, audio_file_path):
        query_input = dialogflow.types.QueryInput(audio_config=audio_config)

        # The first request contains the configuration.
        yield dialogflow.types.StreamingDetectIntentRequest(
            session=session_path, query_input=query_input)

        # Here we are reading small chunks of audio data from a local
        # audio file.  In practice these chunks should come from
        # an audio input device.
        with open(audio_file_path, 'rb') as audio_file:
            while True:

                chunk = audio_file.read(4096)

                if not chunk:
                    break
                # The later requests contains audio data.
                yield dialogflow.types.StreamingDetectIntentRequest(
                    input_audio=chunk)

    audio_config = dialogflow.types.InputAudioConfig(
        audio_encoding=audio_encoding, language_code=language_code,
        sample_rate_hertz=sample_rate_hertz)

    requests = request_generator(audio_config, audio_file_path)
    responses = session_client.streaming_detect_intent(requests)

    print('=' * 20)
    for response in responses:
        print('Intermediate transcript: "{}".'.format(
                response.recognition_result.transcript.encode('utf-8')))

    # Note: The result from the last response is the final transcript along
    # with the detected content.

    printResponse(response)

def detect_intent_texts(project_id, session_id, texts, language_code):

    import dialogflow_v2 as dialogflow
    session_client = dialogflow.SessionsClient()

    session = session_client.session_path(project_id, session_id)

    for text in texts:
        text_input = dialogflow.types.TextInput(
            text=text, language_code=language_code)

        query_input = dialogflow.types.QueryInput(text=text_input)

        response = session_client.detect_intent(
            session=session, query_input=query_input)

        printResponse(response)


project_id = 'my_project_id'
session_id = str(uuid.uuid4())
language_code = 'de'
os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = os.path.join('/home/me/', 'xyz.json')
wav_path = os.path.join('/home/me/', 'audio.wav')

try:
    print ("detect_intent_texts:")
    detect_intent_texts(project_id, session_id, ["Hallo"], language_code)
    print('=' * 20)   

    print ("detect_intent_audio:")
    detect_intent_audio(project_id, session_id, wav_path, language_code, 44100)
    print('=' * 20)

    print ("detect_intent_stream:")
    detect_intent_stream(project_id, session_id, wav_path, language_code, 44100)
    print('=' * 20)
except google.api_core.exceptions.ServiceUnavailable:
        print("503 Connect Failed")
...