SEI的发送和接收

ARTC SDK支持发送和接收SEI(Supplemental Enhancement Information)信息。当您需要将自定义消息从RTC系统传输到阿里云CDN直播或第三方直播平台时,可以使用此功能来实现。

功能简介

在视频编码领域,SEI(Supplemental Enhancement Information,补充增强信息)是视频编码标准(如 H.264/AVC 和 H.265/HEVC)中的一部分,用于传输与视频内容相关的附加信息。这些信息为接收端提供辅助功能,例如同步、错误恢复等,可用于视频画面的精准布局、远端歌词同步、直播答题等应用场景。

image

当开发者需要发送自定义消息时,推荐使用SEI。发送的自定义消息会被附加在视频数据流中,随着视频数据一起传输给房间里的其他用户。

  • 优点:

    • 实时性高,文本信息和媒体流同步。

    • 接收方没有人数限制,只要拉流就能收到。

  • 缺点:

    • 为了不影响视频流传输,每条消息目前最多可以传递 4K 字节。

示例代码

ARTC 提供了开源示例项目供您参考,您可以前往下载或查看其中的代码,示例代码请参考:

AndroidSEI发送和接收Android/ARTCExample/BasicUsage/src/main/java/com/aliyun/artc/api/basicusage/SEIUsage/SEIActivity.java

iOSSEI发送和接收iOS/ARTCExample/BasicUsage/SEIUsage/SEIUsageVC.swift

前提条件

在实现 SEI 功能之前,请确保满足以下要求:

功能实现

发送SEI消息

用户在启动视频推流后可以调用sendMediaExtensionMsg接口发送 SEI 数据。

接口信息

ARTC SDK 提供两个接口用于发送 SEI 消息。

API 接口

描述

sendMediaExtensionMsg

参数:

  • message:媒体扩展信息,长度限制为最大 4096 字节。建议使用JSON或纯字符串。

  • repeatCount:重复次数,代表消息冗余度,用于防止网络丢包导致的消息丢失,-1为无限传输。

  • delay:延迟,单位毫秒,调用API后,最短多少毫秒发送扩展信息。

  • isKeyFrame: 是否只有关键帧才使用扩展信息 true表示只有关键帧才附加扩展信息。

sendMediaExtensionMsgEx

相比于 sendMediaExtensionMsg,额外提供payloadType 参数用于设置 SEI 信息的类型,范围: [5, 100..254],当payloadType=5等同于使用sendMediaExtensionMsg 接口。

说明

同一时间只有一条媒体扩展信息在传输,多次调用sendMediaExtensionMsg,新调用的数据会覆盖前一次的数据。

调用示例

下面将以sendMediaExtensionMsgEx发送字符串消息为例演示 SEI 消息的发送。

Android

// 前提已经加入频道且推送视频流(默认自动推送)
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

// 发送SEI消息
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

/* 客户根据自己的业务填写下面的参数 */
char * data = "xxxxx";
int length = strlen(data);
mAliRtcEngine->SendMediaExtensionMsg(data, length, 1,0,true);

接收SEI消息

用户订阅房间内视频流后,如果已经注册 SEI 数据接收的回调,则可以接受当前房间的 SEI 数据。

接口信息

回调接口

描述

onMediaExtensionMsgReceived

SEI消息接收回调。

参数:

  • uid:发送该消息的用户 ID。

  • payloadType:发生时SEI信息的类型,sendMediaExtensionMsg返回5,sendMediaExtensionMsgEx发送的会返回具体类型。

  • message:收到的SEI消息。

调用示例

Android

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

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

iOS

extension SEIUsageMainVC: AliRtcEngineDelegate {
    
    // 收到SEI消息回调
    // receive SEI message
    func onMediaExtensionMsgReceived(_ uid: String, payloadType: Int32, message data: Data) {
        // 处理消息
        guard let message = String(data: data, encoding: .utf8) else {
            print("无法解析消息")
            return
        }
        self.showToast(message: "Received SEI: \(message), from uid: \(uid), payloadType: \(payloadType)")
    }
    // 其他回调 ...

}

Windows

public:
virtual void OnMediaExtensionMsgReceived(const char* uid, const int8_t * message, uint32_t size) override {
    /* TODO:客户根据自己的业务编写处理逻辑 */
}