5

I and my team have been struggling lately to find an explanation why does Firefox produce larger WebM/VP8 video files compared with Chrome when using the MediaRecorder API in our project.

In short, we record a MediaStream from a HTMLCanvas via the captureStream method. In attempt to isolate everything from our app that might affect this, I developed a small dedicated test app which records a <canvas> and produces WebM files. I've been performing tests with the same footage, video duration, codec, A/V bit rate and frame rate. However, Firefox still ends up creating up to 4 times larger files compared with Chrome. I also tried using a different MediaStream source like the web camera but the results were similar.

Here is a fiddle which should demonstrate what I am talking about: https://jsfiddle.net/nzwasv8k/1/ https://jsfiddle.net/f2upgs8j/3/. You can try recording 10-sec or 20-sec long videos on both FF and Chrome, and notice the difference between the file sizes. Note that I am using only 4 relatively simple frames/images in this demo. In real-world usage, like in our app where we record a video stream of a desktop, we reached the staggering 9 times difference.

I am not a video codec guru in any way but I believe that the browsers should follow the same specifications when implementing a certain technology; therefore, such a tremendous difference shouldn't occur, I guess. Considering my knowledge is limited, I cannot conclude whether this is a bug or something totally expected. This is why, I am addressing the question here since my research on the topic, so far, led to absolutely nothing. I'll be really glad, if someone can point what is the logical explanation behind it. Thanks in advance!

4

1 回答 1

3

因为他们不使用相同的设置...

除了我们可以从 MediaRecorder 访问的参数之外,webm 编码器还有很多其他参数。

这些参数可能都对输出文件的大小有影响,并且由实现者来设置。


以下是我从您更新的小提琴生成的视频的快照[点击放大]:

铬 1 火狐 1
铬 2 火狐 2

我希望你能体会到质量的差异,它和 webp 的 0.15 和 0.8 的质量参数差不多,大小也反映了这些变化。

const supportWebPExport = document.createElement('canvas').toDataURL('image/webp').indexOf('webp') > -1;
const mime = supportWebPExport ? 'image/webp' : 'image/jpeg';

const img = new Image();
img.onload = doit;
img.crossOrigin = 'anonymous';
img.src = "https://i.imgur.com/gwytj0N.jpg";

function doit() {
 const canvas = document.createElement('canvas');
 const ctx = canvas.getContext('2d');
 canvas.width = this.width,
 canvas.height = this.height;
 ctx.drawImage(this, 0,0);
 
 canvas.toBlob(b => appendToDoc(b, '0.15'), mime, 0.15);
 canvas.toBlob(b => appendToDoc(b, '0.8'),mime, 0.8);
}

function appendToDoc(blob, qual) {
  const p = document.createElement('p');
  p.textContent = `quality: ${qual} size: ${blob.size/1000}kb`;
  p.appendChild(new Image).src = URL.createObjectURL(blob);
  document.body.appendChild(p);
}

所以是的,就是这样……一种或另一种方式可能更适合您的情况,但最好的是我们,网络开发人员,可以访问这些参数。不幸的是,从规格的角度来看,这并不是一件容易的事......

于 2019-02-12T14:50:59.197 回答