Abdullah
Abdullah

Reputation: 137

Record the highest quality video using MediaRecorder API in HTML5

Using MediaRecorder API, I was able to code a page that captures the video from the web/mobile camera and saves the video on a local disk. Snippet of the code is as follows:

let mediaRecorder;
let recordedBlobs;

window.addEventListener('load', async () => {
    const constraints = {
        audio: true,
        video: true
    };

    await init(constraints);
});

async function init(constraints) {
    const stream = await navigator.mediaDevices.getUserMedia(constraints);
    handleSuccess(stream);
}

function handleSuccess(stream) {
    window.stream = stream;

    const camVideo = document.querySelector('video#vidCamera');
    camVideo.srcObject = stream;
}

function startRecording(mime) {
    recordedBlobs = [];
    let options = { mimeType: 'video/webm;codecs=vp9,opus'};

    mediaRecorder = new MediaRecorder(window.stream, options);
    mediaRecorder.ondataavailable = handleDataAvailable;
    mediaRecorder.start();
}

function handleDataAvailable(event) {
    if (event.data && event.data.size > 0) {
        recordedBlobs.push(event.data);
    }
}

This works well and I download the file after the video is captured and it plays fine. My question is regarding the quality of the video:

Ignoring any limitation of system/mobile resources, I want to set the properties of MediaRecoder to produce a video (recording) with the highest quality possible. I understand that this is handled by passing the appropriate options which in my case is { mimeType: 'video/webm;codecs=vp9,opus'}. I tried different ones and recorded 10 sec video for each (see sizes):

options = { mimeType: 'video/webm;codecs=avc1,opus'};   //904KB
options = { mimeType: 'video/webm;codecs=h264,opus' };  //923KB
options = { mimeType: 'video/webm;codecs=vp9,opus' };   //1951KB
options = { mimeType: 'video/x-matroska;codecs=avc1' }; //917KB
options = { mimeType: 'video/webm;codecs=vp8,opus' };   //2687KB
options = { mimeType: 'video/webm;codecs=avc1' };       //917KB
options = { mimeType: 'video/webm;codecs=h264' };       //919KB
options = { mimeType: 'video/webm' };                   //906KB
options = { mimeType: '' };                             //896KB

All of the above videos have the frame height x width of 480 x 640. Please note, I did not set these dimensions in code anywhere.

I can see the max size is produced by vp8, opus.

  1. Does this mean, the highest quality video is by the combination of vp8 and opus?
  2. If that is not the case, what combination of the video/audio codecs will produce the highest quality?
  3. What about the dimensions, aren't they suppose to be higher? Or is that dependent on the device/machine I am using?

I have checked the Recommendations for high-quality video presentation here but there is no example given of the combination for options. I already tried avc1, opus above and it only produced 904KB video.

The goal is to select the combination of video/audio codecs to produce a video of the highest quality where I assume, it will have the maximum size of all videos.

EDIT:

So I ended up selecting vp8,opus with the following constraints.

Options:

let options = { mimeType: 'video/webm;codecs=vp8,opus' };

Constraints:

const constraints = {
    audio: true,
    video: {
        height: { min: 720, max: 1280 },
        width: { min: 1080, max: 1920 },
        frameRate: { min: 15, ideal: 24, max: 30 },
        facingMode: "user"
    }
}

This produced a high quality video that I was satisfied with. Please also note the type (mp4) used in the code where the recorded chunks are turned to blob.

Blob:

const blob = new Blob(recordedBlobs, { type: 'video/mp4' });

Upvotes: 3

Views: 5345

Answers (1)

Doug Sillars
Doug Sillars

Reputation: 1765

I would assume that 480x640 are the dimensions of your webcam. But just to make sure you are getting the biggest video size, set an ideal constraint for width and height (MDN reference):

const constraints = { audio: true,      video:{
    width: { ideal: <aBigNumber> },
    height: { ideal: <aBigNumber> },      frameRate: {ideal: <framerate>}
}};

To your question as to which is the highest quality - size is not your best reference here. Each format encodes and compresses the videos in different ways - just like you can have a JPG or PNG with the same quality but different compression algorithms.

Upvotes: 1

Related Questions