Я разработал приложение для распознавания потоковой речи в c ++ с использованием другого API и API-интерфейса IBM Watson Speech to Text.
В обеих этих программах я использую один и тот же файл, который содержит этот звук
несколько торнадо приземляются, когда в воскресенье по Колорадо прокатилась линия сильных гроз
Этот файл имеет размер 641 680 байт , и я отправляю 100 000 байт (макс.) кусков за раз на серверы Speech to text.
Теперь с другим API я могу распознать все как единое целое. С API IBM Watson я не смог. Вот что я сделал:
- Подключение к веб-серверу IBM Watson (API для преобразования речи в текст)
- Отправить начальный кадр
{"action":"start","content-type":"audio/mulaw;rate=8000"}
- Отправка двоичного файла 100 000 байт
- Отправить стоп-кадр
{"action":"stop"}
- ... Повторить двоичный файл и остановиться до последнего байта.
IBM Watson Speech API может распознавать фрагменты только по отдельности
например
несколько торнадо приземляются
линия сильного грома
пронесся через Колорадо
Воскресенье
Похоже, что это вывод отдельных фрагментов и слов, находящихся между разделением на фрагменты (например, здесь "гроза" частично присутствует в конце фрагмента и частично в начале следующего фрагмента ) , таким образом, неправильно распознаются или отбрасываются.
Что я делаю не так?
РЕДАКТИРОВАТЬ (я использую C ++ с библиотекой Boost для интерфейса веб-сокета)
//Do the websocket handshake
void IbmWebsocketSession::on_ssl_handshake(beast::error_code ec) {
auto mToken = mSttServiceObject->GetToken(); // Get the authentication token
//Complete the websocket handshake and call back the "send_start" function
mWebSocket.async_handshake_ex(mHost, mUrlEndpoint, [mToken](request_type& reqHead) {reqHead.insert(http::field::authorization,mToken);},
bind(&IbmWebsocketSession::send_start, shared_from_this(), placeholders::_1));
}
//Sent the start frame
void IbmWebsocketSession::send_start(beast::error_code ec) {
//Send the START_FRAME and call back the "read_resp" function to receive the "state: listening" message
mWebSocket.async_write(net::buffer(START_FRAME),
bind(&IbmWebsocketSession::read_resp, shared_from_this(), placeholders::_1, placeholders::_2));
}
//Sent the binary data
void IbmWebsocketSession::send_binary(beast::error_code ec) {
streamsize bytes_read = mFilestream.rdbuf()->sgetn(&chunk[0], chunk.size()); //gets the binary data chunks from a file (which is being written at run time
// Send binary data
if (bytes_read > mcMinsize) { //Minimum size defined by IBM is 100 bytes.
// If chunk size is greater than 100 bytes, then send the data and then callback "send_stop" function
mWebSocket.binary(true);
/**********************************************************************
* Wait a second before writing the next chunk.
**********************************************************************/
this_thread::sleep_for(chrono::seconds(1));
mWebSocket.async_write(net::buffer(&chunk[0], bytes_read),
bind(&IbmWebsocketSession::send_stop, shared_from_this(), placeholders::_1));
} else { //If chunk size is less than 100 bytes, then DO NOT send the data only call "send_stop" function
shared_from_this()->send_stop(ec);
}
}
void IbmWebsocketSession::send_stop(beast::error_code ec) {
mWebSocket.binary(false);
/*****************************************************************
* Send the Stop message
*****************************************************************/
mWebSocket.async_write(net::buffer(mTextStop),
bind(&IbmWebsocketSession::read_resp, shared_from_this(), placeholders::_1, placeholders::_2));
}
void IbmWebsocketSession::read_resp(beast::error_code ec, size_t bytes_transferred) {
boost::ignore_unused(bytes_transferred);
if(mWebSocket.is_open())
{
// Read the websocket response and call back the "display_buffer" function
mWebSocket.async_read(mBuffer, bind(&IbmWebsocketSession::display_buffer, shared_from_this(),placeholders::_1));
}
else
cerr << "Error: " << e->what() << endl;
}
void IbmWebsocketSession::display_buffer(beast::error_code ec) {
/*****************************************************************
* Get the buffer into stringstream
*****************************************************************/
msWebsocketResponse << beast::buffers(mBuffer.data());
mResponseTranscriptIBM = ParseTranscript(); //Parse the response transcript
mBuffer.consume(mBuffer.size()); //Clear the websocket buffer
if ("Listening" == mResponseTranscriptIBM && true != mSttServiceObject->IsGstFileWriteDone()) { // IsGstFileWriteDone -> checks if the user has stopped speaking
shared_from_this()->send_binary(ec);
} else {
shared_from_this()->close_websocket(ec, 0);
}
}