What could be the reason for Safari generating larger videos than Chrome when utilizing the MediaDevices.getUserMedia() API?

Embarking on a small experiment to gauge the size of captured videos using the MediaDevices.getUserMedia() API.

My Safari implementation yielded videos 5-10 times larger than those in Chrome. Here's the code snippet:

index.html:

<html lang="en">
  <head>
    <title>Video Spike</title>
  </head>
  <body>
    <video autoplay id="video" muted></video>
    <br />
    <button id="record">Record 10 second video</button>
  </body>
  <script src="./index.js"></script>
</html>

index.js:

const videoElem = document.getElementById("video");
const recordBtn = document.getElementById("record");

async function startCamera() {
  const stream = await navigator.mediaDevices.getUserMedia({
    audio: true,
    video: {
      frameRate: 30,
      height: 240,
      width: 240,
    },
  });

  videoElem.srcObject = stream;

  let buffer;

  recordBtn.addEventListener("click", () => {
    buffer = [];
    const recorder = new MediaRecorder(stream);

    setTimeout(() => recorder.stop(), 10000);

    recorder.ondataavailable = async (event) => {
      buffer.push(event.data);
      console.log(
        "current video size:",
        new Blob(buffer, { type: "video/webm" }).size / 1024 / 1024,
        "MB"
      );
    };

    recorder.start(1000);
  });
}

startCamera();

On my end, Safari clocks in at 6.5MB after 10 seconds, while Chrome maintains a modest 0.6MB.

Despite tweaking MediaConstraints, resolutions, and duration parameters, the glaring size discrepancy between the two browsers persists.

Answer №1

When initializing a MediaRecorder, one can specify the bitsPerSecond option.

const recorder = new MediaRecorder(stream, { bitsPerSecond: 200_000 });

It appears that default values for bitsPerSecond differ between Chrome and Safari.

In addition to bitsPerSecond, it is also possible to individually set the audioBitsPerSecond and videoBitsPerSecond.

Answer №2

The main issue at hand is the difference in video encoding between Safari and Chrome. Safari encodes videos as H264 in an mp4 container, while Chrome produces VP9 webm videos.

Simply setting { type: "video/webm" } in the Blob() constructor doesn't fully convert it to a webm file. You need to specify the mimeType for the MediaRecorder:

const recorder = new MediaRecorder(stream, { mimeType: "video/webm" });

It's worth noting that you can customize the codecs used, but Safari still only supports H264 in mp4 format.

While Safari may have a default videoBitsPerSecond value of 10Mbps compared to Chrome's 2.5Mbps, adjusting it as suggested in another answer will still result in a significant discrepancy between the two browsers. For example, with a forced 2.5Mbps bit rate, Safari generates a 3MB file while Chrome creates a 0.8Mb one. Unfortunately, there isn't much room for adjustment.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Several different forms are present on a single page, and the goal is to submit all of the data at

Looking for assistance with combining Twitter and Google data entry at once. Here's the code I've developed: Please guide me on how to submit Twitter and Google details together. <html> <head> <script type="text/javascript">< ...

How to extract a subset of data from an existing object and create a new object in Vue JS

My latest project involves creating a search app to find products. I have implemented a PHP script that returns results in JSON format when a keyword is submitted. The data retrieval is done using axios. The challenge I am facing is with handling the disp ...

When attempting to access front-end SPA links through the browser, the back-end triggers an error due to not being

My front-end single-page-application is built using JS (ReactJS), and the back-end is running on Phoenix (Elixir). Everything functions smoothly within the application, but I encounter a route error from Phoenix when attempting to access a page in the SPA ...

Adding new elements to a list with Jquery, seamlessly integrating them without the need to

I am facing a bit of a roadblock in figuring out how to achieve this, mainly due to my limited understanding of JavaScript. The code that I have been looking at is as follows: http://jsfiddle.net/spadez/VrGau/ What I am attempting to accomplish is allowi ...

Combining jQuery dataTables and Codeigniter for dynamic rendering using sAjaxSource

I am currently facing an issue while working with dataTables in Codeigniter. I keep encountering the following error message: array_push() expects parameter 1 to be array, null given The resulting output is {"aaData":null} My desired outcome should look ...

`Upkeeping service variable upon route alteration in Angular 2`

Utilizing a UI service to control the styling of elements on my webpage is essential. The members of this service change with each route, determining how the header and page will look. For example: If the headerStyle member of the service is set to dark ...

Develop a library of components using TypeScript and Less files

I'm currently in the process of creating a React UI library that will consist of various components such as Buttons, Inputs, textareas, etc. This library, which I've temporarily named mylib, will be reused across multiple projects including one c ...

Utilizing the Public Directory in Vite Compilation

One issue I encountered in my project with Vite version 2.9.7 is related to the handling of images stored in the public folder within the project's root directory. To import these images, I utilized Vite's import.meta.glob function, like so: imp ...

Is it possible to utilize the spread operator for combining arrays?

Consider two different arrays represented by variables a and b. The variable c represents the output as a single array, indicating that this method combines two or more arrays into one. let a=[a ,b]; let b=[c ,d]; c=[a,...b] The resulting array will be: ...

When you click on a single checkbox, it automatically selects all of them

Struggling with a form that uses HTML PDO and AngularJS for validation. When clicking one checkbox, all other checkboxes get checked as well. Here is my form: <input type="checkbox" name="declaration" id="declaration" ng-m ...

Is Node.js or Express.js a server-side language like PHP or something completely different?

Hello, I have a question about Node.js and Express.js. I come from a PHP background and understand that PHP operations and functions execute on the server and return results to the client's screen. In simple terms, does Node.js/Express.js serve the s ...

Utilizing Data From External Sources in a React Application

I have encountered an issue with displaying data from another page in a reusable table I created using React. Specifically, I am having trouble getting the value to be shown in <TableCell> Please check out this code sandbox link for reference ACCES ...

Using JavaScript promises to handle connection pooling and query execution

I am contemplating whether this approach is on the right track or if it requires further adjustments. Should I consider promisifying my custom MySQL getConnection method as well? request: function(queryRequest) { return new Promise(function(re ...

Adding a number repeatedly and showing the result

I have been searching for a solution to this particular problem for quite some time now, but unfortunately, I haven't been able to find one yet. It would be incredibly helpful if someone could guide me in the right direction. Let's say we start ...

Executing a method from the parent controller within nested directives by utilizing isolated scope

I need help with a treeview directive in my project. I am having trouble invoking a function from the parent controller and can't seem to figure out why it's not working. It could be due to the structure of the treeview and nesting of child eleme ...

Utilize React Native to continuously fetch and display data from this API

[React-Native] Seeking assistance on looping through JSON API for conditional rendering. As a beginner, I would greatly appreciate your guidance. Thank you. Find my code here: https://drive.google.com/file/d/0B3x6OW2-ZXs6SGgxWmtFTFRHV00/view Check out th ...

What is the best way to delete the material-dashboard-react text from the starting route in a material ui admin panel?

When launching my React web application, I am initially directed to localhost:3000/material-dashboard-react, which then redirects to /. However, this redirect is briefly visible before the web app fully loads. Can anyone advise on how to remove this initia ...

Having difficulties sending data from axios to my node server, resulting in an empty object being returned

Here is the client-side code I am using: <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport&quo ...

The concept of IFA on Android and accessing it through the browser/javascript

IFA (Identifier for Advertisers) is a new feature in iOS 6 that functions as a unique ID for tracking user context anonymously and improving the overall experience. My inquiries mainly focus on the realm of web development (specifically mobile browser/jav ...

express-session is failing to maintain persistence and refusing to transmit a cookie to the browser

I am currently developing a web application using the MERN stack (React, Node.js, Express, and MongoDB). I have integrated express-session in my Node.js project, but for some reason, I cannot see the connect.sid cookie in the browser. Additionally, it appe ...