All Products
Search
Document Center

ApsaraVideo Live:Send and receive SEI messages

Last Updated:Dec 15, 2025

ApsaraVideo Real-time Communication (ARTC) SDK supports sending and receiving Supplemental Enhancement Information (SEI) messages. This feature allows you to transport custom messages from the RTC system to Global Realtime Transport Network or a third-party live streaming platform.

Feature introduction

SEI is part of video encoding standards such as H.264/AVC and H.265/HEVC. It is used to carry additional information related to the video content. This information provides supplementary functionality for the receiver, such as synchronization or error recovery, and can be used for scenarios such as precise video layout, lyric synchronization, and interactive live quizzes.

image

SEI is the recommended method for sending custom messages. The message is embedded into the video stream and transmitted along with the video data to other users in the channel.

  • Pros:

    • High real-time performance: Text messages are synchronized with the media stream.

    • Unlimited receivers: Anyone who subscribes to the stream can receive the message.

  • Cons:

    • Size limit: To avoid impacting video stream quality, each SEI message is limited to a maximum of 4 KB.

Sample code

ARTC provides an open-source demo project for your reference. You can download them or view the code online.

Android: Android/ARTCExample/BasicUsage/src/main/java/com/aliyun/artc/api/basicusage/SEIUsage/SEIActivity.java

iOS: iOS/ARTCExample/BasicUsage/SEIUsage/SEIUsageVC.swift

Before you begin

Before you implement the feature, make sure you meet the following requirements:

Implementation

Send an SEI message

After starting to publish a video stream, call the sendMediaExtensionMsg API to send SEI data.

API information

The ARTC SDK provides two methods for sending SEI messages.

API

Description

sendMediaExtensionMsg

Parameters:

  • message: The media extension message. Max length: 4096 bytes. We recommend using JSON or a plain string.

  • repeatCount: The number of times to repeat the message. This provides redundancy to prevent message loss due to network packet loss. Use -1 for infinite repetition.

  • delay: The delay in milliseconds before the message is sent after the API is called.

  • isKeyFrame: A boolean indicating whether to attach the message only to keyframes (true) or to all frames (false).

sendMediaExtensionMsgEx

This method is an extension of sendMediaExtensionMsg. It includes an additional payloadType parameter to set the SEI message type. The valid range is [5, 100-254]. Using a payloadType of 5 is equivalent to calling sendMediaExtensionMsg.

Note

Only one media extension message can be in transit at a time. Subsequent calls to sendMediaExtensionMsg will overwrite the previous message.

Sample code

The following examples demonstrate how to send a string as an SEI message using sendMediaExtensionMsg.

Android

// Prerequisite: You have joined a channel and started stream ingest (automatic ingest by default).
mSendSEIButton.setOnClickListener(v -> {
    if(mAliRtcEngine == null) {
        return;
    }
    String seiMessage = mEditText.getText().toString();
    if (TextUtils.isEmpty(seiMessage)) {
        return;
    }
    byte[] seiData = seiMessage.getBytes();
    mAliRtcEngine.sendMediaExtensionMsg(seiData,1,0,false);
    // mAliRtcEngine.sendMediaExtensionMsgEx(seiData,1,0,false, 5);
});

iOS

// Send an SEI message
func sendSEI(seiMessage: String) -> Bool {
    guard let data = seiMessage.data(using: .utf8) else {
        return false
    }
    let repeatCount: Int32 = 1
    let delay: Int32 = 0
    let payloadType: Int32 = 5
    let isKeyFrameOnly = false
    let ret = self.rtcEngine?.sendMediaExtensionMsg(data, repeatCount: repeatCount, delay: delay, isKeyFrame: isKeyFrameOnly)
    // let ret = self.rtcEngine?.sendMediaExtensionMsgEx(data, repeatCount: repeatCount, delay: delay, isKeyFrame: isKeyFrameOnly, payloadType: payloadType)
    debugPrint("sendSEI: \(ret ?? -1)")
    return ret == 0
}

Windows

/* Specify the following parameters as needed. */
char * data = "xxxxx";
int length = strlen(data);
mAliRtcEngine->SendMediaExtensionMsg(data, length, 1,0,true);

Receive an SEI message

After a user subscribes to a video stream in a channel, they can receive SEI data if they have registered the appropriate callback.

API information

Callback

Description

onMediaExtensionMsgReceived

Triggered when an SEI message is received.

Parameters:

  • uid: The user ID of the sender.

  • payloadType: The type of the SEI message. Returns 5 for messages sent via sendMediaExtensionMsg. Returns the specific type for messages sent via sendMediaExtensionMsgEx.

  • message: The received SEI message data.

Sample code

Android

@Override
public void onMediaExtensionMsgReceived(String uid, int payloadType, byte[]message) {
    super.onMediaExtensionMsgReceived(uid,payloadType, message);

    handler.post(new Runnable() {
        @Override
        public void run() {
            // Process the message.
            String receivedMsg = new String(message);
            ToastHelper.showToast(SEIActivity.this, receivedMsg, Toast.LENGTH_SHORT);
            
        }
    });
}

iOS

extension SEIUsageMainVC: AliRtcEngineDelegate {
    
    // Callback for receiving an SEI message
    // receive SEI message
    func onMediaExtensionMsgReceived(_ uid: String, payloadType: Int32, message data: Data) {
        // Process the message.
        guard let message = String(data: data, encoding: .utf8) else {
            print("Failed to parse the message")
            return
        }
        self.showToast(message: "Received SEI: \(message), from uid: \(uid), payloadType: \(payloadType)")
    }
    // Other callbacks...

}

Windows

public:
virtual void OnMediaExtensionMsgReceived(const char* uid, const int8_t * message, uint32_t size) override {
    /* TODO: Write the processing logic as needed. */
}