fix: video recording captures every frame + dynamic FPS for FFmpeg
- Removed skipFrames logic — capture every frame for reliability - FFmpeg framerate set to actual FPS (capped at 60) instead of hardcoded 30 - Added -vf fps=30 filter to downsample to 30fps in output - First frame: CapturedFrame is null (no previous capture), skipped naturally - Second frame onwards: data available from previous frame's GPU copy
This commit is contained in:
Binary file not shown.
@@ -328,7 +328,8 @@ class Program
|
|||||||
|
|
||||||
var w = window.Width;
|
var w = window.Width;
|
||||||
var h = window.Height;
|
var h = window.Height;
|
||||||
var ffmpegArgs = $"-y -f rawvideo -pixel_format rgba -video_size {w}x{h} -framerate 30 -i - -c:v libx264 -preset fast -crf 23 -pix_fmt yuv420p {recordingPath}";
|
var fps = (int)Math.Round(1000.0 / timing.DeltaTime);
|
||||||
|
var ffmpegArgs = $"-y -f rawvideo -pixel_format rgba -video_size {w}x{h} -framerate {Math.Min(fps, 60)} -i - -c:v libx264 -preset fast -crf 23 -pix_fmt yuv420p -vf fps=30 {recordingPath}";
|
||||||
|
|
||||||
var psi = new ProcessStartInfo
|
var psi = new ProcessStartInfo
|
||||||
{
|
{
|
||||||
@@ -388,30 +389,25 @@ class Program
|
|||||||
|
|
||||||
renderer.RenderWorld(world);
|
renderer.RenderWorld(world);
|
||||||
queue.CompletePendingScreenshots();
|
queue.CompletePendingScreenshots();
|
||||||
|
|
||||||
// If recording, get captured frame and write to FFmpeg
|
// If recording, get captured frame and write to FFmpeg
|
||||||
if (isRecording && ffmpegProcess != null && !ffmpegProcess.HasExited)
|
if (isRecording && ffmpegProcess != null && !ffmpegProcess.HasExited)
|
||||||
{
|
{
|
||||||
skipFrames++;
|
var frameData = vkRenderer.CapturedFrame;
|
||||||
if (skipFrames >= 2) // Capture every 2nd frame for 30fps at ~60fps
|
if (frameData != null && frameData.Length > 0)
|
||||||
{
|
{
|
||||||
skipFrames = 0;
|
try
|
||||||
var frameData = vkRenderer.CapturedFrame;
|
|
||||||
if (frameData != null && frameData.Length > 0)
|
|
||||||
{
|
{
|
||||||
try
|
ffmpegProcess.StandardInput.BaseStream.Write(frameData, 0, frameData.Length);
|
||||||
{
|
ffmpegProcess.StandardInput.BaseStream.Flush();
|
||||||
ffmpegProcess.StandardInput.BaseStream.Write(frameData, 0, frameData.Length);
|
recordedFrames++;
|
||||||
ffmpegProcess.StandardInput.BaseStream.Flush();
|
|
||||||
recordedFrames++;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"[App] FFmpeg write error: {ex.Message}");
|
|
||||||
isRecording = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} }
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"[App] FFmpeg write error: {ex.Message}");
|
||||||
|
isRecording = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
frames++;
|
frames++;
|
||||||
if (timing.TotalTime - lastFpsTime >= 1.0)
|
if (timing.TotalTime - lastFpsTime >= 1.0)
|
||||||
|
|||||||
Reference in New Issue
Block a user