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.
Demo
HTML & Javascript
<button id="start-camera">Start Camera</button>
<video id="video" width="320" height="240" autoplay muted></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. Don't forget to include autoplay & muted attibutes. If you need to record audio too, then include the controls attribute so that user can unmute audio.
- #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) {
blobs_recorded.push(e.data);
});
// 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
media_recorder.start(1000);
});
stop_button.addEventListener('click', function() {
media_recorder.stop();
});
- 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. Update June 2024 : Chrome has implemented mp4 support for MediaRecorder.
- 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
media_recorder.pause();
// resume recording after it was paused
media_recorder.resume();
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
});
How to check whether browser supports the given format (webm, mp4 etc) ?
The isTypeSupported() method can be used. This returns a true / false whether the given format is supported or not.
// boolean true or false whether webm is supported
media_recorder.isTypeSupported('video/webm')
// check support for mp4 with H264 video
media_recorder.isTypeSupported('video/mp4;codecs=h264')