Skip to content

Instantly share code, notes, and snippets.

@mondain
Last active October 31, 2024 15:02
Show Gist options
  • Save mondain/a6d232abbf333c52dc90685e737497ea to your computer and use it in GitHub Desktop.
Save mondain/a6d232abbf333c52dc90685e737497ea to your computer and use it in GitHub Desktop.
Old - WebRTC client API for Red5 Pro

Client API

Defines communication between a browser client using Javascript and a server listening on a WebSocket. Requests and responses are communicated using JSON.

Author

Paul Gregoire

Prerequisites

  • Chrome or Firefox

Note: IE or Microsoft Edge use ORTC or don't support WebRTC at all. Safari requires a plugin at the time of writing and has not been tested.

** USE AT YOUR OWN RISK - THIS IS NOT OFFICIAL AND IS QUITE OLD **

ICE/STUN/TURN

If using local embedded turnserver

    if (window.moz) {
        ice.push({
            urls: 'stun:' + location.hostname + ':3478'
        });
        ice.push({
            urls: 'turn:' + location.hostname + ':3478?transport=udp', credential: 'webrtc', username: 'webrtc'
        });
    } else {
        ice.push({
            url: 'stun:' + location.hostname + ':3478'
        });
        ice.push({
            url: 'turn:' + location.hostname + ':3478?transport=udp',
            credential: 'webrtc',
            username: 'webrtc'
        });
    }

Using public STUN servers:

    if (window.moz) {
        // mozilla STUN
        ice.push({
            urls: 'stun:stun.services.mozilla.com:3478'
        });
    } else {
        // google STUN (1...4)
        ice.push({
            url: 'stun:stun2.l.google.com:19302'
        });
    }

Public STUN list: https://gist.github.com/mondain/b0ec1cf5f60ae726202e

Methods

The API methods are designed to handle requests and provide responses made by a browser using JSON formatting. To be aware of: when a client (WebSocket client) is connected successfully, the WebSocket connection is added to the PingService to keep the connection alive.

isAvailable

Returns whether or not a specified stream is available. A value of true is returned if the stream already exists.

In the signature below, a Flash media originated stream is identified with 'flash' and a stream originated from a WebRTC publisher is designated by 'webrtc'.

JSON signature:

  • isAvailable - the stream name
  • type - the type of stream being requested; only 'webrtc' and 'flash' are recognized
  • bundle - whether or not bundling of audio, video, and rtcp message bundling are requested (bundle is default)

request:

  {"isAvailable":"publisher1","type":"webrtc","bundle":true}

response:

  {"isAvailable": true}

publish

Publishes the given WebRTC stream. This method is only aplicable to WebRTC streams.

JSON signature:

  • publish - the stream name

request:

  {"publish":"publisher1"}

response:

  {
    "data":{
      "type":"status","message":"publisher1 starting"
    }
  }

error response: if flash publish attempted

  { 
    "data":{
      "type":"error","message":"Publish flash stream disallowed: flpublisher1"
    }
  }

error response: if publish or session start failed

  { 
    "data":{
      "type":"error","message":"Session start failed for publisher1"
    }
  }

unpublish

Stops publishing the given WebRTC stream. This method is only aplicable to WebRTC streams.

JSON signature:

  • unpublish - the stream name

request:

  {"unpublish":"publisher1"}

response:

  {
    "data":{
      "type":"status","message":"publisher1 stopping"
    }
  }

error response: if flash publish attempted

  { 
    "data":{
      "type":"error","message":"An exception occured stopping flpublisher1",
      "detail":"error / exception details"
    }
  }

error response: if session lookup failed

  { 
    "data":{
      "type":"error","message":"Session for publisher1 was not found"
    }
  }

subscribe

Subscribes to the given Flash stream. This method is only aplicable to WebRTC (playback) streams.

JSON signature:

  • subscribe - the stream name to subscribe to
  • requestId - a unique id which will identify this client

request:

  {"subscribe":"flpublisher1","requestId":"subscriberId"}

response:

  {
    "data":{
      "type":"status","message":"flpublisher1 starting"
    }
  }

error response: if session start failed

  {"data":{
      "type":"error","message":"Session start failed for flpublisher1"
    }
  }

error response: if an attempting to subscribe to a WebRTC stream

  {"data":{
      "type":"error","message":"Subscribe to RTC stream disallowed: publisher1"
    }
  }

error response: if an exception occurred

  {"data":{
      "type":"error","message":"An exception occured starting flpublisher1",
      "detail":"error / exception details"
    }
  }

error response: if session lookup failed

  {"data":{
      "type":"error","message":"Session for publisher1 was not found"
    }
  }

unsubscribe

Stops subscribing to the given Flash stream. This method is only aplicable to WebRTC (playback) streams.

JSON signature:

  • unsubscribe - the stream name
  • requestId - a unique id which will identify this client

request:

  {"unsubscribe":"flpublisher1","requestId":"subscriberId"}

response:

  {
    "data":{
      "type":"status","message":"flpublisher1 stopping"
    }
  }

error response: if an exception occurred

  {"data":{
      "type":"error","message":"An exception occured stopping flpublisher1",
      "detail":"error / exception details"
    }
  }

error response: if session lookup failed

  {"data":{
      "type":"error","message":"Session for flpublisher1 was not found"
    }
  }

requestOffer

Requests and offer SDP for the given stream.

JSON signature:

  • requestOffer - the stream name
  • requestId - a unique id which will identify this client
  • audioEncoding - requested audio encoding (Opus, PCMU, PCMA, Speex, or NONE)
  • videoEncoding - requested video encoding (VP8, H264, or NONE)

To request an audio-only stream, the videoEncoding must be set to NONE or the default server codec will be applied. Similarly if a video-only stream is expected, the audioEncoding must be set to NONE.

Request using browser and server defaults

request:

  {"requestOffer":"publisher1","requestId":"subscriberId"}

There are several possible responses for this request.

response: if the stream is being created

  {"requestId":"subscriberId",
    "data":{
      "type":"status","message":"Stream is registered"
    }
  }

response: if the stream is being configured and offer sdp isn't ready

  {"requestId":"subscriberId",
    "data":{
      "type":"status","message":"Request is processing"
    }
  }

response: returned when the offer sdp is ready

  {
    "data":{
      "type":"offer","userid":"server",
      "sdp":"v=0\r\n
        o=publisher1 8399569967621 1 IN IP4 127.0.0.1\r\n
        s=-\r\n
        t=0 0\r\n
        a=group:BUNDLE audio video\r\n
        a=msid-semantic: WMS\r\n
        m=audio 5000 UDP/TLS/RTP/SAVPF 111\r\n
        c=IN IP4 67.167.168.182\r\n
        a=rtcp:5001 IN IP4 67.167.168.182\r\n
        a=ice-ufrag:YGbiUqPwHvuY4+yZ\r\n
        a=ice-pwd:WHemqb0cgvGQztgJubZxoc7E\r\n
        a=fingerprint:sha-256 50:33:8C:84:1D:BD:DD:50:65:F2:99:69:4E:85:FA:76:B8:0B:70:AE:BA:A2:9C:86:AD:60:71:94:18:43:15:94\r\n
        a=setup:actpass\r\n
        a=mid:audio\r\n
        a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\r\n
        a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\r\n
        a=sendonly\r\n
        a=rtpmap:111 opus/48000/2\r\n
        a=fmtp:111 minptime=10\r\n
        a=maxptime:60\r\n
        a=ssrc:1433503178 cname:publisher1\r\n
        a=ssrc:1433503178 msid:QdBgXVtqO2YlCAeDNVo5cIDOydGZUSK5PFgq 9e739d4d-8e3d-42df-9532-f012f6328ffc\r\n
        a=ssrc:1433503178 mslabel:QdBgXVtqO2YlCAeDNVo5cIDOydGZUSK5PFgq\r\n
        a=ssrc:1433503178 label:9e739d4d-8e3d-42df-9532-f012f6328ffc\r\n
        m=video 5002 UDP/TLS/RTP/SAVPF 100\r\n
        c=IN IP4 67.167.168.182\r\n
        a=rtcp:5003 IN IP4 67.167.168.182\r\n
        a=ice-ufrag:YGbiUqPwHvuY4+yZ\r\n
        a=ice-pwd:WHemqb0cgvGQztgJubZxoc7E\r\n
        a=fingerprint:sha-256 50:33:8C:84:1D:BD:DD:50:65:F2:99:69:4E:85:FA:76:B8:0B:70:AE:BA:A2:9C:86:AD:60:71:94:18:43:15:94\r\n
        a=setup:actpass\r\n
        a=mid:video\r\n
        a=extmap:2 urn:ietf:params:rtp-hdrext:toffset\r\n
        a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\r\n
        a=extmap:4 urn:3gpp:video-orientation\r\n
        a=sendonly\r\n
        a=rtpmap:100 VP8/90000\r\n
        a=rtcp-fb:100 ccm fir\r\n
        a=rtcp-fb:100 nack\r\n
        a=rtcp-fb:100 nack pli\r\n     
        a=ssrc:2574130012 cname:publisher1\r\n
        a=ssrc:2574130012 msid:QdBgXVtqO2YlCAeDNVo5cIDOydGZUSK5PFgq 0d1d888a-6768-4859-988c-c90067536603\r\n
        a=ssrc:2574130012 mslabel:QdBgXVtqO2YlCAeDNVo5cIDOydGZUSK5PFgq\r\n
        a=ssrc:2574130012 label:0d1d888a-6768-4859-988c-c90067536603\r\n"
    }
  }

error response:

  {
    "data":{
      "type":"error","message":"some error text here"
    }
  }

Request specifying H264 encoding

request:

  {"requestOffer":"publisher1","requestId":"subscriberId","videoEncoding":"H264"}

Example request using the Pro SDK (line 8484 in red5pro-sdk.js)

{
    key: 'requestOffer',
    value: function requestOffer(streamName, subscriptionId) {
      Logger.debug('[requestoffer]');
      // message on socket returns -> onSDPOffer
      this._socketHelper.post({
        requestOffer: streamName,
        requestId: subscriptionId,
        videoEncoding: 'H264'
      });
    }
}

Console output

[R5ProSubscriptionSocket] debug: [websocket-post]: {
  "requestOffer": "publisher1",
  "requestId": "subscriber-6ffe",
  "videoEncoding": "H264"
}

handleOffer

Sends an offer SDP to the server for the current peer instance.

JSON signature:

  • handleOffer - the stream name
  • data - container for the sdp object entry
  • sdp - the offer sdp object

request:

  {"handleOffer":"publisher1",
    "data":{
      "sdp":sdp
    }
  }

response:

  {
    "data":{
      "type":"answer","sdp":" answer sdp here "
    }
  }

response: if the offer sdp is accepted and after the answer sdp is sent, ICE candidate(s) will be returned

  {
    "data":{
      "type":"candidate",
      "candidate":{
        "sdpMLineIndex":1, "sdpMid":"video", "mid":"video", "candidate":"candidate:1 2 udp 2130706430 192.168.86.102 5021 typ host"
      }
    }
  }

error response:

  {
    "data":{
      "type":"error","message":"SDP was not accepted: some error text here"
    }
  }

handleAnswer

Sends an answer SDP to the server for the current peer instance.

JSON signature:

  • handleAnswer - the stream name
  • requestId - a unique id which will identify this client
  • data - container for the sdp object entry
  • sdp - the answer sdp object

request:

  {"handleAnswer":"publisher1","requestId":"subscriberId",
    "data":{
      "sdp":sdp
    }
  }

response: if the answer sdp is accepted, ICE candidate(s) will be returned

  {
    "data":{
      "type":"candidate",
      "candidate":{
        "sdpMLineIndex":1, "sdpMid":"video", "mid":"video", "candidate":"candidate:1 2 udp 2130706430 192.168.86.102 5021 typ host"
      }
    }
  }

error response:

  {
    "data":{
      "type":"error","message":"SDP was not accepted: some error text here"
    }
  }

handleCandidate

Utilized for sending an ICE candidate to the server for the current peer instance.

JSON signature:

  • handleAnswer - the stream name
  • requestId - a unique id which will identify this client
  • data - container for the candidate object entry
  • candidate - the ICE candidate object

request:

  {"handleCandidate":"publisher1","requestId":"subscriberId",
    "data":{
      "candidate":candidate
    }
  }

response: N/A

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment