Video Call
  • iOS
  • Android : Java
  • Web
  • Flutter
  • React Native
  • Electron
  • Unity3D
  • Cocos Creator
  • Windows
  • macOS
  • Linux
  • Overview
  • Develop your app
    • Quick start
    • Enhance basic feature
      • Use Tokens for authentication
      • Config your video based on scenes
      • Check the room connection status
      • Set up common video config
      • Set up common audio config
  • Best practices
    • Implement a video call for multiple users
    • Implement call invitation
    • Implement a live audio room
  • Upgrade using advanced features
    • Advanced features
      • Configure the video
        • Watermark the video/Take snapshots
        • Improve your appearance in the video
        • Beautify & Change the voice
        • Configure video codec
        • Output the video in H.265
      • Improve video quality
        • Configure bandwidth management
        • Test network and devices in advance
        • Visualize the sound level
        • Monitor streaming quality
      • Message signaling
        • Convey extra information using SEI
        • Broadcast real-time messages to a room
        • Quotas and limits
      • Play media files
        • Play media files
        • Play sound effects
      • Share the screen
      • Mix the video streams
      • Publish multiple video streams
      • Encrypt the video streams
      • Record video media data
    • Distincitve features
      • Join multiple rooms
      • Customize the video and audio
      • Set the voice hearing range
      • Transfer traffic via the cloud proxy server
      • Use the bit mask
      • Play streams via URL
      • Play a transparent gift special effect
      • AI Voice Changer
      • In-game voice chat
  • Upgrade using Add-on
  • Resources & Reference
    • SDK
    • Sample codes
    • API reference
      • Client APIs
      • Server APIs
    • Debugging
      • Error codes
      • Logging/Version number
    • FAQs
    • Key concepts
  • Documentation
  • Video Call
  • Upgrade using advanced features
  • Advanced features
  • Message signaling
  • Convey extra information using SEI

Convey extra information using SEI

Last updated:2023-09-07 14:18

Introduction

In audio and video streaming, supplemental enhancement information (SEI) is the text data inserted into the audio and video bitstream to convey extra information, which can be received in accurate synchronization with the related audio and video content.

You can use SEI for various purposes. For example:

  • To include the video layout information in the stream.
  • To send lyrics text in synchronization with the audio and video content.
  • To send quiz information in live quizzing use cases.

Prerequisites

Before you begin, make sure you complete the following:

  • Create a project in ZEGOCLOUD Admin Console and get the AppID and AppSign of your project.

  • Refer to the Quick Start doc to complete the SDK integration and basic function implementation.

Implementation process

The following diagram shows the API call sequence of sending and receiving SEI messages.

/Pics/Common/ZegoExpressEngine/send_and_recv_sei.png

On the stream publisher side, follow these steps to send SEI messages:

  1. Call the createEngine method to create a ZegoExpressEngine instance.

  2. Call the loginRoom method to log in to a room.

  3. Call the startPublishingStream method to start publishing a stream.

  4. After the stream publishing starts successfully, call the sendSEI method to send SEI messages when needed.

On the stream subscriber side, follow these steps to receive SEI messages:

  1. Call the createEngine method to create a ZegoExpressEngine instance.
  2. Create an IZegoEventHandler instance, and override the onPlayerRecvSEI method to implement your SEI message processing logic.
  3. Call the setEventHandler method with the IZegoEventHandler instance created in the previous step passed in as the eventHandler parameter.
  4. Call the loginRoom method to log in to a room.
  5. Call the startPlayingStream method to start playing a stream.
  6. After the stream playback starts successfully, when an SEI message is received, the SDK triggers the onPlayerRecvSEI callback to process the message.

Optional: Set the SEI type

Set SEI type

By default, the ZEGO Express SDK uses a ZEGO-defined SEI type (NALU Type = 6, Payload Type = 243) for packaging SEI messages. This SEI type isn't defined in the SEI types of the SDK's video codes and doesn't mix up with the existing SEI data of the source video file.

But if you use a third-party decoder like FFmpeg, the SEI messages with the ZEGO-defined SEI type can't be decoded correctly. To solve this issue, you need to call the setSEIConfig method to change the SEI type to the UserUnregister type (NALU Type = 6, Payload Type = 5).

As SEI data with Payload Type 5 can also be generated by the video encoder or may exist in the source video file, when you send SEI with Payload Type 5, you need a mechanism to differentiate your SEI data from the SEI data generated by the video encoder itself. For this purpose, you can configure a UUID (16 bytes in length) as an SEI filtering keyword for the ZegoExpressEngine. On the stream publisher side, pass "UUID + message content" as the buffer to the sendSEI method when sending SEI messages. On the stream subscriber side, the SDK only throws out those SEI messages that start with the configured UUID. If no UUID is configured, the SDK throws out all received SEI messages.

This step is required only when you use a third-party decoder to decode SEI.
  • Function prototype:

    /**
     * Sets the supplemental enhancement information (SEI) type
     *
     * The SEI type must be set before stream publishing starts.
     *
     * @param config: The SEI configuration object. By default, the ZEGO Express SDK uses the ZEGO-defined SEI type to package SEI messages.
     */
    public void setSEIConfig(ZegoSEIConfig config);
  • Sample code:

    // Configure the SDK to use the UserUnregister SEI type (NALU Type = 6, Payload Type = 5).
    
    ZegoSEIConfig seiConfig = new ZegoSEIConfig();
    
    seiConfig.type = ZegoSEIType.USER_UNREGISTER;
    
    engine.setSEIConfig(seiConfig);
    
    // Set up the advancedConfig property to configure a UUID for filtering SEI messages. With this setup, the SDK on the stream subscriber side only throws out those SEI messages of which the first 12 bytes match the configured UUID.
    ZegoEngineConfig engineConfig = new ZegoEngineConfig();
    // The first 12 bytes of SEI messages by the stream subscribers through the [onPlayerRecvSEI] callback are always "zegozegozego".
    engineConfig.advancedConfig.put("unregister_sei_filter", "zegozegozego");
    ZegoExpressEngine.setEngineConfig(engineConfig);
    
    // Start publishing a stream.
    engine.startPublishingStream("STREAM_ID");

Send SEI messages

On the stream publisher side, after the stream publishing starts successfully, you can call the sendSEI method to send SEI messages when needed.

  • Funcation prototype:

    /**
     * Sends supplemental enhancement information (SEI)
     *
     * You can use this method to send extra text information alongside the audio and video stream being published for various purposes. 
     * For example, you can use SEI to include video layout information in a video stream or send lyrics text in synchronization with the audio and video content.
     * After the stream publisher sends an SEI message, the stream subscribers can receive it by listening for the [onPlayerRecvSEI] callback.
     * SEI messages are packaged as part of the bitstream of the audio/video frames, which can be lost because of network problems. To solve such potential issues, you can send the same SEI message several times with a limited frequency. 
     * Frequency limit: No more than 30 times per second.
     * The maximum length of the SEI data is 4096 bytes.
     * @param data: SEI data
     */
    public void sendSEI(byte[] data)
  • Sample code:

    /** Define a ZegoExpressEngine object */
    ZegoExpressEngine engine;
    
    ZegoEngineProfile profile = new ZegoEngineProfile();
    /** AppID format: 123456789L */
    profile.appID = appID;
    /** General scenario */
    profile.scenario = ZegoScenario.GENERAL;
    /** Set application object of App */
    profile.application = getApplication();
    /** Create a ZegoExpressEngine instance */
    engine = ZegoExpressEngine.createEngine(profile, null);
    // Log in to a room.
    engine.loginRoom("roomid", new ZegoUser("userid_1"));
    // Start publishing a stream.
    engine.startPublishingStream("streamid");
    // Implement other business logic.
    ...;
    // Send SEI messages when needed.
    engine.sendSEI("12345".getBytes());

Receive SEI messages

On the stream subscriber side, after the stream playback starts successfully, the SDK triggers the onPlayerRecvSEI callback when an SEI message is received.

  • Function prototype:

    /**
     * The callback triggered when a supplemental enhancement information (SEI) message is received
     *
     * After the stream playback starts successfully, the SDK triggers this callback when an SEI message is received.
     * If a subscriber subscribes to the audio stream only, it can't receive any SEI messages.
     * @param data: SEI content
     * @param streamID: Stream ID
     */
    public void onPlayerRecvSEI(String streamID, byte[] data){
    
    }
  • Sample code:

    /** Define a ZegoExpressEngine object */
    ZegoExpressEngine engine;
    
    ZegoEngineProfile profile = new ZegoEngineProfile();
    /** AppID format: 123456789L */
    profile.appID = appID;
    /** General scenario */
    profile.scenario = ZegoScenario.GENERAL;
    /** Set application object of App */
    profile.application = getApplication();
    /** Create a ZegoExpressEngine instance */
    engine = ZegoExpressEngine.createEngine(profile, null);
    
    // Create an IZegoEventHandler object, and override the onPlayerRecvSEI method to implement your SEI message processing logic.
    IZegoEventHandler handler = new IZegoEventHandler(){
        // Listen for other callbacks.
        ...;
    
        // Listen for the callback that is triggered when an SEI message is received.
        public void onPlayerRecvSEI(String streamID, byte[] data) {
            // Implement your SEI processing logic. For example, present the related UI components.
            ...;
        }
    
    }
    // Set up the event handler.
    engine.setEventHandler(handler);
    // Log in to a room.
    engine.loginRoom("roomid", new ZegoUser("userid_2"));
    // Start playing a stream.
    engine.startPlayingStream("streamid", canvas);
    // Implement other business logic.
    ...;
Page Directory