This document defines a set of ECMAScript APIs in WebIDL to allow media to be sent and received from another browser or device implementing the appropriate set of real-time protocols. However, unlike the current WebRTC 1.0 APIs, ORTC does not mandate a media signaling protocol or format. As a result, ORTC does not utilize Session Description Protocol (SDP) within its APIs, nor does it mandate support for the Offer/Answer state machine. Instead, ORTC focuses on "connections" and "tracks" being carried over those connections.
Object RealTime Communications (ORTC) provides a powerful API for the development of WebRTC based applications. ORTC does not mandate a media signaling protocol or format (as the current WebRTC 1.0 does by mandating SDP Offer/Answer). Instead, ORTC focuses on "sender", "receiver" and "transport" objects, which have "capabilities" describing what they are capable of doing, as well as "parameters" which define what they are configured to do. "Tracks" and "data channels" are sent over the transports, between senders and receivers.
This specification defines several objects: RTCDtlsTransport (Section 2), RTCIceTransport (Section 3), RTCIceListener (Section 4), RTCRtpSender (Section 5), RTCRtpReceiver (Section 6), RTCDTMFTrack (Section 8), RTCDataChannel (Section 9), and RTCSctpTransport (Section 10); RTP dictionaries are described in Section 7.
In a Javascript application utilizing the ORTC API, the relationship between the application and the objects, as well as between the objects themselves is shown below:
The EventHandler
interface represents a callback used for event handlers as defined in
[[!HTML5]].
The concepts queue a task and fires a simple event are defined in [[!HTML5]].
The terms event, event handlers and event handler event types are defined in [[!HTML5]].
The terms MediaStream, MediaStreamTrack, Constraints, and Consumer are defined in [[!GETUSERMEDIA]].
The RTCDtlsTransport includes information relating to Datagram Transport Layer Security (DTLS) transport.
An RTCDtlsTransport instance is associated to an RTCRtpSender or an RTCRtpReceiver.
A RTCDtlsTransport instance is optionally constructed from an RTCIceTransport object or an RTCIceTransport is automatically constructed.
The RTCIceTransport includes information relating to Interactive Connectivity Establishment (ICE).
An RTCIceTransport instance is associated to a transport object (such as RTCDtlsTransport), and provides RTC related methods to it.
An RTCIceTransport instance is constructed from an RTCIceRole and either an RTCIceListener or an RTCIceOptions object.
// Assume we already have a way to signal. This is an example
// of how to offer ICE and DTLS parameters and ICE candidates and
// get back ICE and DTLS parameters and ICE candidates, and start
// both ICE and DTLS.
function initiate(signaller) {
var iceOptions = ...;
var ice = new RTCIceTransport(RTCIceRole.controlling, iceOptions);
var dtls = new RTCDtlsTransport(ice);
// ... get tracks and RTP objects from other example
signaller.sendInitiate({
"ice": ice.
getLocalParameters(),
"dtls": dtls.
getLocalParameters(),
// ... include RTP info from other example
}, function(remote) {
ice.setRemoteParameters(remote.ice);
dtls.start(remote.dtls);
// ... start RTP senders and receivers from other example
});
ice.oncandidate = function(candidate) {
signaller.sendLocalCandidate(candidate);
}
signaller.onRemoteCandidate = function(candidate) {
ice.addRemoteCandidate(candidate);
}
ice.start();
}
// Assume we already have a way to signal and remote info is
// signalled to us. This is an example of how to answer with ICE and DTLS
// and DTLS parameters and ICE candidates and start both ICE and DTLS.
//
function accept(signaller, remote) {
var iceOptions = ...;
var ice = new RTCIceTransport(iceOptions);
var dtls = new RTCDtlsTransport(ice);
// ... get tracks and RTP objects from other example
ice.oncandidate = function(candidate) {
signaller.sendLocalCandidate(candidate);
}
signaller.onRemoteCandidate = function(candidate) {
ice.addRemoteCandidate(candidate);
}
signaller.sendAccept({
"ice": ice.
getLocalParameters(),
"dtls": ice.
getLocalParameters()
// ... include RTP info from other example
});
ice.start(remote.ice);
dtls.start(remote.dtls);
// ... start RTP senders and receivers from other example
}
The non-normative ICE state transitions are:
The RTCIceOptions object includes information relating to ICE configuration.
The RTCIceServer is used to provide STUN or TURN server configuration. In network topologies with multiple layers of NATs, it is desirable to have a STUN server between every layer of NATs in addition to the TURN servers to minimize the peer to peer network latency.
An example of an array of RTCIceServer objects:
[ { urls: "stun:stun1.example.net } , { urls:"turn:turn.example.org", username: "user", credential:"myPassword"} ]
The RTCIceCandidate object includes information relating to an ICE candidate.
{
foundation: "abcd1234",
priority: 1694498815,
connectionAddress: "192.0.2.33",
connectionPort: 10000,
type: "host"
};
The RTCIceCandidateType includes the type of ICE candidate.
The RTCIceListener enables an endpoint to construct multiple RTCIceTransport objects from a set of local ICE parameters, enabling usage scenarios such as parallel forking.
An RTCIceListener instance is associated to an RTCIceTransport.
An RTCIceListener instance is optionally constructed from an RTCIceOptions object, or an RTCIceListener is automatically constructed.
The RTCIceOptions instance.
var iceOptions = ...;
var iceListener = new RTCIceListener(iceOptions);
sendInitiate(iceListener.getLocalParameters(), function(response) {
// We may get N responses
var ice = new RTCIceTransport(RTCIceRole.controlling, iceListener);
var ice.setRemoteParameters(response.iceParameters);
ice.start();
// ... setup DTLS, RTP, SCTP, etc.
});
iceListener.oncandidate = sendLocalCandidate;
iceListener.start();
The RTCRtpSender includes information relating to the RTP sender.
An RTCRtpSender instance is associated to a sending MediaStreamTrack and provides RTC related methods to it.
A RTCRtpSender instance is constructed from an MediaStreamTrack object and associated to an RTCDtlsTransport.
The associated MediaStreamTrack instance.
The associated RTCDtlsTransport instance.
Obtain the capabilities of the RTCRtpSender.
Create parameters based on the MediaStreamTrack and the capabilities specified in RTCRtpCapabilities.
Filter parameters based on the RTCRtpCapabilities.
Media is controlled by the given "parameters". The sender starts sending when the send() is called and stopped when the stop() is called.
Stops sending the track on the wire. Stop is final like MediaStreamTrack
The RTCRtpReceiver includes information relating to the RTP receiver.
An RTCRtpReceiver instance is associated to a sending MediaStreamTrack and provides RTC related methods to it.
A RTCRtpReceiver instance is constructed from an MediaStreamTrack object and associated to an RTCDtlsTransport.
The associated MediaStreamTrack instance.
The associated RTCDtlsTransport instance.
Obtain the capabilities of the RTCRtpReceiver.
Filter parameters based on the RTCRtpCapabilities.
Media is controlled by the given "parameters". The receiver starts receiving when the receive() is called and stopped when the stop() is called.
Stops receiving the track on the wire. Stop is final like MediaStreamTrack
// Assume we already have a way to signal, a transport
// (RTCDtlsTransport), and audio and video tracks. This is an example
// of how to offer them and get back an answer with audio and
// video tracks, and begin sending and receiving them.
function initiate(signaller, transport, audioTrack, videoTrack) {
var audioSender = new RTCRtpSender(audioTrack, transport);
var videoSender = new RTCRtpSender(videoTrack, transport);
var audioReceiver = new RTCRtpReceiver(transport);
var videoReceiver = new RTCRtpReceiver(transport);
var sendAudioParams = RTCRtpSender.createParameters(audioTrack);
var sendVideoParams = RTCRtpSender.createParameters(videoTrack);
signaller.offerTracks({
// The initiator offers parameters it wants to send with,
// and the capabilities it has for receiving.
"rtpCaps": RTCRtpReceiver.getCapabilities(),
"audio": sendAudioParams,
"video": sendVideoParams
}, function(answer) {
// The responder answers with parameters it wants to send with
// and the capabilities it has for receiving.
audioSendParams = RTCRtpSender.filterParameters(
sendAudioParams, answer.rtpCaps);
videoSendParams = RTCRtpSender.filterParameters(
sendVideoParams, answer.rtpCaps
var audioRecvParams = RTCRtpSender.filterParameters(
answer.audio);
var videoRecvParams = RTCRtpSender.filterParameters(
answer.video);
audioSender.send(audioSendParams);
videoSender.send(videoSendParams)
audioReceiver.receive(audioRecvParams);
videoReceiver.receive(videoRecvParams);
// Now we can render/play
// audioReceiver.track and videoReceiver.track.
});
}
// Assume we already have a way to signal, a transport
// (RTCDtlsTransport), and audio and video tracks. This is an example
// of how to answer an offer with audio and video tracks, and begin
// sending and receiving them.
function accept(
signaller, remote, transport, audioTrack, videoTrack) {
var audioSender = new RTCRtpSender(audioTrack, transport);
var videoSender = new RTCRtpSender(videoTrack, transport);
var audioReceiver = new RTCRtpReceiver(transport);
var videoReceiver = new RTCRtpReceiver(transport);
var audioSendParams = RTCRtpSender.createParameters(
audioTrack, remote.rtpCaps);
var videoSendParams = RTCRtpSender.createParameters(
videoTrack, remote.rtpCaps);
var audioRecvParams = RTCRtpSender.filterParameters(
remote.audio);
var videoRecvParams = RTCRtpSender.filterParameters(
remote.video);
audioSender.send(audioSendParams);
videoSender.send(videoSendParams)
audioReceiver.receive(audioRecvParams);
videoReceiver.receive(videoRecvParams);
signaller.answerTracks({
"rtpCaps": RTCRtpReceiver.getCapabilities(),
"audio": audioSender.parameters(),
"video": videoSender.parameters()
});
// Now we can render/play
// audioReceiver.track and videoReceiver.track.
}
An RTCDtmfSender instance allows sending DTMF tones to/from the remote peer.
An RTCDtmfSender object is constructed from an RTCRtpSender object.
The RTCRtpSender instance
The ontonechange event handler uses the RTCDTMFToneChangeEvent interface to return the character for each tone as it is played out.
The toneBuffer attribute returns a list of the tones remaining to be played out.
The duration attribute returns the current tone duration value in milliseconds. This value will be the value last set via the insertDTMF() method, or the default value of 70 ms if insertDTMF() was called without specifying the duration.
The interToneGap attribute returns the current value of the between-tone gap. This value will be the value last set via the insertDTMF() method, or the default value of 70 ms if insertDTMF() was called without specifying the interToneGap.
The tonechange event uses the RTCDTMFToneChangeEvent interface.
Firing an tonechange event named e with a DOMString tone means that an event with the name e, which does not bubble (except where otherwise stated) and is not cancelable (except where otherwise stated), and which uses the RTCDTMFToneChangeEvent interface with the tone attribute set to tone, MUST be created and dispatched at the given target.
The tone attribute contains the character for the tone that has just begun playout (see insertDTMF()). If the value is the empty string, it indicates that the previous tone has completed playback.
The tone parameter is treated as a series of characters. The characters 0 through 9, A through D, #, and * generate the associated DTMF tones. The characters a to d are equivalent to A to D. The character ',' indicates a delay of 2 seconds before processing the next character in the tones parameter. Unrecognized characters are ignored.
This section needs reworking. An RTCDataChannel class instance allows sending data messages to/from the remote peer.
Method used for sending data to the remote peer.
Parameter | Type | Nullable | Optional | Description |
data | Object | no | no |
This event handler, of event handler event type data, must be fired to allow a developer's JavaScript to receive data from a remote peer.
Event Argument | Description |
Object data | The received remote data. |
The RTCSctpTransport includes information relating to Stream Control Transmission Protocol (SCTP) transport.
An RTCSctpTransport is associated to a RTCDataChannel.
An RTCSctpTransport instance is constructed from an RTCDtlsTransport object.
function initiate(signaller) {
var dtls = ...; // See ICE/DTLS example.
var sctp = new RTCSctpTransport(dtls);
signaller.sendInitiate({
// ... include ICE/DTLS info from other example.
sctpCapabilities: RTCSctpTransport.getCapabilities()
}, function(remote) {
sctp.start(remote.sctpCapabilities);
});
var channel = sctp.createDataChannel({...});
channel.send("foo");
}
function accept(signaller, remote) {
var dtls = ...; // See ICE/DTLS example.
signaller.sendAccept({
// ... include ICE/DTLS info from other example.
"sctpCapabilities": RTCSctpTransport.getCapabilities()
});
var sctp = new RTCSctpTransport(dtls);
sctp.start(remote.sctpCapabilties);
// Assume in-band signalling. We could also easily add
// RTCDataChannelParameters into the out-of-band signalling
// And call .createDataChannel here with negotiated: true.
sctp.ondatachannel = function(channel) {
channel.onmessage = function(message) {
if (message == "foo") {
channel.send("bar");
}
}
}
This specification determines that RTCP packets must be multiplexed with the RTP packets as defined by [[!RFC5761]].
This example code provides a basic audio and video session between two browsers.
This section will be removed before publication.