Real-Time Communication
Real-Time Communication in the Web, WebRTC in short, is a set of APIs allowing Web applications to send and receive streaming real-time video, audio and data to/from remote peers, without relying it through the centralized server. The server, implementing one of the specific signalling protocols, is needed for initial discovery and connection handshake, though. The APIs rely on the mediaStream
object - see Audio & Video Capture.
API glimpse
connection = new RTCPeerConnection(configuration)
- Creates a connection object that will be used to establish serverless connection between peers. The
configuration
may include the set oficeServers
that will be used for discovery and connection handshake. connection.addEventListener('icecandidate', listener)
- An event fired when the signalling server registers a remote peer with which the connection may be established.
connection.addStream(localMediaStream)
- Adds an existing local Media Stream (e.g. the local Web cam) to the remote peer connection.
connection.onaddstream = event => video.src = URL.createObjectURL(event.stream)
- Registers an
onaddstream
event handler that, if and when called, retrieves the remote party's Media Stream and plugs it into a <video> tagvideo
. connection.createOffer(options)
- Returns a
Promise
resolved when the remote peer connects to the connections and streams offered. connection.createAnswer(options)
- Accepts the connection offered by the remote peer. Returns a
Promise
resolved when the connection is established. dataChannel = connection.createDataChannel(label, configuration)
- Opens a data channel for the connection, allowing it to transmit arbitrary types of data.
dataChannel.send(data)
- Sends the data over the data channel to the remote peer.
dataChannel.addEventListener('message', listener)
- An event fired when the data has been received via the data channel.
Live Demo
-
function getUserMedia(options, successCallback, failureCallback) { var api = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia; if (api) { return api.bind(navigator)(options, successCallback, failureCallback); } } var pc1; var pc2; var theStreamB; function getStream() { if (!navigator.getUserMedia && !navigator.webkitGetUserMedia && !navigator.mozGetUserMedia && !navigator.msGetUserMedia) { alert('User Media API not supported.'); return; } var constraints = { video: true }; getUserMedia(constraints, function (stream) { addStreamToVideoTag(stream, 'localVideo'); // RTCPeerConnection is prefixed in Blink-based browsers. window.RTCPeerConnection = window.RTCPeerConnection || window.webkitRTCPeerConnection; pc1 = new RTCPeerConnection(null); pc1.addStream(stream); pc1.onicecandidate = event => { if (event.candidate == null) return; pc2.addIceCandidate(new RTCIceCandidate(event.candidate)); }; pc2 = new RTCPeerConnection(null); pc2.onaddstream = event => { theStreamB = event.stream; addStreamToVideoTag(event.stream, 'remoteVideo'); }; pc2.onicecandidate = event => { if (event.candidate == null) return; pc1.addIceCandidate(new RTCIceCandidate(event.candidate)); }; pc1.createOffer({offerToReceiveVideo: 1}) .then(desc => { pc1.setLocalDescription(desc); pc2.setRemoteDescription(desc); return pc2.createAnswer({offerToReceiveVideo: 1}); }) .then(desc => { pc1.setRemoteDescription(desc); pc2.setLocalDescription(desc); }) .catch(err => { console.error('createOffer()/createAnswer() failed ' + err); }); }, function (err) { alert('Error: ' + err); }); } function addStreamToVideoTag(stream, tag) { var mediaControl = document.getElementById(tag); if ('srcObject' in mediaControl) { mediaControl.srcObject = stream; } else if (navigator.mozGetUserMedia) { mediaControl.mozSrcObject = stream; } else { mediaControl.src = (window.URL || window.webkitURL).createObjectURL(stream); } }
-
<p><button onclick="getStream()">Grab video & start local peer connection</button></p> <p>Local video</p> <video autoplay id="localVideo" style="height:180px; width: 240px;" poster="https://image.freepik.com/free-icon/video-camera-symbol_318-40225.png"></video> <p>Remote video</p> <video autoplay id="remoteVideo" style="height:180px; width: 240px;"></video> <p><small>Demo by <a href="http://www.mcasas.tk/" target="_blank" rel="noopener">Miguel Casas-Sanchez</a>.</small></p>