JavaScript MediaRecorder video format compatibility between different browsers
Asked Answered
S

2

7

Introduction

When using the MediaRecorder on the browser to record a video stream, depending on the browser (Chrome, Safari, or Firefox) the MediaRecorder can record videos in a specific format.

The table below shows what video formats/containers the MediaRecorder can record in each browser (I get this by using the isTypeSupported static method). Also this article shows a table of all supported MediaRecorder format on different browsers using the isTypeSupported method.

Browser Recording Format
Chrome .WEBM, .MKV
Opera .WEBM, .MKV
Edge .WEBM, .MKV
Firefox .WEBM
Safari .MP4

When you want to play a video you also not all browsers support the same format as well. The table below shows what video format each browser can play (It might be inaccurate).

Browser Can play video format
Chrome .MP4, .WEBM, .MKV
Opera .MP4, .WEBM, .MKV
Edge .MP4, .WEBM, .MKV
Firefox .MP4, .WEBM
Safari .MP4

The Problem

I have a web app where the user can record a video on his/her browser and then upload this video to the database.

After that, other users can visit the website and watch that video on their browsers. If the user record a video on Safari browser, the recorded video format is supported by all browsers (MP4), but if the user is using Chrome or Firefox, the recorded video format is supported by all browsers (WEBM) except for Safari.

Is there a way to record a video in a format that can be played on all browsers (For example MP4)?

  1. I tried using video.js npm package but it wasn't successful.
  2. I also tried using FFMPEG to convert the video on the client side but the amount of processing is huge compared to a website and takes a very long time.

I am looking for a solution that can be done only on the browser without converting the video format.

Syblesybley answered 27/4, 2023 at 20:52 Comment(2)
I looked for this myself for a long time and found nothing useful, except for the server side transcoding solution. Sigh.Hesson
helpful table thanks!Lacylad
L
1

Use cloudinary or a similar CDN. I wrote some code to detect which browser the device recorded on (in the case of desktop chrome or firefox webm is preferred as you say) then when uploading it to a service like cloudinary you can just pull it back in any format on the fly changing the suffix (eg mp4 would make sense).

note: chrome on safari is actually considered safari since its based on safari (took me a while to figure that out!)

Wish the industry would just stick to one standard!

Lacylad answered 20/11, 2023 at 12:56 Comment(0)
S
0

In my demo web app below the code is trying to use differents kinds of container and codecs that are standards for webrtc, depending on what user agent is on the client side, when making a new recorded video. Unfortunately I don't use Safary browser so I cant tell you which format/codecs it use by default, but you can try it and see. I report the code that make the choice with mimetype option within try catch code

https://vrobbi-webrtc-demo.glitch.me/uploadvideo

  //     mimeType: 'video/webm;codecs=vp8,opus', audioBitsPerSecond: 30000, videoBitsPerSecond: 50000
  //   video/webm; codecs="vp8, vorbis"
  //   video/mp4; codecs="avc1.424028, opus"   ****   FUNZIONA ***   
  //    video/webm;codecs="vp8"        
  //   'video/mp4; codecs="avc1.42E01E, mp4a.40.2"'
  //  video/webm;codecs="vp08.00.41.08,vorbis"
  try {
    options.videoBitsPerSecond = document.getElementById('videoquality').value;
    mediaRecorder = new MediaRecorder(window.stream, options);
    console.log('riga opzioni: ' + options.mimeType + ' ' + options.videoBitsPerSecond);
    infoupload.innerHTML = 'Registrazione in corso, tipo ' + options.mimeType;

  } catch (e0) {
    console.log('Unable to create MediaRecorder with options Object: ', options, e0);
    try {
      options = { mimeType: 'video/webm;codecs=vp9,opus', audioBitsPerSecond: 12000, videoBitsPerSecond: 32000 };
      options.videoBitsPerSecond = document.getElementById('videoquality').value;
      mediaRecorder = new MediaRecorder(window.stream, options);
      infoupload.innerHTML = 'Registrazione in corso, tipo ' + options.mimeType;
      console.log('riga opzioni: ' + options.mimeType + ' ' + options.videoBitsPerSecond);
    } catch (e1) {
      console.log('Unable to create MediaRecorder with options Object: ', options, e1);
      try {
        options = { mimeType: 'video/webm;codecs=avc1,opus', videoBitsPerSecond: 48000, audioBitsPerSecond: 12000 };
        options.videoBitsPerSecond = document.getElementById('videoquality').value;
        mediaRecorder = new MediaRecorder(window.stream, options);
        infoupload.innerHTML = 'Registrazione in corso, tipo ' + options.mimeType;
        console.log('riga opzioni: ' + options.mimeType + ' ' + options.videoBitsPerSecond);
      } catch (e2) {
        console.log('Unable to create MediaRecorder', e2);


        try {
          options = { mimeType: 'video/webm;codecs=vp8,opus', videoBitsPerSecond: 48000, audioBitsPerSecond: 32000 };
          options.videoBitsPerSecond = document.getElementById('videoquality').value;
          mediaRecorder = new MediaRecorder(window.stream, options);
          infoupload.innerHTML = 'Registrazione in corso, tipo ' + options.mimeType;
          console.log('riga opzioni: ' + options.mimeType + ' ' + options.videoBitsPerSecond);
        } catch (e3) {
          alert('MediaRecorder is not supported by this browser.');
          console.log('Unable to create MediaRecorder', e3);
          return;
        }
      }

    }

  }
Saad answered 15/2, 2024 at 9:51 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.