gpt4 book ai didi

c# - 如何让 FFMPEG 使用与输入相同的时间来构建视频?

转载 作者:行者123 更新时间:2023-12-04 22:55:57 25 4
gpt4 key购买 nike

我正在尝试通过将屏幕截图从 C# 控制台应用程序传送到 FFMPEG 来创建用户采取的屏幕操作视频。我每秒发送 10 帧。最终视频的帧数与我发送的帧数完全相同(即:10 秒的视频有 100 帧)。但是,视频的时间不匹配。使用下面的代码,我从 490751 ms 的输入中获得了 7m 47s 的视频。我发现 PTS 让我更接近了一点,但感觉就像我做错了什么。

    private const int VID_FRAME_FPS = 10;
private const double PTS = 2.4444;

/// <summary>
/// Generates the Videos by gathering frames and processing via FFMPEG.
/// Deletes the generated Frame images after successfully compiling the video.
/// </summary>
public static void RecordScreen(string pathToOutput)
{
Logger.log.Info("Launching FFMPEG ....");
String arg = "-f image2pipe -i pipe:.bmp -filter:v \"setpts = " + PTS + " * PTS\" -r " + VID_FRAME_FPS + " -pix_fmt yuv420p -qscale:v 5 -vcodec libvpx -bufsize 30000k -y \"" + pathToOutput + "\\VidOut.webm\"";
//String arg = "-f image2pipe -i pipe:.bmp -filter:v \"setpts = " + PTS + " * PTS\" -r " + VID_FRAME_FPS + " -pix_fmt yuv420p -qscale:v 5 -vcodec libx264 -bufsize 30000k -y \"" + pathToOutput + "\\VidOut.mp4\"";
Process launchingFFMPEG = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "ffmpeg",
Arguments = arg,
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardInput = true
}
};
launchingFFMPEG.Start();

System.Drawing.Image img;
Stopwatch stopWatch = Stopwatch.StartNew(); //creates and start the instance of Stopwatch
int sleep;

Stopwatch vidTime = Stopwatch.StartNew();

do
{
img = Capture.GetScreen();
img.Save(launchingFFMPEG.StandardInput.BaseStream, System.Drawing.Imaging.ImageFormat.Bmp);
img.Dispose();

sleep = 10 * VID_FRAME_FPS - (int)stopWatch.ElapsedMilliseconds;
if (sleep > 0)
{
Logger.log.Info("Captured frame, sleeping " + sleep + " milliseconds.");
Thread.Sleep(sleep);
}
stopWatch.Restart();
} while (workerThread.IsAlive);
Logger.log.Debug("Video Time: " + vidTime.ElapsedMilliseconds);
launchingFFMPEG.StandardInput.Flush();
launchingFFMPEG.StandardInput.Close();
launchingFFMPEG.Close();
}

有没有办法在没有 PTS 的情况下做到这一点?如果我需要 PTS,正确的值是多少?似乎 2.565656 的 PTS 接近正确。

所有相关文档都指向仅使用 -r (帧速率命令),但这不起作用(因为我正在使用它)。

注意:我只使用 H.264 进行 ffprobe 调试,我计划在解决此问题后切换回 webm。我试图避免 H.256 和 MP4 专利。

最佳答案

我建议使用以下语法:

String arg = "-f image2pipe -framerate " + VID_FRAME_FPS + " -i pipe:.bmp -pix_fmt yuv420p -qscale:v 5 -vcodec libx264 -bufsize 30000k -y \"" + pathToOutput + "\\VidOut.mp4\"";

这假设发送帧之间的间隔是固定的,即每一帧在前一帧之后 100 毫秒发送。如果有可变的时序或帧速率,则需要使用不同的方法。

顺便说一句,libx264 将忽略 -qscale:v , 所以最好使用 -crf N相反,其中 18 到 28 是 N 的一个很好的范围。

关于c# - 如何让 FFMPEG 使用与输入相同的时间来构建视频?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36635141/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com