Dialogflow никогда не заполняет queryResult, когда передается поток UDP (в котором есть микрофонный вход) - PullRequest
0 голосов
/ 25 января 2019

Случай высокого уровня 1. У меня есть приложение для Android, которое передает данные с микрофона на сервер.2. Сервер получает этот поток и перенаправляет его в Dialogflow. 3. Я вижу результаты (промежуточные транскрипции текста), но окончательный queryResult всегда остается нулевым.

Код Android Я включил этот фрагмент кода, чтобы показать, что код Android использует те же параметры для потока, что и сервер.На самом деле у меня также есть другой сервер, который получает строку UDP и перенаправляет ее в другой сервис.Это работает.Поэтому я ожидаю, что код Android в этом отношении будет в порядке.

public byte[] buffer;
public static DatagramSocket socket;
private int port = 3000;
private Thread streamThread;

AudioRecord recorder;

private int sampleRate = 16000 ; // 44100 for music
private int channelConfig = AudioFormat.CHANNEL_IN_MONO;
private int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
int minBufSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat);

...

socket = new DatagramSocket();

byte[] buffer = new byte[minBufSize];

DatagramPacket packet;

final InetAddress destination = InetAddress.getByName("192.168.1.105");
recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,sampleRate,channelConfig,audioFormat,minBufSize*10);
recorder.startRecording();

while(status == true) {
  //reading data from MIC into buffer
  minBufSize = recorder.read(buffer, 0, buffer.length);

  //putting buffer in the packet
  packet = new DatagramPacket (buffer,buffer.length,destination,port);

  socket.send(packet);
}

Код сервера Код сервера выглядит следующим образом:

var udp = require('datagram-stream');
const through2 = require('through2');
const pump = require('pump');
const randomstring = require('randomstring');

// Imports the Dialogflow library
const dialogflow = require('dialogflow').v2beta1;
const projectId = "chatbot-sm-prototype-v1"
const sessionId = randomstring.generate()
// Instantiates a session client
const sessionClient = new dialogflow.SessionsClient();

// The encoding of the audio file, e.g. 'AUDIO_ENCODING_LINEAR_16'
const encoding = 'AUDIO_ENCODING_LINEAR_16';
// The sample rate of the audio file in hertz, e.g. 16000
const sampleRateHertz = 16000;
// The BCP-47 language code to use, e.g. 'en-US' or 'nl-NL'
const languageCode = 'en-US';
const sessionPath = sessionClient.sessionPath(projectId, sessionId);

const initialStreamRequest = {
  session: sessionPath,
  queryParams: {
    session: sessionClient.sessionPath(projectId, sessionId),
  },
  queryInput: {
    audioConfig: {
      audioEncoding: encoding,
      sampleRateHertz: sampleRateHertz,
      languageCode: languageCode,
    },
    singleUtterance: true
  }
};

var stream = udp({
  address     : '0.0.0.0',  //address to bind to
  bindingPort : 3000      //udp port to listen on. Default: port
});

// Create a stream for the streaming request.
const detectStream = sessionClient
.streamingDetectIntent()
.on('error', err => {
  console.error("DF.error=", err)
})
.on('data', data => {
  console.log('DF.data=', data)
  if (data.recognitionResult) {
    // I am getting intermediate results here just fine
    // sometimes the isFinal field is set to true as well.
    console.log(`Intermediate transcript: ${data.recognitionResult.transcript}`);
  } else {
    // however, queryResult is always null
    console.log('data.queryResult=', data.queryResult)
  }
})
.on('status', status => {
  console.log("DF.status = ", status);
})
.on('end', endmsg => {
  console.log("DF.end =", endmsg);
});

// Write the initial stream request to config for audio input.
detectStream.write(initialStreamRequest);

// pass the UDP input stream into the Dialogflow detector
pump(
   stream,
   // Format the audio stream into the request format.
   through2.obj((obj, _, next) => {
       next(null, {inputAudio: obj});
   }),
   detectStream
);

Вывод Проблема в том, что я никогда не получаю вывод для data.queryResult.Это поле всегда пустое.I do см. Вывод для Intermediate transcript.И то, и другое можно увидеть ниже.

Обратите внимание, что когда я читаю из потока файлов вместо потока UDP, код, приведенный ниже, работает.

Слово "goedemorgen" известно в диалоге как намерение.

DF.data= { alternativeQueryResults: [],
  responseId: '',
  recognitionResult: 
   { messageType: 'TRANSCRIPT',
     transcript: 'goede',
     isFinal: false,
     confidence: 0 },
  queryResult: null,
  webhookStatus: null,
  outputAudio: <Buffer >,
  outputAudioConfig: null }
Intermediate transcript: goede
DF.data= { alternativeQueryResults: [],
  responseId: '',
  recognitionResult: 
   { messageType: 'TRANSCRIPT',
     transcript: 'goedemorgen',
     isFinal: false,
     confidence: 0 },
  queryResult: null,
  webhookStatus: null,
  outputAudio: <Buffer >,
  outputAudioConfig: null }
Intermediate transcript: goedemorgen
DF.data= { alternativeQueryResults: [],
  responseId: '',
  recognitionResult: 
   { messageType: 'TRANSCRIPT',
     transcript: 'goedemorgen',
     isFinal: false,
     confidence: 0 },
  queryResult: null,
  webhookStatus: null,
  outputAudio: <Buffer >,
  outputAudioConfig: null }
Intermediate transcript: goedemorgen
DF.data= { alternativeQueryResults: [],
  responseId: '',
  recognitionResult: 
   { messageType: 'TRANSCRIPT',
     transcript: 'goedemorgen',
     isFinal: true,
     confidence: 0.9556559324264526 },
  queryResult: null,
  webhookStatus: null,
  outputAudio: <Buffer >,
  outputAudioConfig: null }
Intermediate transcript: goedemorgen

Любые идеи Очень ценятся!

...