Record Video From Camera using Javascript

Published on January 7, 2021

Videos can be recorded from a camera using MediaDevices & MediaRecorder APIs :

  • Use getUserMedia() method to get access to the user's webcam.
  • Use the camera stream to create a new MediaRecorder object.
  • Use start() & stop() methods on the MediaRecorder object to start & stop recording.


Click to see demo

HTML & Javascript

<button id="start-camera">Start Camera</button>
<video id="video" width="320" height="240" autoplay></video>
<button id="start-record">Start Recording</button>
<button id="stop-record">Stop Recording</button>
<a id="download-video" download="test.webm">Download Video</a>
  • #start-camera button requests user for camera access.
  • #video displays the camera stream.
  • #start-record starts video recording.
  • #stop-record stops video recording.
  • #download-video downloads the recorded video.
let camera_button = document.querySelector("#start-camera");
let video = document.querySelector("#video");
let start_button = document.querySelector("#start-record");
let stop_button = document.querySelector("#stop-record");
let download_link = document.querySelector("#download-video");

let camera_stream = null;
let media_recorder = null;
let blobs_recorded = [];

camera_button.addEventListener('click', async function() {
   	camera_stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
	video.srcObject = camera_stream;

start_button.addEventListener('click', function() {
    // set MIME type of recording as video/webm
    media_recorder = new MediaRecorder(camera_stream, { mimeType: 'video/webm' });

    // event : new recorded video blob available 
    media_recorder.addEventListener('dataavailable', function(e) {

    // event : recording stopped & all blobs sent
    media_recorder.addEventListener('stop', function() {
    	// create local object URL from the recorded video blobs
    	let video_local = URL.createObjectURL(new Blob(blobs_recorded, { type: 'video/webm' }));
    	download_link.href = video_local;

    // start recording with each recorded blob having 1 second video

stop_button.addEventListener('click', function() {
  • getUserMedia() method requests access to the user's webcam.
  • Using the video stream from the camera, a new MediaRecorder object is created.
  • The format of the recorded video has been set as video/webm as its support is great across browsers. video/mp4 would have even better, however it has limited browser support.
  • start() method starts the recording. Its parameter represents the timeslice of captured video chunks (however it is optional — if no parameter is passed then entire video will be recorded as a single chunk).
  • dataavailable event is fired each time when a recorded video chunk is available (if no timeslice has been provided during start, then this will be fired only once).
  • stop() method stops the recording.
  • stop event is fired after recording is stopped and final dataavailable event has been fired. At this point all recorded blobs can be combined.

Browser Compatibility

Chrome, Edge & Firefox have support for the MediaRecorder API. They all support video/webm.

Safari 14.1+ has also added support for MediaRecorder API. It supports video/mp4 format. video/webm may also be supported (as per this).

Other FAQs

How to add a pause/resume feature to recording ?

The pause() & resume() methods can be used to pause and resume the recording.

// media_recorder refers to created MediaRecorder object

// pauses recording

// resume recording after it was paused
How to upload the recorded video to server ?

The recorded blobs can be converted to a Javascript File, which can be uploaded to server via XMLHttpRequest or fetch().

// blobs_recorded refers to recorded blobs array
let recording = new File(blobs_recorded, 'recording.webm', { type: 'video/webm' });

let data = new FormData();
data.append('file', recording);

// send fetch along with cookies
let response = await fetch('/upload.php', {
    method: 'POST',
    credentials: 'same-origin',
    body: data


In this Tutorial