RTS超低延时直播是以WebRTC信令交互方式为基础,借助阿里云直播节点的全球覆盖及优秀调度算法能力,实现功能。通过阅读本文,您可以了解RTS信令协议的详细信息。本文适合具有WebRTC基础的开发人员阅读。

信令交互流程

信令交互图如下所示:

001

信令交互流程

  1. 客户端发送offer请求。
    1. 客户端本地创建RTCPeerConnection,设置接收音视频属性Stream Direction,并创建offer SDP。
      // 开启音视频, recvonly or sendonly
      { offerToReceiveVideo: true, offerToReceiveAudio: true }
    2. 客户端向直播服务发送拉流请求,通过HTTPS POST协议方式将JSON格式的请求信息发送至直播服务。协议格式请参见信令协议定义
      说明
      • version字段为协议版本,当前版本固定为2。
      • sdk_version字段为SDK版本,您可以自定义该字段。
    3. 生成协议内容后,通过POST方式将信令地址给直播服务完成信令交互,在请求的JSON包体中包含要拉取的流地址。
      POST /app/streamname?auth=xxx HTTP/1.1
      Host: domain
      Connection: keep-alive
      Content-Length: 2205
      Content-Type: application/json
      说明 信令地址与流地址基本一致,协议头不同,如下所示:
      • 信令地址:https://domain/app/streamname?auth=xxx
      • 流地址:artc://domain/app/streamname?auth=xxx
  2. 服务端SDP Answer响应。

    直播服务端校验安全性后生成SDP Answer, 节点信息封装在响应包体中返回给客户端。协议格式请参见信令协议定义

  3. 客户端ICE建联。
    1. 客户端收到SDP Answer响应后,设置到RTCPeerConnection中。
      peerConnection.setRemoteDescription(new RTCSessionDescription(answer.jsep));
    2. RTCPeerConnection启动ICE建连流程以及后续的DTLS流程,媒体通道建立成功后可以获取到直播服务输出的媒体流,实现WebRTC标准接入拉流播放。
  4. 断开连接。

    客户端需要断开连接停止推流或播放,使用DTLS的Alert消息表达。

    断开连接

H5 Demo示例

// Create peer connection and local offer sdp.
peerConnection = new RTCPeerConnection();
peerConnection.onicecandidate = iceCandidateCallback;
peerConnection.ontrack = remoteStreamCallback;
peerConnection.createOffer({ offerToReceiveVideo: true, offerToReceiveAudio: true })
      .then(signaling_pull).catch(errorHandler);


// CDN live post pull stream request.
function signaling_pull(offer_sdp) {
  console.log('local offer sdp', offer_sdp);

  peerConnection.setLocalDescription(offer_sdp).then(function() {
    // Get pull stream url.
    var stream_url = $("#stream_url").val();
    console.log("stream url:" , stream_url);

    // Add sdk and protocol versions.
    var protocol_version = 2;
    var sdk_version = "0.0.1";

    $.ajax({url: stream_url, data: JSON.stringify({
          mode: "live",
          version: protocol_version,
          sdk_version: sdk_version,
          jsep:description,
      }),
      type: "post",
      success:function(result){
          var signal = JSON.parse(result);
          peerConnection.setRemoteDescription(new RTCSessionDescription(signal.jsep)).then(function() {
              console.log("get remote answer sdp: ", signal.jsep.sdp);
          }).catch(errorHandler);
      }});
  }).catch(errorHandler);
}

信令协议定义

RTS信令协议通道为HTTPS(短链接),格式为JSON。协议详情如下所示:

请求示例

Request:
{
    "version":2,
    "sdk_version":"0.0.1",
    "mode":"live",
    "pull_streams":[
        {
            "url":"artc://demo.aliyundoc.com/liveApp****/liveStream****",
            "amsid":[
                "rts audio"
            ],
            "vmsid":[
                "rts video"
            ]
        }
    ],
    "jsep":{
        "type":"offer",
        "sdp":"v=0\n\ro=- 6839248142876176651 2 IN IP4 127.0.0.1\n\rs=-\n\r以下省略"
    }
}
参数 类型 是否必选 描述
mode string 模式,取值:live。
version int 协议版本号,取值:2。
push_stream string 推流URL。
pull_streams []object 拉流对象,支持多个拉流。详情请参见下表。
sdk_version string SDK版本号。
jsep.type string SDP类型,取值:offer。
jsep.sdp string SDP描述。
表 1. pull_stream参数
字段 类型 是否必填 描述
url string 拉流URL,例如:artc://<拉流地址>
amsid []string 拉流音频msid,直播场景取值rts audio
vmsid []string 拉流视频msid,直播场景取值rts video

相应示例

Response:
{
    "trace_id":"2_1591173296_101.227.XX.XX_702080732320_dec327eb6eed0e0b07b349c8a565****",
    "code":200,
    "jsep":{
        "type":"answer",
        "sdp":"v=0\r\no=- 1591173291 2 IN IP4 127.0.0.1\n\r 以下省略"
    }
}
字段 类型 是否必需 描述
code int 返回码。正确返回200,错误码请参见下表。
trace_id string 全局唯一请求标识ID。由CDN生成,请尽量做好保存,用于对请求进行定位和问题排查。
jsep.type string SDP类型,取值:answer。
jsep.sdp string 直播CDN回源拉流生成SDP。
表 2. 错误码描述
错误码 描述
403 鉴权失败。
404 流不存在。
611 需要客户端强制降级到TCP播放。
302 需要客户端向新的服务地址发起信令请求。

增强的SDP

在信令交互中,SDP用来描述媒体信息。通用的SDP协商是基于RFC 4566展开的,阿里云RTS在其基础上扩展出了更多丰富的语义,兼容直播行业的特点,支持更多的音视频封装和通信协议,突破了WebRTC仅支持音频OPUS、不支持视频B帧等的窘境,满足了如今流媒体业界日益扩大的协议族。

支持AAC音频

RTS支持传输任何能在RTMP中传输的AAC格式的音频,包括AAC-LC、HE-AACv1和HE-AACv2。AAC格式详情请参见ISO IEC 14496-3

RTS支持以LATM格式进行AAC音频传输。LATM可根据传输中的音频是否自带音频编码信息来决定是带内(每个音频都发)或带外(只发一次)音频编码信息,即由Audio Mux Element中的muxconfigPresent决定AudioSpecificConfig是带内或带外传输。因此,LATM相对ADTS更灵活,其AudioSpecificConfig如果保持不变,则可以通过SDP会话先传输StreamMuxConfig(AudioSpecificConfig)信息。

在信令交互阶段,RTS会解析推流侧音频编码信息,并在协商响应中返回对应的信息。如下所示:

offer SDP answer SDP
AAC-LC HE-AACv1 HE-AACv2
m=audio 9 UDP/RTP/AVPF 120 96 
a=rtpmap:120 MP4A-LATM/44100/2
AudioSpecificConfig = 0x1210
AudioSpecificConfig = 2b920800
AudioSpecificConfig = eb8a0800
a=rtpmap:120 MP4A-LATM/44100/2
a=fmtp:120 cpresent=0;profile-level-id=1;object=2;config=400024203fc0
a=rtpmap:120 MP4A-LATM/44100/2 
a=fmtp:120 cpresent=0;profile-level-id=1;object=2;config=4000572410003fc0;SBR-enabled=1
a=rtpmap:120 MP4A-LATM/44100/2 
a=fmtp:120 cpresent=0;object=2;profile-level-id=1;config=4001d71410003fc0;PS-enabled=1;SBR-enabled=1

此处,通过在answer SDP音频MP4A-LATM的fmtp中添加SBR-enabled=1表示AAC-HE,添加SBR-enabled=1PS-enabled=1表示HE-AACv2。由于从AAC-LC到HE-AACv2有技术递进关系,因此在表示fmtp时,递进地增加SBR、PS的标识来表示不同的AAC格式。此外,在fmtp中添加config=StreamMuxConfig,其由推流AudioSpecificConfig信息组装而来,具体地描述了音频编码的各种参数信息,客户端可以各取所需。

002

更多信息,请参见AAC-LC / HE-AACv1 / HE-AACv2 Encoder Parameters

支持H.265视频

RTS会解析推流侧视频编码信息(H.264、H.265),在answer SDP中根据推流侧实际的编码方式,返回H.264H.265

编码类型 offer SDP answer SDP
H.265
a=rtpmap:102 H265/90000
a=rtpmap:122 H265/90000
a=fmtp:122

支持B帧视频

在信令交互阶段,客户端可以在offer SDP中增加字段标识其是否支持解析B帧视频。例如:在视频fmtp中增加BFrame-enabled = 1标识以表示支持B帧,此时,RTP timestamp = PTS,sequence number递增,正常情况下客户端按照sequence number解码即可。如果不支持B帧,RTS可以对视频源流进行转码,去掉B帧。

此外,RTS还支持额外返回CTS扩展头以支持需要精确计算DTS的客户端(PTS=DTS+CTS),如果offer SDP中带有a=extmap:{$id} uri:webrtc:rtc:rtp-hdrext:video:CompositionTime,RTS会在每一帧视频的第一个RTP包上增加extension identifier = {$id}的CTS扩展头,id由offer SDP来决定。offer SDP片段及拉流抓包示例如下所示:

Offer SDP片段004

RTS给予客户端充分的表达能力,将决定权下放给用户,让其决定是否接受视频带B帧,以及是否需要额外的CTS信息,构建更通用的通信能力。

MSID相关概念

关于MSID详细信息,请参见The Msid Mechanism