-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add an example of frame-by-frame video export #10172
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is awesome! Great work Vlad.
I've also experimented with using some cool new ES patterns in the demo like in-browser ES modules, async/await and Promises to get a feel for it, and it's super great — we should definitely explore API improvements in this area.
The new render test suite makes use of async/await
and I like it quite a bit. I'd be excited to make some updates in this area. I think the docs team is also on board with updating our examples to ES code.
|
||
// stub performance.now for deterministic rendering per-frame (only available in dev build) | ||
let now = performance.now(); | ||
mapboxgl.setNow(now); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is only available with dev builds, I believe. This example isn't directly usable with the built version of GL JS on CDN or NPM. That's fine for this debug page, but it's good to note.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ryanhamley yes, I mentioned this in the PR description and the code comment above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added another commit that documents & exposes these methods in production build, so we can add the official example after this gets into a release. Note that it no longer falls back to Date.now
because it should be universally supported now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ooops I missed that in the PR description.
Note that it no longer falls back to Date.now because it should be universally supported now.
👍 awesome
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great. I think we just need to update the docs comment for restoreNow
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks good to me, this is an amazing example!
One cool way to extend this would be to add some kind of idle_but_animating
event that fires while animating, but after all tile loads and placement has finished for that animation frame.
This wouldn't be possible with easeTo
/flyTo
but should be possible with camera API or jumpTo
jumpTo
/setFreeCameraOptions
-> setNow
-> await idle
-> record frame -> repeat
5150e52
to
aa89ae1
Compare
Any example about this? |
I tried the https://github.com/mapbox/mapbox-gl-js/blob/main/debug/video-export.html. However, the saved mp4 file only has few bytes and cannot open it. I don't know why? |
Ref #5297. I'm adding this as a debug page for now, but will work on a more fleshed-out official example in the docs. The approach can be used with v1 as well.
This uses @mattdesl's excellent new WebAssembly-powered H264-MP4 encoder library to record a predefined GL JS animation frame-by-frame into a 1920x1080 60fps, buttery smooth zero-jank video download.
The sizes produced are quite big, so results need to be re-encoded with
ffmpeg -i video.mp4 video2.mp4
(see mattdesl/mp4-h264#4). To make the export ~2x faster, turn onWebAssembly SIMD
feature inchrome://flags
.The most tricky part of the approach is that we need to hijack GL JS's
browser.now
utility used for all animation timings, making it grow with 60fps-adjusted fixed increments on every frame to produce a natural video. Currently the methods for this are only exposed in themapbox-gl-dev.js
build, but I think we should expose it in production build specifically for video export purposes. cc @arindam1993 (update: exposed the methods in second commit).I've also experimented with using some cool new ES patterns in the demo like in-browser ES modules,
async/await
and Promises to get a feel for it, and it's super great — we should definitely explore API improvements in this area. I've made subtle eslint config changes for the debug folder to accommodate this page while not affecting other pages.