WebRTC Basics: Accessing Media Devices, Streams, Screen Sharing, and Recording
This article introduces WebRTC fundamentals, explains how to enumerate audio/video devices, describes MediaStream and MediaStreamTrack concepts, demonstrates using getUserMedia for media capture with constraints, shows screen sharing via getDisplayMedia, and provides code examples for recording and downloading video streams using MediaRecorder.
Getting Available Audio/Video Devices
WebRTC provides the enumerateDevices API to list all available media input and output devices such as microphones, cameras, and headphones. The API returns an array of MediaDeviceInfo objects, each containing deviceId , kind , label , and groupId .
navigator.mediaDevices.enumerateDevices().then(function(devices) {
devices.forEach(function(device) {
if (device.kind === 'audioinput') {
// audio input device
} else if (device.kind === 'videoinput') {
// video input device
} else if (device.kind === 'audiooutput') {
// audio output device
}
});
});MediaStream and MediaStreamTrack Overview
A MediaStreamTrack represents a single media source (e.g., a video track from a camera or an audio track from a microphone). Important properties include enabled , id , kind , and readyState .
A MediaStream is a collection of zero or more MediaStreamTrack objects. It can be rendered in a <video> element, and tracks within the same stream are time‑synchronized.
Audio/Video Capture
Use navigator.mediaDevices.getUserMedia() to request access to the camera and microphone. It returns a Promise that resolves with a MediaStream on success or rejects with an error (e.g., PermissionDeniedError ).
const constraints = { video: true };
navigator.mediaDevices.getUserMedia(constraints)
.then(function(mediaStream) {
const video = document.querySelector('video');
video.srcObject = mediaStream;
video.onloadedmetadata = function(e) {
video.play();
};
})
.catch(function(err) {
console.log(err.name + ": " + err.message);
});You can specify more detailed constraints, such as resolution, frame rate, or camera facing mode:
{ audio: true, video: { width: 1280, height: 720 } }
{ video: { frameRate: { ideal: 10, max: 15 } } }
{ audio: true, video: { facingMode: "user" } }
{ audio: true, video: { facingMode: { exact: "environment" } } }Screen Sharing
Screen sharing is achieved with navigator.mediaDevices.getDisplayMedia() , which prompts the user to select a screen, window, or tab to share.
let displayMediaOptions = {
video: {
width: { max: 1280 },
height: { max: 720 },
frameRate: { ideal: 15 }
}
};
navigator.mediaDevices.getDisplayMedia(displayMediaOptions)
.then(handleSuccess);
function handleSuccess(stream) {
const video = document.querySelector('video');
video.srcObject = stream;
stream.getVideoTracks()[0].addEventListener('ended', () => {
// handle end of sharing
});
}Video Recording and Download
Recording is performed with the MediaRecorder API, which captures data from a MediaStream and stores it in an array of Blob objects.
const recordedBlobs = [];
navigator.mediaDevices.getUserMedia({ video: true })
.then(function(stream) {
const mediaRecorder = new MediaRecorder(stream, { mimeType: 'video/webm' });
mediaRecorder.ondataavailable = event => {
if (event.data && event.data.size > 0) {
recordedBlobs.push(event.data);
}
};
mediaRecorder.start();
});To stop recording:
mediaRecorder.stop();Playback the recorded video:
const blob = new Blob(recordedBlobs, { type: 'video/webm' });
const recordedVideo = document.querySelector('video');
recordedVideo.src = window.URL.createObjectURL(blob);
recordedVideo.play();Download the video by creating a hidden a element:
download.addEventListener('click', () => {
const blob = new Blob(recordedBlobs, { type: 'video/webm' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.style.display = 'none';
a.download = 'record.webm';
a.click();
});360 Smart Cloud
Official service account of 360 Smart Cloud, dedicated to building a high-quality, secure, highly available, convenient, and stable one‑stop cloud service platform.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.