Closed cdaein closed 8 months ago
Thanks for the full reproduction, I really appreciate it! Even better would be a finished setup on StackBlitz (with Vite or something), so I can just open it and see it immediately. But that's for next time :)
MP4 and WebM work a little different; in WebM, video frames only have a timestamp. In MP4, the timing of frames is determined by the delta between frames, so duration matters more. A simple fix in your code made the MP4 file play back correctly:
let frame = new VideoFrame(canvas, {
timestamp: (frameCount * 1e6) / fps, // Ensure equally-spaced frames every 1/30th of a second
+ duration: 1e6 / fps,
});
Without this field, the frame implicitly gets a duration of 0. With the proper duration set, the last frame of the video shows correctly (this is in Finder):
https://github.com/Vanilagy/mp4-muxer/assets/1696106/d358ae9f-34e5-4ad2-81ae-3b79bb2b47fb
It has to be noted that this also depends heavily on the player, Chromium properly showed the last frame even for the "incorrect" file.
The 31.03 frame rate can be explained like so: Since the original video had 0-duration frames, its duration was equal to the timestamp of the last frame, which is at $\frac{29}{30}$ seconds. But the video still had 30 frames, so it comes out to a frame rate of
$$ \frac{30}{\frac{29}{30}} \approx 31.03448 $$
With the frame duration set, it correctly has a duration of exactly 1 second and a frame rate of 30.
I hope this clears things up. If you still have any questions, feel free to ask!
That solved the issue! Thank you for the kind explanation. I will be keep in mind to include a live environment next time. 🙏
@Vanilagy, just to clarify? fixing the duration solves the problem on all players? specially interested in browsers
@Pensarfeo It was the case for me, but I only tested Chromium and QuickTime. I attached a fixed file in my reply in this thread, so you can try that out.
Ill check! :)
Worked for me, thanks @Vanilagy!
Awesome! I think this is partially on me since I don't set the duration in my demo script. I should!
Hi, Thank you for all the work on webm-muxer and mp4-muxer!
I am using the libraries to record canvas animation frames. I've noticed each library behaves a little differently when used in the same way.
In the example below, I'm recording the total of 30 frames.
In the resulting WebM video, the last
frameCount
is29
, which is accurate. It also has the correct fps of 30.But in the mp4 video, the last
frameCount
shows up as28
, missing the very last frame. What's also strange is that when I manually scrub the Quicktime timeline, I sometimes do see 29 displayed but it seems this frame doesn't have any duration. Also, the frame rate is displayed as31.03
instead of30
.I'm wondering if I need to handle frame recording differently with mp4-muxer.
Below is a simple demo to illustrate my issue. You can click the mouse inside the canvas to initiate the recording of both videos: