How to Record a Video using WebRTC in the Browser
WebRTC (Web Real-Time Communication) is a free and open-source project providing web browsers and mobile applications with real-time communication (RTC) via application programming interfaces (APIs). It provides an API named getUserMedia
to access the device’s cameras and microphones.
Sometimes, we may need to record a video to save the content we get from the camera and the microphone, like the seconds when a new barcode is detected or a person enters the camera.
There are several ways to record a video:
- Use the MediaStream Recording API.
- Use the RecordRTC library.
RecordRTC’s compatibility is better which works on browsers on Android, iOS and PC devices. In this article, we are going to use WebRTC to open a camera and record a video of it with RecordRTC.
It can be used with Dynamsoft Barcode Reader to create web barcode scanner apps, which is useful in the following aspects:
- Record the video before successfully reading a barcode to test the performance.
- Record the video of the seconds when a barcode is read for double checking in the future.
Create a Page to Open a Camera
-
Create a new HTML file with the following content.
<!DOCTYPE html> <html lang="en"> <head> <title>RecordRTC Simple Demos</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"> <style> </style> </head> <body> </body> </html>
-
Ask for permissions of cameras and microphones.
window.onload = function(){ askForPermissions(); } async function askForPermissions(){ var stream; try { var constraints = {video: true, audio: true}; //ask for camera and microphone permission stream = await navigator.mediaDevices.getUserMedia(constraints); } catch (error) { console.log(error); var constraints = {video: true, audio: false}; //ask for camera permission only if no microphones detected stream = await navigator.mediaDevices.getUserMedia(constraints); hasMicrophone = false; } closeStream(stream); } function closeStream(stream){ try{ if (stream){ stream.getTracks().forEach(track => track.stop()); } } catch (e){ alert(e.message); } }
-
List camera devices in a
select
.HTML:
<select id="select-camera"></select>
JavaScript:
var cameraSelect = document.getElementById("select-camera"); var devices; async function listDevices(){ devices = await getCameraDevices() for (let index = 0; index < devices.length; index++) { const device = devices[index]; cameraSelect.appendChild(new Option(device.label ?? "Camera "+index,device.deviceId)); } } async function getCameraDevices(){ await askForPermissions(); var devices = await navigator.mediaDevices.enumerateDevices(); var cameraDevices = []; for (var i=0;i<devices.length;i++){ var device = devices[i]; if (device.kind == 'videoinput'){ cameraDevices.push(device); } } return cameraDevices; }
-
List predefined resolutions in a
select
.<select id="select-resolution"> <option selected>640x480</option> <option>1280x720</option> <option>1920x1080</option> <option>3840x2160</option> </select>
-
Open the selected camera with the selected resolution.
HTML:
<div id="video-container"> <video class="absolute" controls autoplay playsinline></video> </div>
JavaScript:
var video = document.querySelector('video'); function captureCamera(callback) { var constraints = { audio:false, video:true } if (cameraSelect.selectedOptions[0]) { var device = devices[cameraSelect.selectedIndex]; var deviceID = device.deviceId; console.log(deviceID); constraints = { video: {deviceId: deviceID}, audio: hasMicrophone } } if (resolutionSelect.selectedOptions[0]) { let desiredWidth = resolutionSelect.selectedOptions[0].label.split("x")[0]; let desiredHeight = resolutionSelect.selectedOptions[0].label.split("x")[1]; if (constraints["video"]["deviceId"]) { constraints["video"]["width"] = desiredWidth; constraints["video"]["height"] = desiredHeight; }else{ constraints = {width:desiredWidth,height:desiredHeight}; } } navigator.mediaDevices.getUserMedia(constraints).then(function(camera) { video.srcObject = camera; }).catch(function(error) { alert('Unable to capture your camera. Please check console logs.'); console.error(error); }); }
Record the Video
-
Include the library of
RecordRTC
.<script src="https://www.WebRTC-Experiment.com/RecordRTC.js"></script>
-
Create a
Recorder
instance using the camera stream.var recorder = RecordRTC(camera, { type: 'video' });
-
Start recording.
recorder.startRecording(); // keep camera for stopping recorder.camera = camera;
-
Stop recording.
recorder.stopRecording(stopRecordingCallback);
After the recording is stopped, stop the camera and play the recorded video.
function stopRecordingCallback() { video.src = video.srcObject = null; video.muted = false; video.volume = 1; video.src = URL.createObjectURL(recorder.getBlob()); recorder.camera.stop(); recorder.destroy(); recorder = null; }
-
Add a button to download the video.
JavaScript:
document.getElementById("btn-download").onclick = function() { if (!interval) { var a = document.createElement("a"); a.href = video.src; document.body.appendChild(a); a.click(); a.remove() } };
Source Code
All right, we’ve now finished the demo. We can add other features like reading the barcode at the same time. Get the source code to have a try: