La Información de Mejora Suplementaria (SEI, por sus siglas en inglés) es un mecanismo dentro de los flujos de bits de video que permite adjuntar metadatos personalizados a los cuadros de video. A diferencia de los mensajes enviados por canales de datos paralelos, el SEI viaja empaquetado directamente con la señal de video, lo que garantiza una sincronización temporal perfecta entre el contenido visual y la información adicional.
Esta tecnología es fundamental en escenarios donde la latencia y la precisión son críticas, tales como:
- Sincronización de letras en aplicaciones de Karaoke.
- Actualización de diseños de pantalla en transmisiones multijugador.
- Activación de preguntas en trivias en vivo.
- Transmisión de parámetros técnicos o estados del emisor en tiempo real.
1. Configuración del tipo de SEI
Por defecto, algunos SDK utilizan tipos de SEI propietarios (como el NALU tipo 6, payload 243) para evitar conflictos con codificadores estándar. Sin embargo, si se requiere compatibilidad con decodificadores de terceros como FFmpeg, es necesario configurar el tipo de SEI a UserUnregister (payload tipo 5).
// Configuración avanzada para compatibilidad con decodificadores externos
ZegoSEIConfig configuracionSEI = new ZegoSEIConfig();
configuracionSEI.type = ZegoSEIType.USER_UNREGISTER;
// Aplicar la configuración antes de iniciar la transmisión
instanciaEngine.setSEIConfig(configuracionSEI);
// Opcionalmente, definir un filtro UUID para identificar los mensajes
ZegoEngineConfig configMotor = new ZegoEngineConfig();
configMotor.advancedConfig.put("unregister_sei_filter", "mi_identificador_unico");
ZegoExpressEngine.setEngineConfig(configMotor);
2. Flujo de implementación del emisor
Para enviar información SEI, el emisor debe haber iniciado correctamente la publicación de una secuencia de video. El envío de datos SEI debe realizarse con una frecuencia controlada (se recomienda no exceder los 30 pauqetes por segundo) para no saturar el ancho de banda del flujo.
Pasos principales:
- Inicializar el motor y autenticar al usuario en la sala.
- Llamar a
startPublishingStreampara comenzar el flujo. - Utilizar el método
sendSEIcuando el evento de negocio lo requiera.
// Ejemplo de envío de metadatos en el lado del emisor
String datosJson = "{\"comando\": \"mostrar_letra\", \"texto\": \"Hola Mundo\"}";
byte[] payload = datosJson.getBytes();
// Es recomendable reintentar el envío si la sincronización es crítica
instanciaEngine.sendSEI(payload);
3. Flujo de implementación del receptor
El receptor debe estar suscrito al flujo de video para procesar los paquetes SEI. Si el receptor silencia el video (mute) mediante el SDK, dejará de recibir los datos SEI asociados a esos cuadros.
Pasos principales:
- Registrar un manejador de eventos (Event Handler).
- Sobrescribir el método de recuperación de SEI.
- Iniciar la reproducción del flujo con
startPlayingStream.
// Implementación del receptor para procesar mensajes SEI
instanciaEngine.setEventHandler(new IZegoEventHandler() {
@Override
public void onPlayerRecvSEI(String idTransmision, byte[] contenido) {
// Convertir los bytes recibidos a una cadena de texto
String mensajeRecibido = new String(contenido);
// Ejecutar lógica de interfaz de usuario o procesamiento de datos
procesarDatosSincronizados(idTransmision, mensajeRecibido);
}
});
// Iniciar la escucha del flujo remoto
instanciaEngine.startPlayingStream("id_secuencia_remota", vistaRenderizado);
4. Consideraciones técnicas importantes
- Limitación de tamaño: El paquete de datos SEI no suele superar los 4096 bytes. Se recomienda mantener los mensajes lo más ligeros posible.
- Naturaleza de los datos: Al estar ligados a los cuadros de video, si un cuadro se pierde debido a condiciones de red, el SEI asociado también se perderá. No debe usarse para transferencias de archivos o datos críticos de configuración que no puedan tolerar pérdidas.
- Sincronización de audio: El SEI se adjunta predominantemente al flujo de video. En configuraciones de "solo audio", la disponibilidad de SEI depende de la implementación específica del transporte del SDK.