-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
Easy screenrecording plugin #21237
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
Easy screenrecording plugin #21237
Conversation
b901e65 to
746e1fc
Compare
72d67c1 to
5e206e0
Compare
5e206e0 to
88f3173
Compare
|
Would be even better imo if I could choose which resolution to record at. One way could be to have the plugin take care to copy the source texture to another texture then rescale as part of the render graph. Another could be to just use the CPU data and resize via e.g. the image crate or similar. The user-responsibility way is probably to have them choose the correct primary window size, but if I have a low res screen and want to record e.g. 4k then it's better to have an off-screen render target. |
|
Also, why not https://crates.io/crates/video-rs? |
I agree, but I think out of scope of this PR, that's part of the frame capture pipeline, this PR is mostly on what to do with the frames once captured. And hopefully to stay "easy and simple". |
Mainly because I'm so used to use ffmeg on the command line that I didn't look for a crate for it but directly for an encoder |
|
It looks like your PR has been selected for a highlight in the next release blog post, but you didn't provide a release note. Please review the instructions for writing release notes, then expand or revise the content in the release notes directory to showcase your changes. |
|
now with a fixed frame time:
|
|
More of a note for the future that may or may not be worth it but it would be nice to have a way to conveniently playback what was just recorded. |
I still disagree with this, the video crate lets you // One time init...
video_rs::init().unwrap();
let settings = Settings::preset_h264_yuv420p(1920, 1080, false);
let mut encoder = Encoder::new("foo.mp4", settings)?;
let frame_duration = Time::from_nth_of_a_second(30);
let mut position = Time::zero();
// For all screenshots
let to_encode = Frame::from_shape_vec([1080, 1920, 3], screenshot.to_rgb8()).unwrap();
encoder.encode(to_encode, position);
position = position.aligned_with(frame_duration).add();Then the finished |
|
Adding my two cents (tldr): Using If the application is crashing, then the entire |
|
Also please note: x264 is GPL-licensed, but the H.264/AVC codec itself is covered by MPEG-LA patents. This means even open-source projects might need to pay license fees when distributing software that includes H.264 encoding. So using x264 can have legal and licensing risks. I would rather use VP8/VP9 or (even better but there are no good software decoder and less hardware decoder) AV1. Edit: I would recommend the vpx-rs crate, this is much better, it supports vp8/vp9 and there are no patent/license problems. :) |
kerkmann
left a comment
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.
Move from x264 to vp8/vp9 or av1 regards MPEG/LA patents.
pablo-lua
left a comment
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.
Can we have an example on how to use this feature?
|
The code looks fine, but I'll defer to the video format expertise of our contributors here. An example would be nice for testing, but I won't block on it. |
|
Couple notes from usage (m1 mac) The slowdown of recording is very noticeable and we need to make sure we encourage people to use The I was able to replicate the load_gltf example recording with the sun moving. load_gltf-1765751810398.h264.mp4But the animated_mesh example's gpu skinning stalls when recording. animated_mesh-1765751920464.h264.mp4I am currently unable to run this on windows due to some pkg-config issues. |
An example is not possible as this is willingly behind a feature that's not available on top level Bevy |
ChristopherBiscardi
left a comment
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.
There are caveats:
- Windows support is uncertain (pkg-config is required)
- This has a performance impact that might make it unsuitable for active gameplay scenarios (fps, 3d platformer, etc) and should almost certainly should only be used with
--release
But I think this is a useful first step to ship because it unlocks:
- built-in recording at all, which is useful for casual games and games with non-active or scriptable gameplay
- recording in CI and other scripted scenarios
In the future I'd love to see the CI use case documented in a way that people can snag for their github actions or whatnot.
People can also advocate for av1 or whatever their tool of choice is in the future. This PR is first step that can be built upon.
# Objective - Followup on #21235 - See mockersf/bevy@easy-screenshots...mockersf:bevy:easy-screenrecording for what's new - Be able to record videos from Bevy in a consistent manner ## Solution - Make a new `EasyScreenRecordPlugin` in the dev tools ## Testing - Add to any example ``` .add_plugins(bevy::dev_tools::EasyScreenRecordPlugin::default()) ``` - Run the example with the feature `bevy_internal/screenrecording` enabled - press the space bar - wait for it... - press the space bar again - screen recording! 🎉 - almost... you now have a h264 file. VLC can read them, but they are not the most friendly format - `ffmpeg` is our friend! `for file in *.h264; do ffmpeg -i $file $file.mp4; done` - you now have a .mp4 file that can be shared anywhere! --- ## Showcase directly taken by Bevy https://github.com/user-attachments/assets/217f5093-9443-40e5-b2ce-33f65f6a56c6
# Objective - Followup on #21237 - It can be hard to share how to record a demo for a specific feature - Make it easy ## Solution - Add a dev plugin that can move the camera - Add plumbing to CI testing to be able to move the camera and control screen recording - Demo can be configured in code or in a configuration file ## Testing - Add to an example: ```rs let fps = 120; // FPS for the example on your computer [...] // Before `DefaultPlugins`: .insert_resource(CiTestingConfig { events: vec![ CiTestingEventOnFrame(fps * 1, ci_testing::CiTestingEvent::StartScreenRecording), { let transform = Transform::from_xyz(0.7, 0.7, -1.0) .looking_at(Vec3::new(0.0, 0.3, 0.0), Vec3::Y); CiTestingEventOnFrame( fps * 6, ci_testing::CiTestingEvent::MoveCamera { translation: transform.translation, rotation: transform.rotation, }, ) }, { let transform = Transform::from_xyz(-0.7, 0.7, -1.0) .looking_at(Vec3::new(0.0, 0.3, 0.0), Vec3::Y); CiTestingEventOnFrame( fps * 11, ci_testing::CiTestingEvent::MoveCamera { translation: transform.translation, rotation: transform.rotation, }, ) }, { let transform = Transform::from_xyz(-0.7, 0.7, 1.0) .looking_at(Vec3::new(0.0, 0.3, 0.0), Vec3::Y); CiTestingEventOnFrame( fps * 16, ci_testing::CiTestingEvent::MoveCamera { translation: transform.translation, rotation: transform.rotation, }, ) }, { let transform = Transform::from_xyz(0.7, 0.7, 1.0) .looking_at(Vec3::new(0.0, 0.3, 0.0), Vec3::Y); CiTestingEventOnFrame( fps * 21, ci_testing::CiTestingEvent::MoveCamera { translation: transform.translation, rotation: transform.rotation, }, ) }, CiTestingEventOnFrame(fps * 26, ci_testing::CiTestingEvent::StopScreenRecording), ], ..default() }) ``` - Run the example with `--features bevy_internal/screenrecording,bevy_ci_testing` - Lay back, enjoy your demo recording --- ## Showcase https://github.com/user-attachments/assets/bbd9e56d-58c1-41eb-b6b4-1f1db2f2dab5
Objective
Solution
EasyScreenRecordPluginin the dev toolsTesting
bevy_internal/screenrecordingenabledffmpegis our friend!for file in *.h264; do ffmpeg -i $file $file.mp4; doneShowcase
directly taken by Bevy
load_gltf-1758937494581.h264.mp4