IBM Watson STT: Как использовать интерфейс Websocket с несколькими блоками? - PullRequest
0 голосов
/ 27 мая 2019

Я разработал приложение для распознавания потоковой речи в 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);
    }
}

Ответы [ 2 ]

0 голосов
/ 28 мая 2019

@ data_henrik правильный, поток неправильный, он должен быть: ... START FRAME >> двоичные данные >> двоичные данные >> двоичные данные >> ... >> STOP FRAME

отправлять сообщение {"action":"stop"} нужно только в том случае, если больше нет аудиоблоков для отправки

0 голосов
/ 27 мая 2019

IBM Watson Speech to Text имеет несколько API для передачи аудио и получения транскрибированного текста.Исходя из вашего описания, вы, похоже, используете интерфейс WebSocket .

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

У вас нет общего кода, но кажется, что вы запускаете и останавливаете запрос для каждого чанка.Остановитесь только после последнего фрагмента.

Я бы порекомендовал взглянуть на документ API, содержащий примеры на разных языках. Образец Node.js показывает, как зарегистрироваться для событий .Есть также примеры на GitHub, такие как WebSocket API с Python .И вот еще один, который показывает фрагмент .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...