媒体补充增强信息 SEI

更新时间: 2024/03/15 17:25:04

通过 NERTC SDK,您可以将包括音量信息在内的自定义信息作为 SEI 的一部分,封装在视频码流中,并将其发送至远端用户解码查看,可用于音画同步等场景。

功能描述

在音视频流媒体应用中,用户的消息分发通道和音视频或直播通道是分开的,通常情况下难以保证消息与视频数据的同步性。NERTC 支持将时间戳等自定义数据作为流媒体补充增强信息 (SEI Supplemental Enhancement Information)的一部分,通过流媒体通道将其与视频内容打包在一起,发送给远端用户,以此实现文本数据与音视频内容的精准同步的目的。

SEI 一般用于以下场景:

  • 在线教育场景,知识竞答等教育教学工具中需要老师的声音和需要作答的题目进行同步。
  • 电商购物场景,需要将商品信息和主播的声音及画面进行同步。
  • 泛娱乐场景的在线 KTV 玩法中,需要在合唱场景中歌词和声音及画面进行同步。

注意事项

  • sendSEIMsg 方法默认通过主流发送 SEI 信息。您也可以在调用 sendSEIMsg 时指定通过辅流发送 SEI,发送前需确保该通道为开启状态。
  • 纯音频场景的 SEI 帧通过 Fake Video 形式发送,不涉及视频流数据计费。

实现方法

音视频直播场景

本端:

  1. 本端加入房间后,通过 enableLocalVideo 开启视频流。
  2. 视频流成功开启后,调用 sendSEIMsg 接口发送 SEI 信息。

远端:

远端接收到本端发送的 SEI 信息后,触发 onRecvSEIMsg 回调。

纯音频通话场景

纯音频通话场景下,如果需要发送 SEI 信息到远端,SDK 会自动采取 Fake Video 方案。实现过程如下:

  1. 本端调用 sendSEIMsg 发送SEI信息。

    此时 SDK 内部会自动生成一个 Fake Video 的视频流,并携带 SEI 信息发送至远端。Fake Video 的分辨率为 16×16,画面为纯黑色。

  2. 远端接收到纯音频流下发送的 Fake Video 的信令通知,通过 kNERtcVideoProfileFake 字段判断该视频流为 Fake Video。

    • 若您使用的是 v4.6.0 及之前版本的 SDK,此时需要订阅该视频流,但无需展示该视频流画面。
    • 若您使用的是 v4.6.1 及之后版本的 SDK,不再需要关注该信令通知。
  3. 远端接收到本端发送的SEI信息后,触发 onRecvSEIMsg 回调。

当您在纯音频通话场景下,通过发送 Fake Video 的方式实现 SEI 帧发送后,如果需要开启视频流正常发送视频数据,可以通过 enableLocalVideo 开启视频流,并调用 sendSEIMsg 继续发送 SEI 信息。此时 SDK 会自动判断之前是否开启了 Fake Video,如果开启了就会关闭 Fake Video,然后再开启视频。

示例代码

//string到UTF8的格式转换
std::string StringToUTF8(const std::string &str) { 
    int nwLen = ::MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, NULL, 0);
    wchar_t *pwBuf = new wchar_t[nwLen + 1]; 
    ZeroMemory(pwBuf, nwLen * 2 + 2); 
    ::MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.length(), pwBuf, nwLen); 
    int nLen = ::WideCharToMultiByte(CP_UTF8, 0, pwBuf, -1, NULL, NULL, NULL, NULL); 
    char *pBuf = new char[nLen + 1]; 
    ZeroMemory(pBuf, nLen + 1); 
    ::WideCharToMultiByte(CP_UTF8, 0, pwBuf, nwLen, pBuf, nLen, NULL, NULL); 
 
    std::string strRet(pBuf); 
    delete[] pwBuf; 
    delete[] pBuf; 
    pwBuf = NULL; 
    pBuf = NULL; 
 
    return strRet; 
} 

// 首先获取到引擎对象 engine
nertc::IRtcEngineEx* nrtc_engine_ = ...

//subStream 为true表示辅流,false表示主流
NERtcStreamChannelType streamChannelType = subStream ? kNERtcStreamChannelTypeSubStream : kNERtcStreamChannelTypeMainStream; 

//SEI message,需要转换成UTF8格式
std::string strSEIInfo = StringToUTF8(strSEIMsg); 

//发送SEI消息
int res = nrtc_engine_->sendSEIMsg(reinterpret_cast<const char*>(strSEIInfo.c_str()), strSEIInfo.size()+1, streamChannelType); 

//消息打印
ShowLogInfo("ChannelType:%s, Send SEI msg:%s\n", subStream ? "kNERtcStreamChannelTypeSubStream" : "kNERtcStreamChannelTypeMainStream", strSEIInfo.c_str());
此文档是否对你有帮助?
有帮助
去反馈
  • 功能描述
  • 注意事项
  • 实现方法
  • 音视频直播场景
  • 纯音频通话场景
  • 示例代码