WHIP/WHEP • publisher • subscriber •
This document describes how to use the Red5 Pro WebRTC SDK to start a broadcast session.
Grab the lastest Red5 Pro WebRTC SDK here.
The Red5 Pro WebRTC SDK is intended to communicate with a Red5 Pro Server, which allows for broadcasting and consuming live streams utilizing WebRTC and other protocols, including RTMP and HLS.
As such, you will need a distribution of the Red5 Pro Server running locally or accessible from the web, such as Amazon Web Services.
As of release 11.0.0
, the Red5 Pro WebRTC SDK supports WHIP to ingest/broadcast of streams!
Creating a WHIPClient
for publishing is very similar to RTCPublisher
(as described later in this document), but allows for connection to go through HTTP/S instead of relying on a WebSocket.
If you know the endpoint you are targeting and do not need any additional customization in the broadcast stream, establishing a WHIP broadcast is as simple as:
const whipEndpoint = 'https://yourred5pro.com/live/whip/endpoint/stream1'
const publisher = new WHIPClient(
whipEndpoint,
document.querySelector('#red5pro-publisher')
)
publisher.on('*', (event) => console.log(event))
However, if you want more control over the configuration of a broadcast stream, establish a WHIPClient
similar to how you would have established an RTCPublisher
in previous releases to 11.0.0
:
const config = {
host: 'yourred5pro.com',
streamName: 'stream1',
...more,
}
const publisher = await new WHIPClient().init(config)
publisher.on('*', (event) => console.log(event))
await publisher.publish()
Read more from our WHIP/WHEP documentation.
The Red5 Pro WebRTC SDK WebRTC Publisher solution utilizes WebSockets and WebRTC support in modern browsers.
It is highly recommended to include adapter.js when targeting the WebRTC publisher.
WebRTC-based Publishers need to be delivered over HTTPS due to browser security restrictions related to
getUserMedia
which accesses the Camera and Microphone of your machine. Read more here.
Property | Required | Default | Description |
---|---|---|---|
protocol | [x] | wss |
The protocol for the WebSocket communication; ws or wss . |
port | [x] | 443 |
The port on the host that the WebSocket listens on; 5080 or 443 (insecure or secure, respectively). |
app | [x] | live |
The webapp name that the WebSocket is listening on. |
streamMode | [x] | live |
The mode to broadcast; live , record or append . |
keyFramerate | [-] | 3000 |
The framerate (in milliseconds) between sending key frames in broadcast. |
host | [x] | None | The IP or address that the WebSocket server resides on. |
streamName | [x] | None | The name of the stream to subscribe to. |
mediaElementId | [-] | red5pro-publisher |
The target video or audio element id attribute which will display the preview media. |
rtcConfiguration | [-] | None | The RTCConfiguration to user in setting up RTCPeerConnection . RTCConfiguration |
iceServers | [x] | None (Test) | The list of ICE servers to use in requesting a Peer Connection. Marked for Deprecation. Favor rtcConfiguration . |
iceTransport | [-] | UDP |
The transport type to use in ICE negotiation. Either UDP or TCP |
bandwidth | [-] | {audio: 56, video: 512} |
A configuration object to setup bandwidth setting in publisher. |
connectionParams | [-] | undefined |
An object of connection parameters to send to the server upon connection request. |
mediaConstraints | [x] | see below | A object representative of the Media Constraints to use while setting up the Media (via getUserMedia internally to the SDK). |
onGetUserMedia | [-] | see below | An override method for performing your own getUserMedia request. |
signalingSocketOnly | [-] | true |
Flag to indicate whether the WebSocket should only be used for signaling while establishing a connection. Afterward, all data between client and server will be sent over an RTCDataChannel . |
dataChannelConfiguration | [-] | {name: "red5pro"} |
An object used in configuring a n RTCDataChannel . Only used when signalingSocketOnly is defined as true |
forceVP8 | [-] | false |
Flag to force VP8 as the encoder for the outgoing stream. Marked for Deprecation. |
videoEncoding | [-] | undefined |
PublishVideoEncoder enum: VP8 |
audioEncoding | [-] | undefined |
PublishAudioEncoder enum. |
endpoint | [-] | undefined |
The full URL of the endpoint to stream to. This is primarily used in Stream Manager 2.0 integration for clients. Refer to the Stream Manager 2.0 Section |
import { RTCPublisher } from 'red5pro-webrtc-sdk'
const start = async () => {
try {
const publisher = new RTCPublisher()
await publisher.init({
protocol: 'ws',
port: 5080,
host: 'localhost',
app: 'live',
streamName: 'mystream',
rtcConfiguration: {
iceServers: [{urls: 'stun:stun2.l.google.com:19302'}],
iceCandidatePoolSize: 2,
bundlePolicy: 'max-bundle'
}, // See https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/RTCPeerConnection#RTCConfiguration_dictionary
streamMode: 'live',
mediaElementId: 'red5pro-publisher',
bandwidth: {
audio: 56,
video: 512
},
mediaConstraints: {
audio: true,
video: {
width: {
exact: 640
},
height: {
exact: 480
},
frameRate: {
min: 8
max: 24
}
}
}
})
await publisher.publish()
} catch (e) {
// An error occured in establishing a broadcast session.
}
}
index.html:
<!doctype html>
<html>
<head>
<!-- Recommended shim for cross-browser WebRTC support. -->
<script src="https://webrtchacks.github.io/adapter/adapter-latest.js"></script>
</head>
<body>
<!-- `autoplay` will immediately show preview video. `muted` will mute the audio to avoid feedback noise. -->
<video id="red5pro-publisher" autoplay muted></video>
<!-- Exposes `red5prosdk` on the window global. -->
<script src="lib/red5pro/red5pro-sdk.min.js"></script>
<!-- Example script below. -->
<script src="main.js"></script>
</body>
</html>
main.js:
(function (red5prosdk) {
// Create a new instance of the WebRTC publisher.
var publisher = new red5prosdk.RTCPublisher();
// Initialize
publisher.init({
protocol: 'ws',
port: 5080,
host: 'localhost',
app: 'live',
streamName: 'mystream',
rtcConfiguration: {
iceServers: [{urls: 'stun:stun2.l.google.com:19302'}],
iceCandidatePoolSize: 2,
bundlePolicy: 'max-bundle'
}, // See https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/RTCPeerConnection#RTCConfiguration_dictionary
streamMode: 'live',
mediaElementId: 'red5pro-publisher',
bandwidth: {
audio: 56,
video: 512
},
mediaConstraints: {
audio: true,
video: {
width: {
exact: 640
},
height: {
exact: 480
},
frameRate: {
min: 8
max: 24
}
}
}
})
.then(function() {
// Invoke the publish action.
return publisher.publish();
})
.catch(function(error) {
// A fault occurred while trying to initialize and publish the stream.
console.error(error);
});
})(window.red5prosdk);
Because this example demonstrates publishing to a Red5 Pro Server located on localhost
, we set the protocol to ws
and port to 5080
, which are the default values for non-secure socket connection. If you are publishing to a remote Red5 Pro Server, it will need to be delivered securely - upon which you can rely on the default property values of wss
and 443
, respectively.
The video
or audio
element has the autoplay
and muted
attributes defined. This will ensure:
autoplay
: Once access to your Camera and Microphone are available, it will show a preview of your broadcast to yourself.muted
: You don't get noise feedback when you start publishing, since it will mute your playback volume. Your publishing session will still have audio.
The Red5 Pro WebRTC SDK will handle the getUserMedia
requirements internally to set up your Camera and/or Microphone for a broadcast. As such, you can provide the Media Constraint object to be used.
The mediaConstraints
default configuration property for WebRTC Publishers.
{
audio: true,
video:{
width: {
exact: 640
},
height: {
exact: 480
}
}
}
Internally, the Red5 Pro WebRTC SDK will use the provided Media Constraint to test if the resolutions requested are supported by the browser. If not, it will find the nearest supported lower neighbor based on the originally provided area dimension(s) of the resolutions.
For example, if you provide the following for mediaConstraints
:
{
audio: true,
video:{
width: {
exact: 1280
},
height: {
exact: 720
}
}
}
... and your browser does not support 720p(HD), most likely the nearest neighbor supported by the browser will be either 800x600(SVGA) or 640x480(VGA), and either of those resolutions will be used in your broadcast.
If you would like to bypass the internal determination of resolution, you can use the
onGetUserMedia
override of the configuration properties.
The onGetUserMedia
method - when defined on the configuration provide to a WebRTC-based Publisher - will override the internal call to getUserMedia
in the Red5 Pro WebRTC SDK.
You can provide your own logic on how getUserMedia
is invoked and a Media Stream attained by setting the onGetUserMedia
attribute to a method that conforms to the following guidelines:
- No input arguments are provided to
onGetUserMedia
. - It is expected that a
Promise
object is returned. - A
MediaStream
object must be provided in the resolve of thePromise
. - The error provided in the reject of the
Promise
is optional, but recommended as aString
.
An example of providing onGetUserMedia
as a configuration:
{
host: "localhost",
protocol: "ws",
port: 5080,
streamName: "mystream",
rtcConfiguration: {
iceServers: [{urls: 'stun:stun2.l.google.com:19302'}],
iceCandidatePoolSize: 2,
bundlePolicy: 'max-bundle'
}, // See https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/RTCPeerConnection#RTCConfiguration_dictionary
onGetUserMedia: function () {
return navigator.mediaDevices.getUserMedia({
audio: true,
video: {
width: {
max: 1920,
ideal: 1280,
min: 640
},
width: {
max: 1080,
ideal: 720,
min: 360
}
}
})
}
}
The
navigator.mediaDevices.getUserMedia
API returns aPromise
, but you can define any other method, as long as it returns aPromise
and provides aMediaStream
on resolve.
Be aware that overriding onGetUserMedia
you are losing the logic from the Red5 Pro WebRTC SDK that attempts to pick the optimal resolution supported by your browser. Use with descretion.
To read more about
getUserMedia
please read the following document from Mozilla Developer Network: https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia
This section describes the events dispatched from the Publisher of the Red5 Pro WebRTC SDK.
The Publisher(s) included in the SDK are event emitters that have a basic API to subscribing and unsubscribing to events either by name or by wildcard.
To subscribe to all events from a publisher:
function handlePublisherEvent (event) {
// The name of the event:
const { type } = event
// The dispatching publisher instance:
const { publisher } = event
// Optional data releated to the event (not available on all events):
const { data } = event
}
const publisher = new RTCPublisher()
publisher.on('*', handlePublisherEvent)
The
*
type assignment is considered a "Wildcard" subscription - all events being issued by the publisher instance will invoke the assign event handler.
To unsubscribe to all events from a publisher after assinging an event handler:
publisher.off('*', handlePublisherEvent);
The following sections of this document describe the event types that can also be listened to directly, instead of using the *
wildcard.
The following events are common across all Publisher implementations from the Red5 Pro WebRTC SDK. They can be accessed from the global red5prosdk
object from the PublisherEventTypes
attribute.
Access | Name | Meaning |
---|---|---|
CONNECT_SUCCESS | 'Connect.Success' | When the publisher has established a required remote connection, such as to a WebSocket or RTMP-based server. |
CONNECT_FAILURE | 'Connect.Failure' | When the publisher has failed to establish a required remote connection for streaming. |
PUBLISH_START | 'Publish.Start' | When the publisher has started a broadcast stream. |
PUBLISH_FAIL | 'Publish.Fail' | When the publisher has failed to start a broadcast stream. |
PUBLISH_INVALID_NAME | 'Publish.InvalidName' | When the publisher is rejected from starting a broadcast stream because the streamName provided is already in use. |
UNPUBLISH_SUCCESS | 'Unpublish.Success' | When the publisher has successfully closed an active broadcast stream. |
PUBLISH_METADATA | 'Publish.Metadata' | When the publisher receives metadata from the server. |
PUBLISH_STATUS | 'Publish.Status' | When a status event of the publisher has been receieved from the server. |
PUBLISH_AVAILABLE | 'Publish.Available' | When the publisher stream has become available on the origin server to be consumed. This will follow the connection setup and Publish.Start event. |
PUBLISH_INSUFFICIENT_BANDWIDTH | 'Publish.InsufficientBW' | When the current broadcast session is experiencing insufficient bandwidth conditions. |
PUBLISH_RECOVERING_BANDWIDTH | 'Publish.RecoveringBW' | Then the current broadcast has updated information related to bandwidth condition recovery. |
PUBLISH_SUFFICIENT_BANDWIDTH | 'Publish.SufficientBW' | When the current broadcast session has sufficient bandwidth conditions from previously experiencing network issues. |
CONNECTION_CLOSED | 'Publisher.Connection.Closed' | Invoked when a close to the connection is detected. |
DIMENSION_CHANGE | 'Publisher.Video.DimensionChange' | Notification when the Camera resolution has been set or change. |
The following events are specific to the RTCPublisher
implementation and accessible on the global red5prosdk
object from the RTCPublisherEventTypes
attribute. These events are dispatched during the lifecycle of thre trickle ICE functionality required to start a broadcast:
Access | Name | Meaning |
---|---|---|
CONSTRAINTS_ACCEPTED | 'WebRTC.MediaConstraints.Accepted' | When constraints have been accepted from the internal request to getUserMedia . The data property of this event contains a requested object detailing the constraints used in the getUserMedia request and an accepted object which is the current constraint settings for the media. |
CONSTRAINTS_REJECTED | 'WebRTC.MediaConstraints.Rejected' | Then constraints have been rejected from the internal request to getUserMedia . The data property of this event contains a constraints object detailing the constraints that were used and rejected from getUserMedia . |
MEDIA_STREAM_AVAILABLE | 'WebRTC.MediaStream.Available' | When the negotation process has returned a MediaStream object to use. |
PEER_CONNECTION_AVAILABLE | 'WebRTC.PeerConnection.Available' | When the negotation process has produced a valid PeerConnection . |
OFFER_START | 'WebRTC.Offer.Start' | When the publisher requests to send an offer using a SessionDescription on the PeerConnection . |
OFFER_END | 'WebRTC.Offer.End' | When the publisher has received an answer from the SDP offer on the PeerConnection . |
ICE_TRICKLE_COMPLETE | 'WebRTC.IceTrickle.Complete' | When the negotaiton process (a.k.a. trickle) has completed and the publisher will attempt at opening a broadcast stream. |
DATA_CHANNEL_AVAILABLE | 'WebRTC.DataChannel.Available' | the underlying RTCDataChannel is available when signalingSocketOnly configuration is used. |
DATA_CHANNEL_OPEN | 'WebRTC.DataChannel.Open' | When the underlying RTCDataChannel is opened when signalingSocketOnly configuration is used. |
DATA_CHANNEL_CLOSE | 'WebRTC.DataChannel.Close' | When the underlying RTCDataChannel is closed when signalingSocketOnly configuration is used. |
DATA_CHANNEL_ERROR | 'WebRTC.DataChannel.Error' | When an error has occurred within the underlying RTCDataChannel when signalingSocketOnly configuration is used. |
DATA_CHANNEL_MESSAGE | 'WebRTC.DataChannel.Message' | When a message has been delivered over the underlying RTCDataChannel when signalingSocketOnly configuration is used. |
UNSUPPORTED_FEATURE | 'WebRTC.Unsupported.Feature' | Notification that a feature attempting to use in WebRTC is not supported or available in the current browser that the SDK is being employed. e.g., Insertable Streams. |
TRANSFORM_ERROR | 'WebRTC.Transform.Error' | An error has occurred while trying to apply transform to a media track. See Insertable Streams |
This section provides information that relate to the release of Stream Manager 2.0 and its integration with WHIP/WHEP clients.
The Stream Manager 2.0 simplifies the proxying of web clients to Origin and Edge nodes. As such, an initialization configuration property called endpoint
was added to the WebRTC SDK. This endpoint
value should be the full URL path to the proxy endpoint on the Stream Manager as is used as such:
const host = 'my-deployment'
const streamName = 'mystream'
const nodeGroup = 'my-node-group'
const endpoint = `https://${host}/as/v1/proxy/ws/publish/live/${streamName}`
const config = {
endpoint,
streamName,
connectionParams: {
nodeGroup
},
// additional configurations
}
const publisher = await new RTCPublisher().init(config)
publisher.on('*', (event) => console.log(event))
await publisher.publish()
Note: The requirement of a
nodeGroup
connection parameter that is the target nodegroup within your Stream Manager deployment on which you want to proxy the Publisher and Subscriber client(s).