All Products
Search
Document Center

ApsaraVideo Live:WebRTC signaling specifications for GRTN access

Last Updated:Jun 08, 2026

Real-Time Streaming (RTS) delivers ultra-low latency live streaming through Alibaba Cloud CDN nodes using WebRTC signaling. Learn the WebRTC signaling specifications for accessing Global Realtime Transport Network (GRTN). Intended for developers with WebRTC experience.

Background information

TCP-based live streams have a latency of 3 to 6 seconds. To reduce latency, ApsaraVideo Live provides the RTS feature for UDP-based streaming. RTS delivers millisecond-latency, HD live streaming that supports tens of millions of concurrent requests. Beyond the RTS SDKs from ApsaraVideo Live, you can use your own clients to push or pull streams from CDN nodes through WebRTC-compatible signaling. ApsaraVideo Live provides global CDN nodes and optimized scheduling to operate the RTS service at scale.

GRTN performs well under poor network conditions.

Prerequisites

Signaling process

The following figure shows the signaling process.

001

Signaling process

  1. The client sends a request with an SDP offer.

    1. Create an RTCPeerConnection object, specify whether to receive or send audio and video, and create an SDP offer.

      // Specify whether to receive or send audio and video signals.
      { offerToReceiveVideo: true, offerToReceiveAudio: true }
    2. Send a stream pulling request to ApsaraVideo Live using HTTPS POST. The request body is a JSON string. For more information about the request parameters, see the Definition of the RTS signaling protocol section of this topic.

      • The version parameter specifies the RTS signaling protocol version. Set to 2.

      • The sdk_version parameter specifies the RTS SDK version. Set as needed.

    3. Send the request to ApsaraVideo Live using the signaling URL via POST. Include the source URL in the JSON request body.

      POST /app/streamname?auth=xxx HTTP/1.1
      Host: domain
      Connection: keep-alive
      Content-Length: 2205
      Content-Type: application/json
      Note

      A signaling URL matches the source URL except for the protocol header:

      • Signaling URL: https://domain/app/streamname?auth=xxx

      • Source URL: artc://domain/app/streamname?auth=xxx

  2. The server returns a response with an SDP answer.

    After ApsaraVideo Live verifies the request, it generates an SDP answer and returns a response with the live streaming node information. For more information about the response parameters, see the Definition of the RTS signaling protocol section of this topic.

  3. The client initiates Interactive Connectivity Establishment (ICE).

    1. After receiving the SDP answer, set the session description on the RTCPeerConnection object.

      peerConnection.setRemoteDescription(new RTCSessionDescription(answer.jsep));
    2. Initiate ICE and DTLS encryption through the RTCPeerConnection object. After the signaling channel is established, the client pulls streams from ApsaraVideo Live using standard WebRTC playback.

  4. The client initiates a disconnection.

    The client sends a DTLS alert to stop stream ingest or playback.

    Disconnect

Sample code for the HTML5 player

// 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);
}
                

Definition of the RTS signaling protocol

The RTS signaling protocol uses a short-lived HTTPS connection with JSON messages. Sample code:

{
    "version":2,
    "sdk_version":"0.0.1",
    "mode":"live",
    "pull_streams":[
        {
            "url":"artc://your.domain.com/live/testname",
            "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 Omitted content"
    }
}

Playback

  • Protocol description about playback

    Table 1. Request parameters

    Parameter

    Type

    Required

    Description

    mode

    string

    Yes

    The stream mode. Set to live.

    version

    int

    Yes

    The protocol version. Set to 2.

    push_stream

    string

    No

    The ingest URL.

    pull_streams

    []object

    No

    The streams to pull. Supports multiple streams. See the following table for attributes.

    sdk_version

    string

    No

    The SDK version.

    jsep.type

    string

    Yes

    The SDP message type. Set to offer.

    jsep.sdp

    string

    Yes

    The SDP message content.

    Table 2. Attributes of the pull_stream parameter

    Attribute

    Type

    Required

    Description

    url

    string

    Yes

    The source URL that starts with artc://.

    amsid

    []string

    Yes

    The audio stream MSID. Set to rts audio.

    vmsid

    []string

    Yes

    The video stream MSID. Set to rts video.

    Table 3. Response parameters

    Parameter

    Type

    Required

    Description

    code

    int

    Yes

    The HTTP status code. Returns 200 on success. See the Status codes table.

    trace_id

    string

    Yes

    The request GUID, generated by Alibaba Cloud CDN for troubleshooting. Retain this value.

    jsep.type

    string

    Yes

    The SDP message type. Returns answer.

    jsep.sdp

    string

    Yes

    The SDP message content generated when CDN nodes pull streams from the origin.

  • Playback request example

    Request:
    {
        "version":2,
        "sdk_version":"0.0.1",
        "mode":"live",
        "pull_streams":[
            {
                "url":"artc://your.domain.com/live/testname",
                "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 Omitted content"
        }
    }
    
    Response:
    {
        "trace_id":"2_1591173296_101.227.0.169_702080732320_dec327eb6eed0e0b07b349c8a5653eca",
        "code":200,
        "jsep":{
            "type":"answer",
            "sdp":"v=0\r\no=- 1591173291 2 IN IP4 127.0.0.1\n\r Omitted content"
        }
    }

    sps-pps-idr-in-keyframe: To prevent screen flicker during browser playback under poor network conditions, modify the SDP as follows.

    After creating an SDP offer for HTML5 playback and before calling setLocalDescription, find the H.264 video attribute line:

    a=fmtp:127 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f

    Append sps-pps-idr-in-keyframe=1:

    a=fmtp:127 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f;sps-pps-idr-in-keyframe=1

    GRTN enables this feature in response.

  • Error handling

    A valid request returns HTTP 200. Error responses include code and message in the JSON body:

    Response:
    {
       "code": 200, // A value of 200 indicates that the request is successful. For more information about status codes, see the "Status codes" section.
       "message": "success" // The returned message.
    }

    Table 4. Response parameters

    Parameter

    Type

    Description

    code

    int

    The HTTP status code. See the Status codes table.

    message

    string

    The returned message.

    Table 5. Status codes

    Status code

    Description

    403

    Authentication failed.

    404

    Stream does not exist.

    611

    Client must play the stream over TCP.

    302

    Client must redirect the request to a new address.

Stream ingest

  • Protocol description about stream ingest

    Table 6. Request parameters

    Parameter

    Type

    Required

    Description

    mode

    string

    Yes

    The stream mode. Set to live.

    version

    int

    Yes

    The protocol version. Set to 2.

    push_stream

    string

    No

    The ingest URL.

    sdk_version

    string

    No

    The SDK version.

    jsep.type

    string

    Yes

    The SDP message type. Set to offer.

    jsep.sdp

    string

    Yes

    The SDP message content.

    Table 7. Response parameters

    Parameter

    Type

    Required

    Description

    code

    int

    Yes

    The HTTP status code. Returns 200 on success. See the Status codes table.

    trace_id

    string

    Yes

    The request GUID, generated by Alibaba Cloud CDN for troubleshooting. Retain this value.

    jsep.type

    string

    Yes

    The SDP message type. Returns answer.

    jsep.sdp

    string

    Yes

    The SDP message content generated when CDN nodes pull streams from the origin.

  • Stream ingest request example

    Request:
    {
        "version":2,
        "sdk_version":"0.0.1",
        "mode":"rtc",
        "push_stream":"artc://host/app/name",
        "jsep":{
            "type":"offer",
            "sdp":"v=0\r\no=- 1385856200224536561 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE 0 1 2\r\na=extmap-allow-mixed\r\na=msid-semantic: WMS rts\r\nm=audio 9 UDP/TLS/RTP/SAVPF 111 63 103 104 9 0 8 106 105 13 110 112 113 126\r\nc=IN IP4 0.0.0.0\r\na=rtcp:9 IN IP4 0.0.0.0\r\na=ice-ufrag:iQyM\r\na=ice-pwd:D3GXKCcUGvW9djaAozff5ppT\r\na=ice-options:trickle\r\na=fingerprint:sha-256 20:50:72:9B:A2:C0:D8:50:AD:D0:EF:A7:62:8F:EF:C3:AB:86:D5:B6:3E:17:22:69:79:5B:CE:E8:42:33:B5:E4\r\na=setup:actpass\r\na=mid:0\r\na=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\r\na=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\r\na=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01\r\na=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid\r\na=sendrecv\r\na=msid:rts audio\r\na=rtcp-mux\r\na=rtpmap:111 opus/48000/2\r\na=rtcp-fb:111 transport-cc\r\na=rtcp-fb:111 nack\r\na=fmtp:111 minptime=10;useinbandfec=1\r\na=rtpmap:63 red/48000/2\r\na=fmtp:63 111/111\r\na=rtpmap:103 ISAC/16000\r\na=rtpmap:104 ISAC/32000\r\na=rtpmap:9 G722/8000\r\na=rtpmap:0 PCMU/8000\r\na=rtpmap:8 PCMA/8000\r\na=rtpmap:106 CN/32000\r\na=rtpmap:105 CN/16000\r\na=rtpmap:13 CN/8000\r\na=rtpmap:110 telephone-event/48000\r\na=rtpmap:112 telephone-event/32000\r\na=rtpmap:113 telephone-event/16000\r\na=rtpmap:126 telephone-event/8000\r\na=ssrc:3411287802 cname:s4eR7OuKnnPL0vKS\r\na=ssrc:3411287802 msid:rts audio\r\na=ssrc:3411287802 mslabel:rts\r\na=ssrc:3411287802 label:audio\r\nm=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99 100 101 127 121 125 107 108 109 124 120 123 119 35 36 41 42 114 115 116 117 118\r\nc=IN IP4 0.0.0.0\r\na=rtcp:9 IN IP4 0.0.0.0\r\na=ice-ufrag:iQyM\r\na=ice-pwd:D3GXKCcUGvW9djaAozff5ppT\r\na=ice-options:trickle\r\na=fingerprint:sha-256 20:50:72:9B:A2:C0:D8:50:AD:D0:EF:A7:62:8F:EF:C3:AB:86:D5:B6:3E:17:22:69:79:5B:CE:E8:42:33:B5:E4\r\na=setup:actpass\r\na=mid:1\r\na=extmap:14 urn:ietf:params:rtp-hdrext:toffset\r\na=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\r\na=extmap:13 urn:3gpp:video-orientation\r\na=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01\r\na=extmap:5 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay\r\na=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/video-content-type\r\na=extmap:7 http://www.webrtc.org/experiments/rtp-hdrext/video-timing\r\na=extmap:8 http://www.webrtc.org/experiments/rtp-hdrext/color-space\r\na=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid\r\na=extmap:10 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id\r\na=extmap:11 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id\r\na=sendrecv\r\na=msid:rts video\r\na=rtcp-mux\r\na=rtcp-rsize\r\na=rtpmap:96 VP8/90000\r\na=rtcp-fb:96 goog-remb\r\na=rtcp-fb:96 transport-cc\r\na=rtcp-fb:96 ccm fir\r\na=rtcp-fb:96 nack\r\na=rtcp-fb:96 nack pli\r\na=rtpmap:97 rtx/90000\r\na=fmtp:97 apt=96\r\na=rtpmap:98 VP9/90000\r\na=rtcp-fb:98 goog-remb\r\na=rtcp-fb:98 transport-cc\r\na=rtcp-fb:98 ccm fir\r\na=rtcp-fb:98 nack\r\na=rtcp-fb:98 nack pli\r\na=fmtp:98 profile-id=0\r\na=rtpmap:99 rtx/90000\r\na=fmtp:99 apt=98\r\na=rtpmap:100 VP9/90000\r\na=rtcp-fb:100 goog-remb\r\na=rtcp-fb:100 transport-cc\r\na=rtcp-fb:100 ccm fir\r\na=rtcp-fb:100 nack\r\na=rtcp-fb:100 nack pli\r\na=fmtp:100 profile-id=2\r\na=rtpmap:101 rtx/90000\r\na=fmtp:101 apt=100\r\na=rtpmap:127 H264/90000\r\na=rtcp-fb:127 goog-remb\r\na=rtcp-fb:127 transport-cc\r\na=rtcp-fb:127 ccm fir\r\na=rtcp-fb:127 nack\r\na=rtcp-fb:127 nack pli\r\na=fmtp:127 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f\r\na=rtpmap:121 rtx/90000\r\na=fmtp:121 apt=127\r\na=rtpmap:125 H264/90000\r\na=rtcp-fb:125 goog-remb\r\na=rtcp-fb:125 transport-cc\r\na=rtcp-fb:125 ccm fir\r\na=rtcp-fb:125 nack\r\na=rtcp-fb:125 nack pli\r\na=fmtp:125 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42001f\r\na=rtpmap:107 rtx/90000\r\na=fmtp:107 apt=125\r\na=rtpmap:108 H264/90000\r\na=rtcp-fb:108 goog-remb\r\na=rtcp-fb:108 transport-cc\r\na=rtcp-fb:108 ccm fir\r\na=rtcp-fb:108 nack\r\na=rtcp-fb:108 nack pli\r\na=fmtp:108 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f\r\na=rtpmap:109 rtx/90000\r\na=fmtp:109 apt=108\r\na=rtpmap:124 H264/90000\r\na=rtcp-fb:124 goog-remb\r\na=rtcp-fb:124 transport-cc\r\na=rtcp-fb:124 ccm fir\r\na=rtcp-fb:124 nack\r\na=rtcp-fb:124 nack pli\r\na=fmtp:124 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42e01f\r\na=rtpmap:120 rtx/90000\r\na=fmtp:120 apt=124\r\na=rtpmap:123 H264/90000\r\na=rtcp-fb:123 goog-remb\r\na=rtcp-fb:123 transport-cc\r\na=rtcp-fb:123 ccm fir\r\na=rtcp-fb:123 nack\r\na=rtcp-fb:123 nack pli\r\na=fmtp:123 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=4d001f\r\na=rtpmap:119 rtx/90000\r\na=fmtp:119 apt=123\r\na=rtpmap:35 H264/90000\r\na=rtcp-fb:35 goog-remb\r\na=rtcp-fb:35 transport-cc\r\na=rtcp-fb:35 ccm fir\r\na=rtcp-fb:35 nack\r\na=rtcp-fb:35 nack pli\r\na=fmtp:35 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=4d001f\r\na=rtpmap:36 rtx/90000\r\na=fmtp:36 apt=35\r\na=rtpmap:41 AV1/90000\r\na=rtcp-fb:41 goog-remb\r\na=rtcp-fb:41 transport-cc\r\na=rtcp-fb:41 ccm fir\r\na=rtcp-fb:41 nack\r\na=rtcp-fb:41 nack pli\r\na=rtpmap:42 rtx/90000\r\na=fmtp:42 apt=41\r\na=rtpmap:114 H264/90000\r\na=rtcp-fb:114 goog-remb\r\na=rtcp-fb:114 transport-cc\r\na=rtcp-fb:114 ccm fir\r\na=rtcp-fb:114 nack\r\na=rtcp-fb:114 nack pli\r\na=fmtp:114 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=64001f\r\na=rtpmap:115 rtx/90000\r\na=fmtp:115 apt=114\r\na=rtpmap:116 red/90000\r\na=rtpmap:117 rtx/90000\r\na=fmtp:117 apt=116\r\na=rtpmap:118 ulpfec/90000\r\na=ssrc-group:FID 4075787827 945566690\r\na=ssrc:4075787827 cname:s4eR7OuKnnPL0vKS\r\na=ssrc:4075787827 msid:rts video\r\na=ssrc:4075787827 mslabel:rts\r\na=ssrc:4075787827 label:video\r\na=ssrc:945566690 cname:s4eR7OuKnnPL0vKS\r\na=ssrc:945566690 msid:rts video\r\na=ssrc:945566690 mslabel:rts\r\na=ssrc:945566690 label:video\r\nm=application 9 UDP/DTLS/SCTP webrtc-datachannel\r\nc=IN IP4 0.0.0.0\r\na=ice-ufrag:iQyM\r\na=ice-pwd:D3GXKCcUGvW9djaAozff5ppT\r\na=ice-options:trickle\r\na=fingerprint:sha-256 20:50:72:9B:A2:C0:D8:50:AD:D0:EF:A7:62:8F:EF:C3:AB:86:D5:B6:3E:17:22:69:79:5B:CE:E8:42:33:B5:E4\r\na=setup:actpass\r\na=mid:2\r\na=sctp-port:5000\r\na=max-message-size:262144\r\n"
        }
    }
    
    Response:
    {
        "trace_id":"...",
        "code":200,
        "jsep":{
            "type":"answer",
            "sdp":"v=0\r\no=- 1657264764 2 IN IP4 127.0.0.1 Omitted content"
        }
    }
                        

    In the preceding signaling request, push_stream specifies the ingest URL, similar to RTMP stream ingest. Note the following:

    • You must specify an MSID in the SDP message. GRTN uses the MSID to identify media streams.

    • Codec negotiation is not supported. Each MSID allows only one codec. GRTN does not negotiate codecs. Supported codecs: AAC, Opus, H.264, and H.265.

    • Sample code for audioaudio1audio2

    • videovideo1video2

  • Error handling

    A valid request returns HTTP 200. Error responses include code and message in the JSON body:

    Response:
    {
       "code": 200, // A value of 200 indicates that the request is successful. For more information about status codes, see the "Status codes" section.
       "message": "success" // The returned message.
    }

    Table 8. Response parameters

    Parameter

    Type

    Description

    code

    int

    The HTTP status code. See the Status codes table.

    message

    string

    The returned message.

    Table 9. Status codes

    Status code

    Description

    403

    Authentication failed.

    611

    Client must play the stream over TCP.

    302

    Client must redirect the request to a new address.

Enhanced SDP negotiation

SDP negotiation follows RFC 4566 with RTS-specific extensions for live streaming. RTS extends standard SDP semantics to support more video and audio container formats and communication protocols, resolving WebRTC limitations such as Opus-only audio and no B-frame support.

AAC supported for stream ingest and pulling

RTS can transmit audio in various AAC formats over RTMP. The AAC formats include AAC-LC, HE-AACv1, and HE-AACv2.

RTS transmits AAC audio using the LATM container format. LATM determines whether audio encoding information is transmitted in-band (per frame) or out-of-band (once) based on the muxconfigPresent parameter in the AudioMuxElement array. This makes LATM more flexible than ADTS. When AudioSpecificConfig remains unchanged, StreamMuxConfig can be transmitted in the SDP message first.

  • AAC supported for stream ingest

    Carry the AAC audio format information in the SDP offer. Add config=StreamMuxConfig (obtained from AudioSpecificConfig of the ingested stream) in the fmtp attribute to pass the AudioSpecificConfig to the server for AAC header generation.

    SDP offer

    a=rtpmap:125 MP4A-LATM/48000/2
    a=fmtp:125 config=4000232000;cpresent=0;object=2;profile-level-id=1
  • AAC supported for stream pulling

    During signaling, RTS parses the audio encoding information and returns the result in the negotiation response:

    SDP offer

    SDP answer

    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

    If SBR-enabled=1 is in the fmtp attribute, the format is HE-AAC. If both SBR-enabled=1 and PS-enabled=1 are present, the format is HE-AACv2. You can also add config=StreamMuxConfig in the fmtp attribute, where StreamMuxConfig (from AudioSpecificConfig) contains detailed encoding parameters.

    002

H.265 supported for stream ingest and pulling

  • H.265 supported for stream ingest

    Carry the H.265 video format information in the SDP offer.

    SDP offer:

    a=rtpmap:102 H265/90000 
  • H.265 supported for stream pulling

    During stream pulling signaling, the server detects the source stream video codec (H.264 or H.265) and negotiates accordingly.

    SDP offer

    SDP answer

    a=rtpmap:102 H265/90000
    a=rtpmap:122 H265/90000
    a=fmtp:122

B-frames supported for stream ingest and pulling

  • B-frames supported for stream ingest

    B-frames are supported in the ingested stream.

  • B-frames supported for stream pulling

    During signaling, the client can add a field in the SDP offer to specify B-frame decoding support. Adding BFrame-enabled = 1 in the fmtp attribute enables B-frame decoding, where RTP timestamp = PTS means the client decodes frames in increasing sequence number order. If B-frames are not supported, RTS transcodes the source stream to remove them.

    For B-frame decoding, "RTP timestamp = PTS" is used and the client decodes frames by increasing sequence number.

    The server can also return a composition timestamp (CTS), allowing the client to calculate the decoding timestamp (DTS) as: PTS = DTS + CTS. If the SDP offer contains a=extmap:{$id} uri:webrtc:rtc:rtp-hdrext:video:CompositionTime, RTS adds extension identifier = {$id} to the first RTP packet of each video frame. The id value is determined by the client's SDP offer.

    RTS lets the client control B-frame decoding and CTS return independently.

The following figures show partial SDP offer content and packet capture during stream pulling:

Partial content of the SDP offer004

Signaling request carrying metadata supported for stream ingest

RTMP ingested streams carry metadata for callbacks and stream pulling clients. Since WebRTC signaling does not include metadata, RTS allows metadata in the signaling request body to generate metadata in the ingested stream.

Add the metadata field to the body of the signaling request for the ingested stream:

{
    "version":2,
    "sdk_version":"0.0.1",
    "mode":"rtc",
    "push_stream":"artc://host/app/name",
    "jsep":{
        "type":"offer",
        "sdp":"..."
    },
    "metadata":{
        "framerate":"20",
        "platform":"iOS",
        "audiodatarate":"200",
        "videodatarate":"2000"
    }
}

MSID mechanism

The MSID mechanism is defined in The Msid Mechanism. Note the following:Msid