IBM Cloud Docs
A interface do WebSocket

A interface do WebSocket

A interface do WebSocket do serviço IBM Watson® Speech to Text é a maneira mais natural para um cliente interagir com o serviço. Para usar a interface do WebSocket para reconhecimento de voz, use primeiro o método /v1/recognize para estabelecer uma conexão persistente com o serviço. Depois envie mensagens binárias e de texto por conexão para iniciar e gerenciar solicitações de reconhecimento.

Por causa de suas vantagens, os WebSockets são o mecanismo preferencial para reconhecimento de voz. Para obter mais informações, consulte Vantagens da interface do WebSocket. Para obter mais informações sobre a interface WebSocket e seus parâmetros, consulte a referência da API e do SDK.

Gerenciando uma conexão WebSocket

O ciclo de solicitação e resposta de reconhecimento do WebSocket tem as etapas a seguir:

  1. Abrir uma conexão
  2. Iniciar uma solicitação de reconhecimento
  3. Enviar áudio e receber os resultados do reconhecimento
  4. Terminar uma solicitação de reconhecimento
  5. Enviar solicitações adicionais e modificar parâmetros de solicitação
  6. Manter uma conexão ativa
  7. Fechar uma conexão

Quando o cliente envia dados para o serviço, ele deve transmitir todas as mensagens JSON como mensagens de texto e todos os dados de áudio como mensagens binárias.

Os fragmentos de código de exemplo a seguir são gravados em JavaScript e são baseados na API do HTML5 WebSocket. Para obter mais informações sobre o protocolo WebSocket, consulte o Request for Comment(RFC)6455 da Internet Engineering Task Force (IETF).

Abrir uma conexão

O serviço Speech to Text usa o protocolo WebSocket Secure (WSS) para tornar o método /v1/recognize disponível no terminal a seguir:

wss://api.{location}.speech-to-text.watson.cloud.ibm.com/instances/{instance_id}/v1/recognize

em que {location} indica onde seu aplicativo está hospedado:

  • us-south para Dallas
  • us-east para Washington, D.C.
  • eu-de para Frankfurt
  • au-syd para Sydney
  • jp-tok para Tóquio
  • eu-gb para Londres
  • kr-seo para Seul

E {instance_id} é o identificador exclusivo da instância de serviço.

Os exemplos na documentação abreviam wss://api.{location}.speech-to-text.watson.cloud.ibm.com/instances/{instance_id} para {ws_url}. Todos os exemplos de WebSocket chamam o método como {ws_url}/v1/recognize.

Um cliente WebSocket chama o método /v1/recognize com os parâmetros de consulta a seguir para estabelecer uma conexão autenticada com o serviço. É possível especificar esses aspectos da solicitação apenas como parâmetros de consulta da URL do WebSocket.

access_token (sequência necessária)

Passe um token de acesso válido para estabelecer uma conexão autenticada com o serviço. Deve-se estabelecer a conexão antes que o token de acesso expire. Você passa um token de acesso apenas para estabelecer uma conexão autenticada. Depois de estabelecer uma conexão, é possível mantê-la ativa indefinidamente. Você permanece autenticado pelo tempo que mantém a conexão aberta. Não é necessário atualizar o token de acesso para uma conexão ativa que dure além do prazo de expiração do token. Uma vez estabelecida uma conexão, ela pode permanecer ativa mesmo depois que o token ou suas credenciais forem excluídos.

  • IBM Cloud Passe um token de acesso Identity and Access Management (IAM) para se autenticar no serviço. Você transmite um token de acesso do IAM em vez de uma chave de API com a chamada. Para obter mais informações, consulte Autenticando para IBM Cloud.
  • IBM Cloud Pak for DataIBM Software Hub Passe um token de acesso como você faria com o cabeçalho Authorization de uma solicitação HTTP. Para obter mais informações, consulte Autenticação em IBM Cloud Pak for Data.
model (sequência opcional)

Especifica o modelo de idioma a ser usado para transcrição. Se você não especificar um modelo, o serviço usará en-US_BroadbandModel por padrão. Para obter mais informações, consulte

language_customization_id (sequência opcional)

Especifica o Identificador Exclusivo Global (GUID) de um modelo de idioma customizado que deve ser usado para todas as solicitações que são enviadas por meio da conexão. O modelo base do modelo de idioma customizado deve corresponder ao valor do parâmetro model. Se incluir um ID de modelo de idioma customizado, você deverá fazer a solicitação com credenciais para a instância do serviço que possui o modelo customizado. Por padrão, nenhum modelo de idioma customizado é usado. Para obter mais informações, consulte Usando um modelo de idioma customizado para reconhecimento de voz.

acoustic_customization_id (sequência opcional)

Especifica o GUID de um modelo acústico customizado que deve ser usado para todas as solicitações enviadas por conexão. O modelo base do modelo acústico customizado deve corresponder ao valor do parâmetro model. Se incluir um ID de modelo acústico customizado, você deverá fazer a solicitação com credenciais para a instância do serviço que possui o modelo customizado. Por padrão, nenhum modelo acústico customizado é usado. Para obter mais informações, consulte Usando um modelo acústico customizado para reconhecimento de voz.

base_model_version (sequência opcional)

Especifica a versão do model base que deve ser usada para todas as solicitações que são enviadas por meio da conexão. O parâmetro é destinado principalmente para o uso com modelos customizados que passaram por upgrade para um novo modelo base. O valor padrão depende de o parâmetro ser usado com ou sem um modelo customizado. Para obter mais informações, consulte Fazendo solicitações de reconhecimento de voz com modelos customizados atualizados.

x-watson-metadata (sequência opcional)

Associa um ID do cliente a todos os dados que são passados por meio da conexão. O parâmetro aceita o argumento customer_id={id}, em que id é uma sequência aleatória ou genérica que deve ser associada aos dados. Deve-se codificar a URL do argumento para o parâmetro, por exemplo, customer_id%3dmy_customer_ID. Por padrão, nenhum ID do cliente está associado aos dados. Para obter mais informações, consulte Segurança de informações.

x-watson-learning-opt-out (booleano opcional)

IBM Cloud Indica se o serviço registra solicitações e resultados que são enviados pela conexão. Para evitar que a IBM acesse seus dados para melhorias gerais de serviço, especifique true para o parâmetro. Para obter mais informações, consulte Criação de log de solicitação.

O fragmento do código JavaScript a seguir abre uma conexão com o serviço. A chamada para o método /v1/recognize passa os parâmetros de consulta access_token e model. O último para direcionar o serviço para usar o modelo de banda larga de espanhol. Após estabelecer a conexão, o cliente define os listeners de eventos (onOpen, onClose e assim por diante) para responder a eventos do serviço. O cliente pode usar a conexão para diversas solicitações de reconhecimento.

var access_token = '{access_token}';
var wsURI = '{ws_url}/v1/recognize'
  + '?access_token=' + access_token
  + '&model=es-ES_BroadbandModel';
var websocket = new WebSocket(wsURI);

websocket.onopen = function(evt) { onOpen(evt) };
websocket.onclose = function(evt) { onClose(evt) };
websocket.onmessage = function(evt) { onMessage(evt) };
websocket.onerror = function(evt) { onError(evt) };

O cliente pode abrir diversas conexões simultâneas do WebSocket com o serviço. O número de conexões simultâneas é limitado apenas pela capacidade do serviço, que geralmente não apresenta problemas para os usuários.

Iniciar uma solicitação de reconhecimento

Para iniciar uma solicitação de reconhecimento, o cliente envia uma mensagem de texto JSON para o serviço por meio da conexão estabelecida. O cliente deve enviar essa mensagem antes de enviar qualquer áudio para transcrição. A mensagem deve incluir o parâmetro action, mas geralmente pode omitir o parâmetro content-type:

action (sequência necessária)
Especifica a ação a ser executada:
content-type (sequência opcional)
Identifica o formato (tipo MIME) dos dados de áudio para a solicitação. O parâmetro é necessário para os formatos audio/alaw, audio/basic, audio/l16 e audio/mulaw. Para obter mais informações, consulte Formatos de áudio.

A mensagem também pode incluir parâmetros opcionais para especificar outros aspectos de como a solicitação deve ser processada e as informações que devem ser retornadas. Esses parâmetros adicionais incluem o parâmetro interim_results, que está disponível apenas com a interface do WebSocket.

  • Para obter mais informações sobre todos os recursos de reconhecimento de voz, consulte o Resumo do parâmetro.
  • Para obter mais informações sobre o parâmetro interim_results, consulte Resultados provisório.

O fragmento do código JavaScript a seguir envia parâmetros de inicialização para a solicitação de reconhecimento por meio da conexão WebSocket. As chamadas são incluídas na função onOpen do cliente para assegurar que elas sejam enviadas somente depois que a conexão for estabelecida.

function onOpen(evt) {
  var message = {
    action: 'start',
    content-type: 'audio/l16;rate=22050'
  };
  websocket.send(JSON.stringify(message));
}

Se receber a solicitação com sucesso, o serviço retornará a mensagem de texto a seguir para indicar que ela é listening. O estado listening indica que a instância de serviço está configurada (a mensagem JSON start era válida) e pronta para aceitar áudio para uma solicitação de reconhecimento.

{'state': 'listening'}

Se o cliente especificar um parâmetro de consulta ou um campo JSON inválido para a solicitação de reconhecimento, a resposta JSON do serviço incluirá um campo warnings. O campo descreve cada argumento inválido. A solicitação é bem-sucedida, apesar dos avisos.

Enviar áudio e receber os resultados do reconhecimento

Depois de enviar a mensagem inicial start, o cliente poderá começar a enviar dados de áudio para o serviço. O cliente não precisa esperar que o serviço responda à mensagem start com a mensagem listening. Quando ele começa a atender, o serviço processa qualquer áudio que foi enviado antes da mensagem listening.

O cliente deve enviar o áudio como dados binários. O cliente pode enviar no máximo 100 MB de dados de áudio por solicitação send. Ele deve enviar pelo menos 100 bytes de áudio para qualquer solicitação. O cliente pode enviar várias solicitações por uma única conexão de WebSocket. Para obter informações sobre o uso da compactação para maximizar a quantidade de áudio que pode ser passada para o serviço com uma solicitação, consulte Limites de dados e compactação.

A interface do WebSocket impõe um tamanho máximo do quadro de 4 MB. O cliente pode configurar o tamanho máximo do quadro para menos de 4 MB. Se não for prático configurar o tamanho do quadro, o cliente poderá configurar o tamanho máximo da mensagem para menos de 4 MB e enviar os dados de áudio como uma sequência de mensagens. Para obter mais informações sobre WebSocket frames, consulte IETF RFC 6455.

A forma como o serviço envia resultados de reconhecimento por uma conexão de WebSocket depende de o cliente solicitar ou não resultados provisórios. Para obter mais informações, consulte Como o serviço envia resultados de reconhecimento.

O fragmento do código JavaScript a seguir envia dados de áudio para o serviço como uma mensagem binária (blob):

websocket.send(blob);

O fragmento a seguir recebe hipóteses de reconhecimento que o serviço retorna de forma assíncrona. Os resultados são manipulados pela função onMessage do cliente.

function onMessage(evt) {
  console.log(evt.data);
}

Seu código deve estar preparado para manipular códigos de retorno de retorno do serviço. Para obter mais informações, consulte Códigos de retorno do WebSocket.

Terminar uma solicitação de reconhecimento

Ao terminar o envio dos dados de áudio para uma solicitação para o serviço, o cliente deve sinalizar o término da transmissão de áudio binário para o serviço de uma das maneiras a seguir:

  • Enviando uma mensagem de texto do JSON com o parâmetro action configurado para o valor stop:

    {action: 'stop'}
    
  • Enviando uma mensagem binária vazia, uma na qual o blob especificado está vazio:

    websocket.send(blob)
    

Se o cliente falhar para sinalizar que a transmissão está completa, a conexão poderá atingir o tempo limite sem o serviço enviar os resultados finais. Para receber resultados finais entre diversas solicitações de reconhecimento, o cliente deve sinalizar o final da transmissão para a solicitação anterior antes de enviar uma solicitação subsequente. Depois de retornar os resultados finais para a primeira solicitação, o serviço retornará outra mensagem {"state":"listening"} para o cliente. Essa mensagem indica que o serviço está pronto para receber outra solicitação.

Enviar solicitações adicionais e modificar parâmetros de solicitação

Enquanto a conexão do WebSocket permanecer ativa, o cliente poderá continuar a usar a conexão para enviar solicitações de reconhecimento adicionais com novo áudio. Por padrão, o serviço continua a usar os parâmetros que foram enviados com a mensagem start anterior para todas as solicitações subsequentes que são enviadas por meio da mesma conexão.

Para mudar os parâmetros para solicitações subsequentes, o cliente pode enviar outra mensagem start com os novos parâmetros depois de receber os resultados finais de reconhecimento e uma nova mensagem {"state":"listening"} do serviço. O cliente pode mudar qualquer parâmetro, exceto aqueles parâmetros especificados quando a conexão é aberta (model, language_customization_id e assim por diante).

O exemplo a seguir envia uma mensagem start com novos parâmetros para solicitações de reconhecimento subsequentes que são enviadas por meio da conexão. A mensagem especifica o mesmo content-type como o exemplo anterior, mas ela direciona o serviço para retornar as medidas de confiança e os registros de data e hora para as palavras da transcrição.

var message = {
  action: 'start',
  content-type: 'audio/l16;rate=22050',
  word_confidence: true,
  timestamps: true
};
websocket.send(JSON.stringify(message));

Manter uma conexão ativa

O serviço finalizará a sessão e fechará a conexão se ocorrer um tempo limite de inatividade ou de sessão:

  • Um tempo limite de inatividade ocorre se o áudio está sendo enviado pelo cliente, mas o serviço não detecta nenhuma fala. O tempo limite de inatividade é 30 segundos por padrão. É possível usar o parâmetro inactivity_timeout para especificar um valor diferente, incluindo -1 para configurar o tempo limite para infinito. Para obter mais informações, consulte Tempo limite de inatividade.
  • Um tempo limite da sessão ocorre se o serviço não recebe dados do cliente ou não envia resultados provisórios por 30 segundos. Não é possível mudar a duração desse tempo limite, mas é possível estender a sessão enviando ao serviço qualquer dado de áudio, incluindo apenas silêncio, antes que o tempo limite ocorra. Também deve-se configurar inactivity_timeout como -1. Você é cobrado pela duração de qualquer dado que envia para o serviço, incluindo o silêncio enviado para estender uma sessão. Para obter mais informações, consulte Tempo limite de sessão.

Os clientes e os servidores do WebSocket também podem trocar quadros de ping-pong para evitar tempos limites de leitura trocando pequenas quantidades de dados periodicamente. Muitos quadros do WebSocket trocam quadros de ping-pong, mas alguns não. Para determinar se a sua implementação usa quadros de ping-pong, verifique sua lista de recursos. Não é possível determinar ou gerenciar programaticamente quadros de ping-pong.

Se a sua pilha do WebSocket não implementar quadros de ping-pong e você estiver enviando arquivos de áudio longos, a sua conexão poderá atingir um tempo limite de leitura. Para evitar esses tempos limites, envie continuamente o áudio para o serviço ou solicite resultados temporários do serviço. Qualquer uma das abordagens pode assegurar que a falta de quadros de ping-pong não faça com que sua conexão seja fechada.

Para obter mais informações sobre quadros de ping-pong, consulte a Seção 5.5.2 Ping e a Seção 5.5.3 Pong da IETF RFC 6455.

Fechar uma conexão

Quando o cliente terminar de interagir com o serviço, ele poderá fechar a conexão do WebSocket. Quando a conexão é fechada, o cliente não pode mais usá-la para enviar solicitações ou receber resultados. Feche a conexão somente após o cliente receber todos os resultados para uma solicitação. Eventualmente, a conexão atinge o tempo limite quando não é encerrada de forma explícita pelo cliente.

O fragmento a seguir do código JavaScript fecha uma conexão aberta:

websocket.close();

Como o serviço envia resultados de reconhecimento

A forma como o serviço envia resultados de reconhecimento de voz para o cliente depende de o cliente solicitar ou não resultados provisórios. Na resposta JSON a uma solicitação, os resultados finais são rotulados "final": true e os resultados provisórios são rotulados "final": false. Para obter mais informações, consulte Resultados provisórios.

Nos exemplos a seguir, os resultados mostram a resposta do serviço para o mesmo áudio de entrada enviado com e sem resultados provisórios. O áudio fala a frase "um dois ...pausa... três quatro", com uma pausa de um segundo entre as palavras "dois" e "três". A pausa é longa o suficiente para representar elocuções separadas. Uma elocução é um componente do áudio de entrada que extrai uma resposta, geralmente como resultado de um silêncio estendido. Para obter mais informações, consulte Compreendendo resultados de reconhecimento de voz.

Se seus resultados incluírem diversos resultados finais, concatene os elementos transcript dos resultados finais para montar a transcrição completa do áudio. Para obter mais informações, consulte O campo result_index.

Exemplo de solicitação sem resultados provisórios

O cliente desativa os resultados provisórios configurando o parâmetro interim_results para false ou omitindo o parâmetro de uma solicitação (o argumento padrão para o parâmetro é false). O cliente recebe um único objeto JSON na resposta somente depois de enviar uma mensagem stop.

O objeto de resposta pode conter múltiplos resultados finais para elocuções separadas do áudio. O serviço não envia o objeto de resposta única até receber uma mensagem stop para indicar que a transmissão de áudio para a solicitação está completa. A estrutura e o formato da resposta do serviço são os mesmos, independentemente de você utilizar um modelo anterior ou de última geração.

{
  "result_index": 0,
  "results": [
    {
      "alternatives": [
        {
          "confidence": 0.99,
          "transcript": "one two "
        }
      ],
      "final": true
    },
    {
      "alternatives": [
        {
          "confidence": 0.99,
          "transcript": "three four "
        }
      ],
      "final": true
    }
  ]
}

Exemplo de solicitação com resultados provisórios

O cliente solicita resultados provisórios da seguinte forma:

  • Para modelos de geração anterior, configurando o parâmetro interim_results para true.
  • Para modelos de última geração, configurando os parâmetros interim_results e low_latency para true. Para receber resultados provisórios com um modelo de última geração, o modelo deve suportar baixa latência e os parâmetros interim_results e low_latency devem estar configurados para true.

O cliente recebe vários objetos JSON na resposta. O serviço retorna objetos de resposta separados para cada resultado provisório e para cada resultado final que é gerado pelo áudio. O serviço envia pelo menos um resultado provisório para cada resultado final.

O serviço envia respostas assim que elas ficam disponíveis. Ele não espera uma mensagem stop para enviar seus resultados, embora a mensagem stop ainda seja necessária para sinalizar o fim da transmissão para a solicitação. A estrutura e o formato da resposta do serviço são os mesmos, independentemente de você utilizar um modelo anterior ou de última geração.

{
  "result_index": 0,
  "results": [
    {
      "alternatives": [
        {
          "transcript": "one "
        }
      ],
      "final": false
    }
  ]
}{
  "result_index": 0,
  "results": [
    {
      "alternatives": [
        {
          "transcript": "one two "
        }
      ],
      "final": false
    }
  ]
}{
  "result_index": 0,
  "results": [
    {
      "alternatives": [
        {
          "confidence": 0.99,
          "transcript": "one two "
        }
      ],
      "final": true
    }
  ]
}{
  "result_index": 1,
  "results": [
    {
      "alternatives": [
        {
          "transcript": "three "
        }
      ],
      "final": false
    }
  ]
}{
  "result_index": 1,
  "results": [
    {
      "alternatives": [
        {
          "transcript": "three four "
        }
      ],
      "final": false
    }
  ]
}{
  "result_index": 1,
  "results": [
    {
      "alternatives": [
        {
          "confidence": 0.99,
          "transcript": "three four "
        }
      ],
      "final": true
    }
  ]
}

Exemplo de trocas do WebSocket

Os exemplos a seguir mostram uma série de trocas entre um cliente e o serviço Speech to Text em uma única conexão de WebSocket. Os exemplos se concentram na troca de mensagens e dados. Eles não mostram a abertura e o fechamento da conexão. (Os exemplos são baseados em um modelo de geração anterior, portanto, a transcrição final para cada resposta inclui um campo confidence.)

Primeira interação de exemplo

Na primeira interação, o cliente envia áudio que contém a sequência Name the Mayflower. O cliente envia uma mensagem binária com um único chunk de dados de áudio PCM (audio/l16), para os quais ele indica a taxa de amostragem necessária. O cliente não aguarda a resposta {"state":"listening"} do serviço para começar a enviar os dados de áudio e para sinalizar o término da solicitação. O envio dos dados reduz imediatamente a latência porque o áudio se torna disponível para o serviço assim que está pronto para manipular uma solicitação de reconhecimento.

  • O cliente envia:

    {
      "action": "start",
      "content-type": "audio/l16;rate=22050"
    }
    <binary audio data>
    {
      "action": "stop"
    }
    
  • O serviço responde:

    {"state": "listening"}
    {"results": [{"alternatives": [{"transcript": "name the mayflower ",
                 "confidence": 0.91}], "final": true}], "result_index": 0}
    {"state":"listening"}
    

Segunda interação de exemplo

Na segunda interação, o cliente envia áudio que contém a sequência Second audio transcript. O cliente envia o áudio em uma única mensagem binária e usa os mesmos parâmetros que especificou na primeira solicitação.

  • O cliente envia:

    <binary audio data>
    {
      "action": "stop"
    }
    
  • O serviço responde:

    {"results": [{"alternatives": [{"transcript": "second audio transcript ",
                 "confidence": 0.99}], "final": true}], "result_index": 0}
    {"state":"listening"}
    

Terceira interação de exemplo

Na terceira interação, o cliente novamente envia áudio que contém a sequência Name the Mayflower. Ele envia uma mensagem binária com um único trecho de dados de áudio PCM. Mas, dessa vez, o cliente envia uma nova mensagem start que solicita resultados provisórios do serviço.

  • O cliente envia:

    {
      "action": "start",
      "content-type": "audio/l16;rate=22050",
      "interim_results": true
    }
    <binary audio data>
    {
      "action": "stop"
    }
    
  • O serviço responde:

    {"results": [{"alternatives": [{"transcript": "name "}],
                 "final": false}], "result_index": 0}
    {"results": [{"alternatives": [{"transcript": "name may "}],
                 "final": false}], "result_index": 0}
    {"results": [{"alternatives": [{"transcript": "name may flour "}],
                 "final": false}], "result_index": 0}
    {"results": [{"alternatives": [{"transcript": "name the mayflower ",
                 "confidence": 0.91}], "final": true}], "result_index": 0}
    {"state":"listening"}
    

Códigos de retorno do WebSocket

O serviço pode enviar os códigos de retorno a seguir para o cliente por meio da conexão do WebSocket:

  • 1000 indica encerramento normal da conexão, o que significa que o propósito para o qual a conexão foi estabelecida foi atendido.
  • 1002 indica que o serviço está fechando a conexão devido a um erro de protocolo.
  • 1006 indica que a conexão foi fechada anormalmente.
  • 1009 indica que o tamanho do quadro excedeu o limite de 4 MB.
  • 1011 indica que o serviço está finalizando a conexão porque encontrou uma condição inesperada que o impede de preencher a solicitação.

Se o soquete fechar com um erro, o cliente receberá uma mensagem informativa do formulário {"error":"{message}"} antes que o soquete seja fechado. Use o manipulador de eventos onerror para responder apropriadamente. Para obter mais informações sobre os códigos de retorno do site WebSocket, consulte a IETF RFC 6455.

As implementações de WebSocket dos SDKs podem retornar códigos de resposta diferentes ou adicionais. Para obter mais informações, consulte a Referência da API e do SDK