当前位置: 首页 > 知识库问答 >
问题:

FFmpeg暂停20%的帧提取(但关闭时,将所有帧转储到磁盘)

滕翔飞
2023-03-14

我正在尝试使用FFMPEG从视频中提取帧。我想能够控制哪些帧提取,通过设置开始,结束和FPS值。

问题是,在提取开始后,FFmpeg在大约20%的过程中停止。它总是停在那里,独立于帧计数。

这是我正在使用的代码:

var start = TimeSpan.FromMilliseconds(SelectionSlider.LowerValue);
var end = TimeSpan.FromMilliseconds(SelectionSlider.UpperValue);
var fps = FpsIntegerUpDown.Value;
var count = CountFrames(); //Duration x FPS
var folder = Path.Combine(RootFolder, "Import");
var path = Path.Combine(folder, $"%0{count.ToString().Length + 1}d.png");

try
{
    //Create temporary folder.
    if (Directory.Exists(folder))
        Directory.Delete(folder, true);

    Directory.CreateDirectory(folder);

    CaptureProgressBar.Value = 0;
    CaptureProgressBar.Maximum = count;

    var info = new ProcessStartInfo(UserSettings.All.FfmpegLocation)
    {
        Arguments = $" -i \"{VideoPath}\" -vsync 2 -progress pipe:1 -vf scale={VideoWidth}:{VideoHeight} -ss {start:hh\\:mm\\:ss\\.fff} -to {end:hh\\:mm\\:ss\\.fff} -hide_banner -c:v png -r {fps} -vframes {count} \"{path}\"",
        CreateNoWindow = true,
        ErrorDialog = false,
        UseShellExecute = false,
        RedirectStandardError = true,
        RedirectStandardOutput = true
     };

     _process = new Process();
     _process.OutputDataReceived += (sender, e) =>
     {
         Debug.WriteLine(e.Data);

         if (string.IsNullOrEmpty(e.Data))
             return;

         var parsed = e.Data.Split('=');

         switch (parsed[0])
         {
             case "frame":
                 Dispatcher?.InvokeAsync(() => { CaptureProgressBar.Value = Convert.ToDouble(parsed[1]); });
                 break;

             case "progress":
                 if (parsed[1] == "end" && IsLoaded)
                     GetFiles(folder); //Get all files from the output folder.

                 break;
          }
    };

_process.ErrorDataReceived += (sender, e) =>
{
    if (!string.IsNullOrEmpty(e.Data))
        throw new Exception("Error while capturing frames with FFmpeg.") { HelpLink = $"Command:\n\r{info.Arguments}\n\rResult:\n\r{e.Data}" };
};

_process.StartInfo = info;
_process.Start();
_process.BeginOutputReadLine();

//Just to wait...
await Task.Factory.StartNew(() => _process.WaitForExit());

因此,在开始导入过程后,FFmpeg将提取一些帧,当达到20%左右时,它将暂停提取。

frame=95
fps=5.79
stream_0_0_q=-0.0
bitrate=N/A
total_size=N/A
out_time_us=1400000
out_time_ms=1400000
out_time=00:00:01.400000
dup_frames=0
drop_frames=0
speed=0.0854x

progress=continue
frame=106
fps=6.25
stream_0_0_q=-0.0
bitrate=N/A
total_size=N/A
out_time_us=1583333
out_time_ms=1583333
out_time=00:00:01.583333
dup_frames=0
drop_frames=0
speed=0.0933x
progress=continue

frame=117
fps=6.67
stream_0_0_q=-0.0
bitrate=N/A
total_size=N/A
out_time_us=1766667
out_time_ms=1766667
out_time=00:00:01.766667
dup_frames=0
drop_frames=0
speed=0.101x
progress=continue

PS:在通过cmd使用FFmpeg时不会发生这种情况,所以它一定是代码中的东西。

共有1个答案

孟增
2023-03-14

如果没有通过beginerrorreadline()实际处理其数据,我就不能设置redirectstandarderror=true

所以我只需要设置redirectstandarderror=false,或者添加beginerrorreadline()

 类似资料:
  • 我试图提取帧使用FFMPEG使用以下命令: 它提取帧并以顺序方式分配帧名称,例如0,1,... 作为提取的一部分,是否可以指定实际帧号? 例如,如果ffmpeg提取10、20。。。帧,它应该将其命名为img00010、img00020,而不是img00000、img00001。。。。

  • 输入#0, mov, mp4, m4a,3gp,3g2, mj2, from'instagram.mp4':元数据:major_brand: isomminor_version: 512compatible_brands: isomiso2avc1mp41编码器: Lavf55.19.104持续时间:00:00:13.61,开始: 0.000000,比特率: 1163 kb/s流#0:0(und)

  • 我录制了一段有限时间的视频。现在我想获取所有的视频帧。我使用下面的代码,通过使用它,我能够得到帧,但我没有得到所有的视频帧。但是众所周知,我们可以在一秒钟内获得25-30帧来显示流畅的视频。如何获得所有帧。 我不想使用NDK。我得到了这个链接,不知道“argb888”的值应该是多少。我这里有个错误。有人能解释一下怎么做吗。在Android中从视频图像中获取帧

  • 问题内容: 我将其发布为相关主题下的评论。但是,它们似乎没有引起注意== 我用过 分成存储为文件的帧。似乎行得通,只是不太行。录制视频时,我的录制速率为,而视频却很长。如果我的数学正确,则整个视频总共应为 149,000帧 。可是我跑的时候 我只获得了4472个文件。如何获得原始的149k帧? 我还尝试通过执行以下操作将原始AVI的帧频转换为1000fps 但这似乎并没有解决我的问题。 问题答案: