Потоковое аудио в Dialogflow с чанками из браузера - PullRequest
1 голос
/ 15 марта 2019

Мы проводим некоторые эксперименты с Dialogflow и на данный момент мы полностью остановились. Мы пытаемся настроить клиент браузера, который передает потоки аудио в чанках на Dialogflow через версию узла v2beta1 пакета dialogflow npm. Мы последовали примеру, чтобы запустить его, и он прекрасно работает, когда мы используем сервер узлов для захвата звука с помощью дополнительного программного обеспечения (sox), но мы хотим транслировать из браузера. Итак, мы создали небольшой фрагмент кода, который забирает MediaStream с микрофона.

Когда событие данных запускается триггером, мы получаем чанк (массив буферов), который мы в чанках передаем на наш сервер узлов.

На сервере мы следовали этому примеру: https://cloud.google.com/dialogflow-enterprise/docs/detect-intent-stream#detect-intent-text-nodejs. Единственное, что мы отличаем, - это вместо того, чтобы использовать насос для цепочки потоков, мы просто записываем свои чанки в sessionClient.

streamingDetectIntent().write({ inputAudio: [chunk] })

Во время экспериментов мы получили несколько ошибок, которые мы решили. Но в этот момент мы передаем наши куски и получаем пустые ответы во время и в конце.

Является ли это допустимым способом передачи звука в диалоговый поток, или нам действительно нужно настроить поток? Мы не хотим использовать сервер узла в качестве записи, это должен быть браузер. У нас будет полный контроль.

Клиент

import getUserMedia from 'get-user-media-promise';
import MicrophoneStream from 'microphone-stream';

export const startVoiceStream = () => {
  const microphoneStream = new MicrophoneStream();

    getUserMedia({ video: false, audio: true })
    .then(function(micStream) {

      microphoneStream.setStream(micStream);

      socket.emit('startMicStream');

      state.streamingMic = true;

      setTimeout(() => {
        // Just closing the stream on a timer for now
        socket.emit('endMicStream');
      }, 5000);
    })
    .catch(function(error) {
      console.log(error);
    });

    microphoneStream.on('data', function(chunk) {
    if (state.streamingMic) {
      socket.emit('micStreamData', chunk);
    }
  });
};

Серверный код намного длиннее, поэтому я думаю, что пощадлю детали, но это основные части.

const initialStreamRequest = {
    session: sessions.sessionPath,
    queryParams: {
        session: sessions.sessionPath, //TODO: try to delete
    },
    queryInput: {
        audioConfig: {
            audioEncoding: 'AUDIO_ENCODING_LINEAR_16',
            sampleRateHertz: '16000',
            languageCode: 'en-US',
        },
        singleUtterance: false
    },
};

const startRecognitionStream = socketClient => {
    streamIntent = sessions.sessionClient
      .streamingDetectIntent()
      .on('error', error => {
        console.error({ error });
        socketClient.emit('streamError', error);
      })
      .on('data', data => {
        socketClient.emit('debug', { message: 'STREAM "ON DATA"', data });
        if (data.recognitionResult) {
          socketClient.emit(
            'playerTranscript',
            data.recognitionResult.transcript,
          );
          console.log(
            `#Intermediate transcript : ${data.recognitionResult.transcript}`,
          );
        } else {
          socketClient.emit('streamAudioResponse', data);
        }
      });
    streamIntent.write(initialStreamRequest);
  };

socket.on('micStreamData', data => {
    if (streamIntent !== null) {
      stop = true;
      streamIntent.write({ inputAudio: data });
    }
  });
...