IBM Cloud Docs
La interfaz WebSocket

La interfaz WebSocket

La interfaz WebSocket del servicio IBM Watson® Speech to Text es la forma más natural de que un cliente interactúe con el servicio. Para utilizar la interfaz WebSocket para el reconocimiento de voz, primero debe utilizar el método /v1/recognize para establecer una conexión permanente con el servicio. A continuación, envía mensajes de texto y binarios a través de la conexión para iniciar y gestionar solicitudes de reconocimiento.

Debido a sus ventajas, WebSockets es el mecanismo preferido para el reconocimiento de voz. Para obtener más información, consulte Ventajas de la interfaz WebSocket. Para obtener más información sobre la interfaz WebSocket y sus parámetros, consulte la referencia de API y SDK.

Gestión de una conexión WebSocket

El ciclo de solicitud y respuesta de reconocimiento de WebSocket tiene los pasos siguientes:

  1. Abrir una conexión
  2. Iniciar una solicitud de reconocimiento
  3. Enviar audio y recibir los resultados del reconocimiento
  4. Finalizar una solicitud de reconocimiento
  5. Enviar solicitudes adicionales y modificar los parámetros de la solicitud
  6. Mantener activa una conexión
  7. Cerrar una conexión

Cuando el cliente envía datos al servicio, debe pasar todos los mensajes JSON como mensajes de texto y todos los datos de audio como mensajes binarios.

Los fragmentos de código de ejemplo que se muestran a continuación están escritos en JavaScript y se basan en la API de WebSocket HTML5. Para obtener más información sobre el protocolo WebSocket, consulte la Solicitud de comentarios(RFC)6455 del Grupo de trabajo de ingeniería de Internet (IETF).

Abrir una conexión

El servicio Speech to Text utiliza el protocolo WebSocket Secure (WSS) para hacer que el método /v1/recognize esté disponible en el punto final siguiente:

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

donde {location} indica el lugar en el que se aloja la aplicación:

  • us-south para Dallas
  • us-east para Washington, DC
  • eu-de para Frankfurt
  • au-syd para Sídney
  • jp-tok para Tokio
  • eu-gb para Londres
  • kr-seo para Seúl

{instance_id} es el identificador exclusivo de la instancia de servicio.

Los ejemplos de la documentación abrevian wss://api.{location}.speech-to-text.watson.cloud.ibm.com/instances/{instance_id} como {ws_url}. Todos los ejemplos de WebSocket llaman al método como {ws_url}/v1/recognize.

Un cliente WebSocket llama al método /v1/recognize con los siguientes parámetros de consulta para establecer una conexión autenticada con el servicio. Puede especificar estos aspectos de la solicitud sólo como parámetros de consulta del URL de WebSocket.

access_token (serie obligatoria)

Pase una señal de acceso válida para establecer una conexión autenticada con el servicio. Debe establecer la conexión antes de que caduque la señal de acceso. Pase una señal de acceso sol para establecer una conexión autenticada. Una vez establecida la conexión, puede mantenerla activa de forma indefinida. Seguirá estando autenticado mientras mantenga la conexión abierta. No es necesario renovar la señal de acceso para una conexión activa que dure más que el periodo de caducidad de la señal. Una vez establecida una conexión, puede permanecer activa incluso después de suprimir la señal o sus credenciales.

  • IBM Cloud Pasar un token de acceso de gestión de identidades y acceso ( Identity and Access Management, IAM) para autenticarse en el servicio. Se pasa una señal de acceso de IAM en lugar de pasar una clave de API con la llamada. Para obtener más información, consulte Autenticación en IBM Cloud.
  • IBM Cloud Pak for Data Software Hub IBM Pase un token de acceso como lo haría con el Authorization encabezado de una solicitud HTTP. Para obtener más información, consulte Autenticación en IBM Cloud Pak for Data.
model (serie opcional)

Especifica el modelo de lenguaje que se debe utilizar para la transcripción. Si no especifica un modelo, el servicio utiliza en-US_BroadbandModel de forma predeterminada. Para obtener más información, consulte

language_customization_id (serie opcional)

Especifica el identificador global exclusivo (GUID) de un modelo de lenguaje personalizado que se va a utilizar para todas las solicitudes que se envían a través de la conexión. El modelo base del modelo de lenguaje personalizado debe coincidir con el valor del parámetro model. Si incluye un ID de modelo de idioma personalizado, debe realizar la solicitud con credenciales para la instancia del servicio que posee el modelo personalizado. De forma predeterminada, no se utiliza ningún modelo de lenguaje personalizado. Para obtener más información, consulte Utilización de un modelo de idioma para el reconocimiento de voz.

acoustic_customization_id (serie opcional)

Especifica el GUID de un modelo acústico personalizado que se va a utilizar para todas las solicitudes que se envían a través de la conexión. El modelo base del modelo acústico personalizado debe coincidir con el valor del parámetro model. Si incluye un ID de modelo acústico personalizado, debe realizar la solicitud con credenciales para la instancia del servicio que posee el modelo personalizado. De forma predeterminada, no se utiliza ningún modelo acústico personalizado. Para obtener más información, consulte Utilización de un modelo acústico personalizado para el reconocimiento de voz.

base_model_version (serie opcional)

Especifica la versión del model base que se va a utilizar para todas las solicitudes que se envíen a través de la conexión. El parámetro está pensado principalmente para que se utilice con modelos personalizados que se actualizan para un nuevo modelo base. El valor predeterminado depende de si el parámetro se utiliza con o sin un modelo personalizado. Para obtener más información, consulte Realización de solicitudes de reconocimiento de voz con modelos personalizados actualizados.

x-watson-metadata (serie opcional)

Asocia un ID de cliente con todos los datos que se pasan a través de la conexión. El parámetro acepta el argumento customer_id={id}, donde id es una serie aleatoria o genérica para asociar a los datos. Debe codificar en URL el argumento para el parámetro, por ejemplo customer_id%3dmy_customer_ID. De forma predeterminada, no hay ningún ID de cliente asociado a los datos. Para obtener más información, consulte Seguridad de la información.

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

IBM Cloud Indica si el servicio registra las solicitudes y los resultados que se envían a través de la conexión. Para evitar que IBM acceda a sus datos para mejoras de servicio generales, especifique true en el parámetro. Para obtener más información, consulte Registro de solicitudes.

El siguiente fragmento de código JavaScript abre una conexión con el servicio. La llamada al método /v1/recognize pasa los parámetros de consulta access_token y model, este último para indicar al servicio que utilice el modelo de banda ancha en español. Después de establecer la conexión, el cliente define las escuchas de sucesos (onOpen, onClose, etc.) para responder a los sucesos procedentes del servicio. El cliente puede utilizar la conexión para varias solicitudes de reconocimiento.

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) };

El cliente puede abrir varias conexiones WebSocket simultáneas en el servicio. El número de conexiones simultáneas está limitado únicamente por la capacidad del servicio, que no suele plantear problemas a los usuarios.

Iniciar una solicitud de reconocimiento

Para iniciar una solicitud de reconocimiento, el cliente envía un mensaje de texto JSON al servicio a través de la conexión establecida. El cliente debe enviar este mensaje antes de enviar cualquier audio para la transcripción. El mensaje debe incluir el parámetro action pero normalmente puede omitir el parámetro content-type:

action (serie obligatoria)
Especifica la acción que se va a llevar a cabo:
content-type (serie opcional)
Identifica el formato (tipo de MIME) de los datos de audio de la solicitud. El parámetro es obligatorio para los formatos audio/alaw, audio/basic, audio/l16 y audio/mulaw. Para obtener más información, consulte Formatos de audio.

El mensaje también puede incluir parámetros opcionales para especificar otros aspectos sobre cómo se va a procesar la solicitud y la información que se va a devolver. Estos parámetros adicionales incluyen el parámetro interim_results, que sólo está disponible con la interfaz WebSocket.

  • Para obtener más información sobre todas las características de reconocimiento de voz, consulte el Resumen de parámetros.
  • Para obtener más información sobre el parámetro interim_results, consulte Resultados provisionales.

El siguiente fragmento de código JavaScript envía parámetros de inicialización para la solicitud de reconocimiento a través de la conexión WebSocket. Las llamadas están incluidas en la función onOpen del cliente para garantizar que se envíen solo después de que se establezca la conexión.

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

Si recibe la solicitud satisfactoriamente, el servicio devuelve el siguiente mensaje de texto para indicar que es listening. El estado listening indica que la instancia de servicio está configurada (el mensaje JSON start era válido) y está preparada para aceptar audio para una solicitud de reconocimiento.

{'state': 'listening'}

Si el cliente especifica un parámetro de consulta o un campo JSON no válido para la solicitud de reconocimiento, la respuesta JSON del servicio incluye un campo warnings (de aviso). El campo describe cada argumento no válido. La solicitud tiene éxito a pesar de las advertencias.

Enviar audio y recibir los resultados del reconocimiento

Después de enviar el mensaje start inicial, el cliente puede empezar a enviar datos de audio al servicio. No es necesario que el cliente espere a que el servicio responda al mensaje start con el mensaje listening. Una vez que empieza a escuchar, el servicio procesa cualquier audio que se haya enviado antes del mensaje listening.

El cliente debe enviar el audio como datos binarios. El cliente puede enviar un máximo de 100 MB de datos de audio por solicitud send. Debe enviar al menos 100 bytes de audio con cualquier solicitud. El cliente puede enviar varias solicitudes a través de una única conexión WebSocket. Para obtener información sobre cómo utilizar la compresión para maximizar la cantidad de audio que puede pasar al servicio con una solicitud, consulte Límites de datos y compresión.

La interfaz WebSocket impone un tamaño máximo de trama de 4 MB. El cliente puede establecer el tamaño máximo de trama en menos de 4 MB. Si no resulta práctico establecer el tamaño de trama, el cliente puede establecer el tamaño máximo de mensaje en menos de 4 MB y enviar los datos de audio como una secuencia de mensajes. Para obtener más información sobre los marcos de transferencia de hipertexto ( WebSocket ), consulte IETF RFC 6455.

El modo en que el servicio envía los resultados de reconocimiento a través de una conexión WebSocket depende de si el cliente solicita resultados provisionales. Para obtener más información, consulte Cómo el servicio envía resultados de reconocimiento.

El siguiente fragmento de código JavaScript envía datos de audio al servicio como un mensaje binario (blob):

websocket.send(blob);

El siguiente fragmento de código recibe las hipótesis de reconocimiento que el servicio devuelve de forma asíncrona. Los resultados se manejan mediante la función onMessage del cliente.

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

El código debe estar preparado para manejar los códigos de retorno de retorno del servicio. Para obtener más información, consulte Códigos de retorno WebSocket.

Finalizar una solicitud de reconocimiento

Cuando termina de enviar los datos de audio para una solicitud al servicio, el cliente debe indicar el final de la transmisión de audio en binario al servicio de una de las formas siguientes:

  • Mediante el envío de un mensaje de texto JSON con el parámetro action establecido en stop:

    {action: 'stop'}
    
  • Mediante el envío de un mensaje binario vacío, uno en el que el blob especificado esté vacío:

    websocket.send(blob)
    

Si el cliente no puede indicar que la transmisión está completa, la conexión puede quedarse sin tiempo sin que el servicio envíe los resultados finales. Para recibir los resultados finales entre varias solicitudes de reconocimiento, el cliente debe indicar el final de la transmisión de la solicitud anterior antes de enviar la siguiente solicitud. Después de devolver los resultados finales para la primera solicitud, el servicio devuelve otro mensaje {"state":"listening"} al cliente. Este mensaje indica que el servicio está listo para recibir otra solicitud.

Enviar solicitudes adicionales y modificar los parámetros de la solicitud

Mientras la conexión de WebSocket permanezca activa, el cliente puede seguir utilizando la conexión para enviar más solicitudes de reconocimiento con un nuevo audio. De forma predeterminada, el servicio sigue utilizando los parámetros que se enviaron con el mensaje start anterior para las siguientes solicitudes que se envíen a través de la misma conexión.

Para cambiar los parámetros de las solicitudes posteriores, el cliente puede enviar otro mensaje start con los nuevos parámetros después de recibir los resultados de reconocimiento final y un nuevo mensaje de {"state":"listening"} del servicio. El cliente puede cambiar cualquier parámetro excepto los que se especifican al abrir la conexión (model, language_customization_id, etc.).

El ejemplo siguiente envía un mensaje start con parámetros nuevos para las siguientes solicitudes de reconocimiento que se envían a través de la conexión. El mensaje especifica el mismo content-type que el ejemplo anterior, pero indica al servicio que devuelva las medidas de confianza y las indicaciones de fecha y hora para las palabras de la transcripción.

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

Mantener activa una conexión

El servicio finaliza la sesión y cierra la conexión si se llega al tiempo de espera excedido de inactividad o de sesión:

  • Se produce un tiempo de espera excedido de inactividad si el cliente está enviando audio pero el servicio no detecta voz. El tiempo de espera excedido predeterminado de inactividad es de 30 segundos. Puede utilizar el parámetro inactivity_timeout para especificar otro valor, incluido -1 para establecer un tiempo de espera excedido infinito. Para obtener más información, consulte Tiempo de espera excedido de inactividad.
  • Se produce un tiempo de espera excedido de sesión si el servicio no recibe datos del cliente o si no envía ningún resultado provisional durante 30 segundos. No puede cambiar la duración de este tiempo de espera excedido, pero puede ampliar la sesión enviando al servicio datos de audio, silencio incluido, antes de que se alcance el tiempo de espera excedido. También debe establecer el parámetro inactivity_timeout en -1. Se le factura por la duración de los datos que envía al servicio, incluido el silencio que envíe para ampliar una sesión. Para obtener más información, consulte Tiempo de espera excedido de sesión.

Los clientes y servidores de WebSocket también intercambian marcos de tipo ping-pong para evitar los tiempos de espera excedidos de lectura intercambiando periódicamente pequeñas cantidades de datos. Muchas pilas de WebSocket intercambian marcos de tipo ping-pong, pero algunas no lo hacen. Para determinas si su implementación utiliza los marcos de tipo ping-pong, compruebe las listas de funciones. No puede determinar o gestionar marcos de tipo ping-pong de forma programática.

Si su pila de WebSocket no implementa los marcos de tipo ping-pong y se están enviando archivos de audio largos, su conexión puede experimentar un tiempo de espera excedido de lectura. Para evitar estos tiempos de espera, la secuencia de audio continuada al servicio o solicitar resultados provisionales del servicio. Cualquier enfoque puede garantizar que la falta de marcos de tipo ping-pong no haga que se cierre la conexión.

Para obtener más información sobre los marcos de ping-pong, consulte la sección 5.5.2 Ping y la sección 5.5.3 Pong de la RFC 6455 del IETF.

Cerrar una conexión

Cuando el cliente termina de interactuar con el servicio, puede cerrar la conexión WebSocket. Una vez que se ha cerrado la conexión, el cliente ya no puede utilizarla para enviar solicitudes ni para recibir resultados. Cierre la conexión sólo después de que el cliente reciba todos los resultados de una solicitud. La conexión eventualmente agota el tiempo y se cierra si el cliente no la cierra explícitamente.

El siguiente fragmento de código JavaScript cierra una conexión abierta:

websocket.close();

Cómo el servicio envía resultados de reconocimiento

La forma en que el servicio envía los resultados del reconocimiento de voz al cliente depende de si el cliente solicita resultados provisionales. En la respuesta JSON a una solicitud, los resultados finales se etiquetan como "final": truey los resultados provisionales se etiquetan como "final": false. Para obtener más información, consulte Resultados provisionales.

En los ejemplos siguientes, los resultados muestran la respuesta del servicio para el mismo audio de entrada enviado con y sin resultados provisionales. El audio dice la frase "uno dos...pausa... tres cuatro", con una segunda pausa entre las palabras "dos" y "tres". La pausa es lo suficientemente larga como para representar expresiones separadas. Una expresión es un componente del audio de entrada que provoca una respuesta, generalmente como resultado de un silencio extendido. Para obtener más información, consulte Cómo comprender los resultados del reconocimiento.

Si los resultados incluyen varios resultados finales, concatene los elementos transcript de los resultados finales para ensamblar la transcripción completa del audio. Para obtener más información, consulte El campo result_index.

Solicitud de ejemplo sin resultados provisionales

El cliente inhabilita los resultados provisionales estableciendo el parámetro interim_results en false u omitiendo el parámetro de una solicitud (el argumento predeterminado para el parámetro es false). El cliente recibe un solo objeto JSON en respuesta sólo después de enviar un mensaje stop.

El objeto de respuesta puede contener varios resultados finales para expresiones separadas del audio. El servicio no envía el objeto de respuesta individual hasta que recibe un mensaje de stop para indicar que se ha completado la transmisión de audio para la solicitud. La estructura y el formato de la respuesta del servicio son los mismos independientemente de si se utiliza un modelo de generación anterior o de próxima generación.

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

Solicitud de ejemplo con resultados provisionales

El cliente solicita los resultados provisionales de la siguiente manera:

  • Para modelos de generación anterior, estableciendo el parámetro interim_results en true.
  • Para modelos de próxima generación, estableciendo los parámetros interim_results y low_latency en true. Para recibir resultados provisionales con un modelo de próxima generación, el modelo debe dar soporte a una latencia baja y los parámetros interim_results y low_latency deben establecerse en true.

El cliente recibe varios objetos JSON en la respuesta. El servicio devuelve objetos de respuesta separados para cada resultado provisional y para cada resultado final generado por el audio. El servicio envía al menos un resultado provisional para cada resultado final.

El servicio envía respuestas tan pronto como están disponibles. No espera a que un mensaje de stop envíe sus resultados, aunque el mensaje stop sigue siendo necesario para indicar el final de la transmisión para la solicitud. La estructura y el formato de la respuesta del servicio son los mismos independientemente de si se utiliza un modelo de generación anterior o de próxima generación.

{
  "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
    }
  ]
}

Ejemplo de intercambios WebSocket

Los ejemplos siguientes muestran una serie de intercambios entre un cliente y el servicio Speech to Text a través de una única conexión WebSocket. Los ejemplos se centran en el intercambio de mensajes y datos. No muestran la apertura y el cierre de la conexión. (Los ejemplos se basan en un modelo de generación anterior, por lo que la transcripción final para cada respuesta incluye un campo confidence.)

Primer intercambio de ejemplo

En el primer intercambio, el cliente envía audio que contiene la serie Name the Mayflower. El cliente envía un mensaje binario con una sola porción de datos de audio PCM (audio/l16), para los que indica la frecuencia de muestreo necesaria. El cliente no espera a recibir la respuesta {"state":"listening"} del servicio para empezar a enviar los datos de audio y para señalar el fin de la solicitud. El envío inmediato de los datos reduce la latencia porque el audio está disponible para el servicio en cuanto está preparado para gestionar una solicitud de reconocimiento.

  • El cliente envía:

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

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

Segundo intercambio de ejemplo

En el segundo intercambio, el cliente envía audio que contiene la serie Second audio transcript. El cliente envía el audio en un solo mensaje binario y utiliza los mismos parámetros que ha especificado en la primera solicitud.

  • El cliente envía:

    <binary audio data>
    {
      "action": "stop"
    }
    
  • El servicio responde:

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

Tercer intercambio de ejemplo

En el tercer intercambio, el cliente vuelve a enviar audio que contiene la serie Name the Mayflower. Envía un mensaje binario con un solo fragmento de datos de audio PCM. Pero esta vez, el cliente envía un nuevo mensaje start que solicita resultados provisionales del servicio.

  • El cliente envía:

    {
      "action": "start",
      "content-type": "audio/l16;rate=22050",
      "interim_results": true
    }
    <binary audio data>
    {
      "action": "stop"
    }
    
  • El servicio 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 de WebSocket

El servicio puede enviar los siguientes códigos de retorno al cliente a través de la conexión de WebSocket:

  • 1000 indica el cierre normal de la conexión, lo que significa que la finalidad para la que se ha establecido la conexión se ha cumplido.
  • 1002 indica que el servicio cierra la conexión debido a un error de protocolo.
  • 1006 indica que la conexión se ha cerrado anormalmente.
  • 1009 indica que el tamaño de trama ha sobrepasado el límite de 4 MB.
  • 1011 indica que el servicio está terminando la conexión porque ha encontrado una condición inesperada que le impide cumplir la solicitud.

Si el socket se cierra con un error, el cliente recibe un mensaje informativo con el formato {"error":"{message}"} antes de que se cierre el socket. Utilice el manejador de sucesos de onerror para responder adecuadamente. Para obtener más información sobre los códigos de retorno WebSocket, consulte IETF RFC 6455.

Las implementaciones de WebSocket de los SDK pueden devolver códigos de respuesta diferentes o adicionales. Para obtener más información, consulte la Referencia de API y SDK.