Skip to content

HTML5 - Web RTC

HTML5 - WebRTC (Web Real-Time Communication)

Section titled “HTML5 - WebRTC (Web Real-Time Communication)”

WebRTC (Web Real-Time Communication) is an open-source project and set of standards supported by the W3C and IETF that enables real-time communication (RTC) capabilities directly within web browsers and mobile applications via simple JavaScript APIs.

It allows peer-to-peer (P2P) communication for applications like voice calling, video chat, screen sharing, and direct data/file transfer without requiring users to install plugins or native applications.

WebRTC is widely supported in modern browsers like Chrome, Firefox, Safari, and Edge on both desktop and mobile platforms.

WebRTC functionality is primarily exposed through three main JavaScript APIs:

  • navigator.mediaDevices.getUserMedia(): Accesses the user’s camera and microphone to capture audio and video streams (MediaStream).
  • RTCPeerConnection: Establishes and manages a peer-to-peer connection between two clients for streaming audio, video, and data.
  • RTCDataChannel: Enables sending arbitrary data directly between peers over an established RTCPeerConnection.

MediaStream (Accessing Camera and Microphone)

Section titled “MediaStream (Accessing Camera and Microphone)”

The getUserMedia() method (part of the MediaDevices API) prompts the user for permission to access their media input devices (like webcams and microphones). If permission is granted, it returns a Promise that resolves with a MediaStream object.

A MediaStream represents a stream of media content, consisting of one or more tracks (MediaStreamTrack), such as an audio track from a microphone or a video track from a webcam.

Example: Accessing and Displaying Webcam Video

Section titled “Example: Accessing and Displaying Webcam Video”
<!DOCTYPE html>
<html>
<head>
<title>getUserMedia Example</title>
<style>
video { max-width: 100%; border: 1px solid black; }
</style>
</head>
<body>
<h1>Webcam Feed</h1>
<video id="webcamVideo" autoplay playsinline></video>
<div id="status">Requesting camera access...</div>
<script>
const videoElement = document.getElementById('webcamVideo');
const statusDiv = document.getElementById('status');
async function startCamera() {
// Check if getUserMedia is supported
if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
statusDiv.textContent = 'getUserMedia is not supported by your browser.';
return;
}
try {
// Define constraints: request video, audio is optional
const constraints = {
video: true,
audio: false // Set to true to request microphone access too
};
// Request media stream
const stream = await navigator.mediaDevices.getUserMedia(constraints);
statusDiv.textContent = 'Camera access granted.';
console.log('Received MediaStream:', stream);
// Attach the stream to the video element
videoElement.srcObject = stream;
// Optional: Log track information
stream.getVideoTracks().forEach(track => {
console.log('Video Track:', track.label, track.getSettings());
});
stream.getAudioTracks().forEach(track => {
console.log('Audio Track:', track.label);
});
} catch (error) {
statusDiv.textContent = `Error accessing media devices: ${error.name} - ${error.message}`;
console.error('Error accessing media devices.', error);
}
}
startCamera();
</script>
</body>
</html>

RTCPeerConnection (Establishing P2P Connections)

Section titled “RTCPeerConnection (Establishing P2P Connections)”

RTCPeerConnection is the core of WebRTC, handling the complex process of connecting two peers directly, even if they are behind NATs or firewalls. This involves:

  • Signaling: Exchanging metadata between peers to coordinate the connection setup. This includes session control messages, network configuration (IP addresses, ports), and media capabilities (codecs, resolutions). WebRTC does not define a signaling protocol. Developers must implement their own signaling mechanism using existing technologies like WebSockets, SSE, or even carrier pigeons (though not recommended!).
  • ICE (Interactive Connectivity Establishment): A framework to find the best possible path for connecting peers. This involves gathering connection candidates (local IP, public IP via STUN servers, relayed IP via TURN servers) and testing connectivity.
  • STUN/TURN Servers: Public servers used during the ICE process. STUN (Session Traversal Utilities for NAT) helps discover public IP addresses. TURN (Traversal Using Relays around NAT) acts as a relay server when a direct P2P connection cannot be established.
  • SDP (Session Description Protocol): A standard format used to describe the multimedia session parameters (codecs, network addresses, etc.) exchanged during signaling.

Simplified Connection Flow (Offer/Answer Model)

Section titled “Simplified Connection Flow (Offer/Answer Model)”
  1. Peer A (Caller): Creates an RTCPeerConnection object.
  2. Peer A: Creates an ‘offer’ (an SDP description of its capabilities and desired session) using createOffer().
  3. Peer A: Sets the offer as its local description using setLocalDescription().
  4. Peer A: Sends the offer to Peer B via the chosen signaling channel.
  5. Peer B (Callee): Receives the offer.
  6. Peer B: Creates an RTCPeerConnection object.
  7. Peer B: Sets the received offer as its remote description using setRemoteDescription().
  8. Peer B: Creates an ‘answer’ (an SDP description responding to the offer) using createAnswer().
  9. Peer B: Sets the answer as its local description using setLocalDescription().
  10. Peer B: Sends the answer back to Peer A via the signaling channel.
  11. Peer A: Receives the answer.
  12. Peer A: Sets the received answer as its remote description using setRemoteDescription().
  13. ICE Candidate Exchange: During this process, both peers generate ICE candidates (potential connection paths) and exchange them via the signaling channel using the onicecandidate event handler and the addIceCandidate() method.
  14. Connection Established: Once compatible ICE candidates are found and exchanged, the P2P connection is established, and media/data can flow directly.

Adding media streams (from getUserMedia) to the connection is done using addTrack() or the older addStream() method.

Once an RTCPeerConnection is established, you can create RTCDataChannels to send arbitrary data (strings, binary data, files) directly between peers. This bypasses the server, offering low latency communication.

Data channels can be configured to be reliable (like TCP) or unreliable and unordered (like UDP), making them suitable for various use cases from file transfer to real-time game state synchronization.

Creating and Using a Data Channel (Conceptual)

Section titled “Creating and Using a Data Channel (Conceptual)”
// --- On the initiating peer (e.g., Peer A) ---
const peerConnectionA = new RTCPeerConnection(/* configuration */);
// Create a data channel BEFORE creating the offer
const dataChannelA = peerConnectionA.createDataChannel("myDataChannel", { reliable: true });
dataChannelA.onopen = () => console.log("Data channel A open");
dataChannelA.onmessage = (event) => console.log("Msg from B:", event.data);
dataChannelA.onclose = () => console.log("Data channel A closed");
// ... proceed with createOffer, setLocalDescription, signaling ...
// --- On the receiving peer (e.g., Peer B) ---
const peerConnectionB = new RTCPeerConnection(/* configuration */);
// Listen for the data channel established by the other peer
peerConnectionB.ondatachannel = (event) => {
const dataChannelB = event.channel;
console.log("Data channel B received:", dataChannelB.label);
dataChannelB.onopen = () => console.log("Data channel B open");
dataChannelB.onmessage = (event) => console.log("Msg from A:", event.data);
dataChannelB.onclose = () => console.log("Data channel B closed");
// Example: Send a message back when open
dataChannelB.onopen = () => {
console.log("Data channel B open");
dataChannelB.send("Hello from Peer B!");
};
};
// ... proceed with setRemoteDescription (offer), createAnswer, setLocalDescription, signaling ...

WebRTC is a complex technology. For deeper dives and practical examples: