w3c / webcodecs

WebCodecs is a flexible web API for encoding and decoding audio and video.
https://w3c.github.io/webcodecs/
Other
994 stars 135 forks source link

The file produced by the 'capture file' sample is broken in some way #332

Closed sashazxtt closed 1 year ago

sashazxtt commented 3 years ago

The Webm file produced by this sample: https://w3c.github.io/webcodecs/samples/capture-to-file/capture-to-file.html is broken in some way. It doesn't properly seek. In VLC the current timestamp becomes some huge value. The Windows video player throws an error. Chrome simply stops playing.

The duration (always) and current time are displaying properly up to some point (30 or se seconds).

nixxquality commented 2 years ago

I noted the same. It's an issue with the webm writer that I copied over to my own project.

After around 31-32 seconds my media player mpv interprets the timestamps as becoming negative. Seeking into past 32 seconds doesn't work.

nixxquality commented 2 years ago

Going through the modified webm-writer code and comparing it to the original

The timestamp issue past 32 seconds is because MAX_CLUSTER_DURATION_MSEC was changed from 5000 to 5000000.

> ffmpeg -i C:\Users\Linus\Videos\test.webm -c copy .\Videos\testt.webm
[webm @ 000001887bc37480] Application provided invalid, non monotonically increasing dts to muxer in stream 0: 65548 >= 28

Looks like a classic overflow, but why?

// all irrelevant parts cut out
    function addFrameToCluster(frame) {
        if (clusterDuration >= MAX_CLUSTER_DURATION_MSEC) {
          flushClusterFrameBuffer();
        }
      }

    function flushClusterFrameBuffer() {
        cluster.data.push(createSimpleBlockForframe(clusterFrameBuffer[i]));
    }

    function createSimpleBlockForframe(frame) {
      bufferStream.writeU16BE(frame.timecode); // 🚨
    }

The file being unseekable is a separate issue, though. I'm not sure why that happens. Notably, it becomes unseekable past the MAX_CLUSTER_DURATION_MSEC.

I guess there's supposed to be some glue between clusters that's missing? I'm not too familiar with the Matroska format.


The seeking issue is because of the cues. For some reason, patching the writeCues function to only print the first cue fixes it.

I'm assuming there's a proper solution for this.

josephrocca commented 1 year ago

Thanks nixxquality! In case it's helpful for others, here's a version of the original with nixxquality's fixed applied: https://gist.github.com/josephrocca/0d6ea26370b897cb71ef9cb3b947fcd6

Weirdly, it doesn't play in VLC - it seeks correctly and has correct duration, but always stays on the first frame. Playback works properly in Chrome and Firefox though.

I'll submit a pull request with these fixes because although it's worth getting to the bottom of the actual issue here, it'd be great if the demo worked properly in the meantime.

nixxquality commented 1 year ago

Don't get me wrong, my solution is definitely not proper and I wouldn't recommend it. It's merely replacing one non-standard hack that only works in some cases with another non-standard hack that only works in some media players. The real solution would be fixing the cue writing.

dalecurtis commented 1 year ago

Probably we should just replace the webm writer with mp4box.js since it's better supported if there are issues with the upstream version.