为什么 ffmpeg 在进程中随机停止?

发布于 2024-08-25 06:33:24 字数 5549 浏览 8 评论 0原文

ffmpeg 感觉花了很长时间。然后我查看输出文件,发现它停在 6 到 8mbs 之间。完整编码的文件大约为 14mb。为什么 ffmpeg 停止了?我的代码锁定在 StandardOutput.ReadToEnd(); 上。我不得不终止该进程(当我看到它之前每秒更新一次时,它已经不动了超过 10 秒),然后我得到了 stdout 和 err 的结果。标准输出是“”标准错误如下。

输出消息显示文件大小已结束。当它停止时,我还发现 CPU 使用率下降。我复制了视觉工作室的论点。 CD 到同一工作目录并运行 cmd (bin/ffmpeg) 并粘贴参数。它能够完成。

注意:我必须取出 std 和 err 来检查故障。

    int soundProcess(string infn, string outfn)
    {
        string aa, aa2;
        aa = aa2 = "DEAD";

        var app = new Process();

        app.StartInfo.UseShellExecute = false;
        app.StartInfo.RedirectStandardOutput = true;
        app.StartInfo.RedirectStandardError = true;
        //*/
        app.StartInfo.FileName = @"bin\ffmpeg.exe";
        app.StartInfo.Arguments = string.Format(@"-i ""{0}"" -ab 192k -y {2} ""{1}""", infn, outfn, param);
        app.Start();
        try
        {
            app.PriorityClass = ProcessPriorityClass.BelowNormal;
        }
        catch (Exception ex)
        {
            if (!Regex.IsMatch(ex.Message, @"Cannot process request because the process .*has exited"))
                throw ex;
        }

        aa = app.StandardOutput.ReadToEnd();
        aa2 = app.StandardError.ReadToEnd();

        app.WaitForExit();

        if (aa2.IndexOf("could not find codec parameters") != -1)
            return 1;
        else if (aa == "DEAD" || aa2 == "DEAD")
            return -1;
        else if (aa2.Length != 0)
            return -2;
        else
            return 0;
    }

标准错误的输出。标准输出为空。

FFmpeg version SVN-r15815, Copyright (c) 2000-2008 Fabrice Bellard, et al.
  configuration: --enable-memalign-hack --enable-postproc --enable-swscale --enable-gpl --enable-libfaac --enable-libfaad --enable-libgsm --enable-libmp3lame --enable-libvorbis --enable-libtheora --enable-libx264 --enable-libxvid --disable-ffserver --disable-vhook --enable-avisynth --enable-pthreads
  libavutil     49.12. 0 / 49.12. 0
  libavcodec    52. 3. 0 / 52. 3. 0
  libavformat   52.23. 1 / 52.23. 1
  libavdevice   52. 1. 0 / 52. 1. 0
  libswscale     0. 6. 1 /  0. 6. 1
  libpostproc   51. 2. 0 / 51. 2. 0
  built on Nov 13 2008 10:28:29, gcc: 4.2.4 (TDM-1 for MinGW)
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'C:\dev\src\trunk\prjname\prjname\App_Data/temp/m/o/6304266424778814852':
  Duration: 00:12:53.36, start: 0.000000, bitrate: 154 kb/s
    Stream #0.0(und): Audio: aac, 44100 Hz, stereo, s16
Output #0, ipod, to 'C:\dev\src\trunk\prjname\prjname\App_Data\temp\m\o\2.m4a':
    Stream #0.0(und): Audio: libfaac, 44100 Hz, stereo, s16, 192 kb/s
Stream mapping:
  Stream #0.0 -> #0.0
Press [q] to stop encoding
size=      87kB time=4.74 bitrate= 150.7kbits/s    
size=     168kB time=9.06 bitrate= 151.9kbits/s    
size=     265kB time=14.28 bitrate= 151.8kbits/s    
size=     377kB time=20.29 bitrate= 152.1kbits/s    
size=     487kB time=26.22 bitrate= 152.1kbits/s    
size=     594kB time=32.02 bitrate= 152.1kbits/s    
size=     699kB time=37.64 bitrate= 152.1kbits/s    
size=     808kB time=43.54 bitrate= 152.0kbits/s    
size=     930kB time=50.09 bitrate= 152.2kbits/s    
size=    1058kB time=57.05 bitrate= 152.0kbits/s    
size=    1193kB time=64.23 bitrate= 152.1kbits/s    
size=    1329kB time=71.63 bitrate= 152.0kbits/s    
size=    1450kB time=78.16 bitrate= 152.0kbits/s    
size=    1578kB time=85.05 bitrate= 152.0kbits/s    
size=    1706kB time=92.00 bitrate= 152.0kbits/s    
size=    1836kB time=98.94 bitrate= 152.0kbits/s    
size=    1971kB time=106.25 bitrate= 151.9kbits/s    
size=    2107kB time=113.57 bitrate= 152.0kbits/s    
size=    2214kB time=119.33 bitrate= 152.0kbits/s    
size=    2345kB time=126.39 bitrate= 152.0kbits/s    
size=    2479kB time=133.56 bitrate= 152.0kbits/s    
size=    2611kB time=140.76 bitrate= 152.0kbits/s    
size=    2745kB time=147.91 bitrate= 152.1kbits/s    
size=    2880kB time=155.20 bitrate= 152.0kbits/s    
size=    3013kB time=162.40 bitrate= 152.0kbits/s    
size=    3146kB time=169.58 bitrate= 152.0kbits/s    
size=    3277kB time=176.61 bitrate= 152.0kbits/s    
size=    3412kB time=183.90 bitrate= 152.0kbits/s    
size=    3540kB time=190.80 bitrate= 152.0kbits/s    
size=    3670kB time=197.81 bitrate= 152.0kbits/s    
size=    3805kB time=205.08 bitrate= 152.0kbits/s    
size=    3932kB time=211.93 bitrate= 152.0kbits/s    
size=    4052kB time=218.38 bitrate= 152.0kbits/s    
size=    4171kB time=224.82 bitrate= 152.0kbits/s    
size=    4277kB time=230.55 bitrate= 152.0kbits/s    
size=    4378kB time=235.96 bitrate= 152.0kbits/s    
size=    4486kB time=241.79 bitrate= 152.0kbits/s    
size=    4592kB time=247.50 bitrate= 152.0kbits/s    
size=    4698kB time=253.21 bitrate= 152.0kbits/s    
size=    4804kB time=258.95 bitrate= 152.0kbits/s    
size=    4906kB time=264.41 bitrate= 152.0kbits/s    
size=    5012kB time=270.09 bitrate= 152.0kbits/s    
size=    5118kB time=275.85 bitrate= 152.0kbits/s    
size=    5234kB time=282.10 bitrate= 152.0kbits/s    
size=    5331kB time=287.39 bitrate= 151.9kbits/s    
size=    5445kB time=293.55 bitrate= 152.0kbits/s    
size=    5555kB time=299.40 bitrate= 152.0kbits/s    
size=    5665kB time=305.37 bitrate= 152.0kbits/s    
size=    5766kB time=310.80 bitrate= 152.0kbits/s    
size=    5876kB time=316.70 bitrate= 152.0kbits/s    
size=    5984kB time=322.50 bitrate= 152.0kbits/s    
size=    6094kB time=328.49 bitrate= 152.0kbits/s    
size=    6212kB time=334.76 bitrate= 152.0kbits/s    
size=    6327kB time=340.99 bitrate= 152.0kbits/s    

ffmpeg feels like its taking a long time. I then look at my output file and i see it stops between 6 and 8mbs. A fully encoded file is about 14mb. Why does ffmpeg stop? My code locks up on StandardOutput.ReadToEnd();. I had to kill the process (after seeing it not move for more then 10 seconds when i see it update every second previously) then i get the results of stdout and err. stdout is "" stderr is below.

The output msg shows the filesize ended. I also see a drop in my CPU usage when it stops. I copyed the argument from visual studios. CD to the same working directory and ran the cmd (bin/ffmpeg) and pasted the argument. It was able to complete.

NOTE: I must get std out and err to check for failures.

    int soundProcess(string infn, string outfn)
    {
        string aa, aa2;
        aa = aa2 = "DEAD";

        var app = new Process();

        app.StartInfo.UseShellExecute = false;
        app.StartInfo.RedirectStandardOutput = true;
        app.StartInfo.RedirectStandardError = true;
        //*/
        app.StartInfo.FileName = @"bin\ffmpeg.exe";
        app.StartInfo.Arguments = string.Format(@"-i ""{0}"" -ab 192k -y {2} ""{1}""", infn, outfn, param);
        app.Start();
        try
        {
            app.PriorityClass = ProcessPriorityClass.BelowNormal;
        }
        catch (Exception ex)
        {
            if (!Regex.IsMatch(ex.Message, @"Cannot process request because the process .*has exited"))
                throw ex;
        }

        aa = app.StandardOutput.ReadToEnd();
        aa2 = app.StandardError.ReadToEnd();

        app.WaitForExit();

        if (aa2.IndexOf("could not find codec parameters") != -1)
            return 1;
        else if (aa == "DEAD" || aa2 == "DEAD")
            return -1;
        else if (aa2.Length != 0)
            return -2;
        else
            return 0;
    }

The output of stderr. stdout is empty.

FFmpeg version SVN-r15815, Copyright (c) 2000-2008 Fabrice Bellard, et al.
  configuration: --enable-memalign-hack --enable-postproc --enable-swscale --enable-gpl --enable-libfaac --enable-libfaad --enable-libgsm --enable-libmp3lame --enable-libvorbis --enable-libtheora --enable-libx264 --enable-libxvid --disable-ffserver --disable-vhook --enable-avisynth --enable-pthreads
  libavutil     49.12. 0 / 49.12. 0
  libavcodec    52. 3. 0 / 52. 3. 0
  libavformat   52.23. 1 / 52.23. 1
  libavdevice   52. 1. 0 / 52. 1. 0
  libswscale     0. 6. 1 /  0. 6. 1
  libpostproc   51. 2. 0 / 51. 2. 0
  built on Nov 13 2008 10:28:29, gcc: 4.2.4 (TDM-1 for MinGW)
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'C:\dev\src\trunk\prjname\prjname\App_Data/temp/m/o/6304266424778814852':
  Duration: 00:12:53.36, start: 0.000000, bitrate: 154 kb/s
    Stream #0.0(und): Audio: aac, 44100 Hz, stereo, s16
Output #0, ipod, to 'C:\dev\src\trunk\prjname\prjname\App_Data\temp\m\o\2.m4a':
    Stream #0.0(und): Audio: libfaac, 44100 Hz, stereo, s16, 192 kb/s
Stream mapping:
  Stream #0.0 -> #0.0
Press [q] to stop encoding
size=      87kB time=4.74 bitrate= 150.7kbits/s    
size=     168kB time=9.06 bitrate= 151.9kbits/s    
size=     265kB time=14.28 bitrate= 151.8kbits/s    
size=     377kB time=20.29 bitrate= 152.1kbits/s    
size=     487kB time=26.22 bitrate= 152.1kbits/s    
size=     594kB time=32.02 bitrate= 152.1kbits/s    
size=     699kB time=37.64 bitrate= 152.1kbits/s    
size=     808kB time=43.54 bitrate= 152.0kbits/s    
size=     930kB time=50.09 bitrate= 152.2kbits/s    
size=    1058kB time=57.05 bitrate= 152.0kbits/s    
size=    1193kB time=64.23 bitrate= 152.1kbits/s    
size=    1329kB time=71.63 bitrate= 152.0kbits/s    
size=    1450kB time=78.16 bitrate= 152.0kbits/s    
size=    1578kB time=85.05 bitrate= 152.0kbits/s    
size=    1706kB time=92.00 bitrate= 152.0kbits/s    
size=    1836kB time=98.94 bitrate= 152.0kbits/s    
size=    1971kB time=106.25 bitrate= 151.9kbits/s    
size=    2107kB time=113.57 bitrate= 152.0kbits/s    
size=    2214kB time=119.33 bitrate= 152.0kbits/s    
size=    2345kB time=126.39 bitrate= 152.0kbits/s    
size=    2479kB time=133.56 bitrate= 152.0kbits/s    
size=    2611kB time=140.76 bitrate= 152.0kbits/s    
size=    2745kB time=147.91 bitrate= 152.1kbits/s    
size=    2880kB time=155.20 bitrate= 152.0kbits/s    
size=    3013kB time=162.40 bitrate= 152.0kbits/s    
size=    3146kB time=169.58 bitrate= 152.0kbits/s    
size=    3277kB time=176.61 bitrate= 152.0kbits/s    
size=    3412kB time=183.90 bitrate= 152.0kbits/s    
size=    3540kB time=190.80 bitrate= 152.0kbits/s    
size=    3670kB time=197.81 bitrate= 152.0kbits/s    
size=    3805kB time=205.08 bitrate= 152.0kbits/s    
size=    3932kB time=211.93 bitrate= 152.0kbits/s    
size=    4052kB time=218.38 bitrate= 152.0kbits/s    
size=    4171kB time=224.82 bitrate= 152.0kbits/s    
size=    4277kB time=230.55 bitrate= 152.0kbits/s    
size=    4378kB time=235.96 bitrate= 152.0kbits/s    
size=    4486kB time=241.79 bitrate= 152.0kbits/s    
size=    4592kB time=247.50 bitrate= 152.0kbits/s    
size=    4698kB time=253.21 bitrate= 152.0kbits/s    
size=    4804kB time=258.95 bitrate= 152.0kbits/s    
size=    4906kB time=264.41 bitrate= 152.0kbits/s    
size=    5012kB time=270.09 bitrate= 152.0kbits/s    
size=    5118kB time=275.85 bitrate= 152.0kbits/s    
size=    5234kB time=282.10 bitrate= 152.0kbits/s    
size=    5331kB time=287.39 bitrate= 151.9kbits/s    
size=    5445kB time=293.55 bitrate= 152.0kbits/s    
size=    5555kB time=299.40 bitrate= 152.0kbits/s    
size=    5665kB time=305.37 bitrate= 152.0kbits/s    
size=    5766kB time=310.80 bitrate= 152.0kbits/s    
size=    5876kB time=316.70 bitrate= 152.0kbits/s    
size=    5984kB time=322.50 bitrate= 152.0kbits/s    
size=    6094kB time=328.49 bitrate= 152.0kbits/s    
size=    6212kB time=334.76 bitrate= 152.0kbits/s    
size=    6327kB time=340.99 bitrate= 152.0kbits/s    

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

那一片橙海, 2024-09-01 06:33:24

假设你在这里遇到了僵局。

来自 MSDN 的参考:

您阅读时也有类似的问题
来自标准输出的所有文本
和标准错误流。这
例如,以下 C# 代码:
对两者执行读取操作
流。

 // Do not perform a synchronous read to the end of both
 // redirected streams.
 // string output = p.StandardOutput.ReadToEnd();
 // string error = p.StandardError.ReadToEnd();
 // p.WaitForExit();
 // Use asynchronous read operations on at least one of the streams.
 p.BeginOutputReadLine();
 string error = p.StandardError.ReadToEnd();
 p.WaitForExit();

代码示例避免了死锁
通过执行异步条件
标准输出上的读取操作
溪流。结果出现死锁情况
如果父进程调用
p.StandardOutput.ReadToEnd 后跟
p.StandardError.ReadToEnd 和
子进程写入足够的文本到
填充其错误流。家长
进程将无限期地等待
子进程关闭它的
标准输出流。孩子
进程将无限期地等待
家长阅读全文
标准错误流。

可以使用异步读取
避免这些依赖性的操作
以及他们的僵局潜力。
或者,您可以避免
通过创建两个死锁条件
线程并读取每个线程的输出
在单独的线程上进行流式传输。

更新:当我使用 ffmpeg 时,我为其编写了一个包装器。主要思想是解析来自 stderr 的每个输出行。因此,我能够识别转换死锁,并在必要时手动终止转换过程。
获取额外的媒体信息(例如持续时间和使用的编解码器)也很有用。

UPDATE2(猜猜最后一个;)):正如我上面提到的,我在异步模式下使用了 stderr 来解析输出。此外,在正常(平均,非异步)模式下使用 stdout 来获取视频预览生成的结果(ffmpeg 的一个功能),以在不使用临时文件的情况下获取结果。

希望这有帮助。

Suppose you caught a deadlock here.

A reference from MSDN:

There is a similar issue when you read
all text from both the standard output
and standard error streams. The
following C# code, for example,
performs a read operation on both
streams.

 // Do not perform a synchronous read to the end of both
 // redirected streams.
 // string output = p.StandardOutput.ReadToEnd();
 // string error = p.StandardError.ReadToEnd();
 // p.WaitForExit();
 // Use asynchronous read operations on at least one of the streams.
 p.BeginOutputReadLine();
 string error = p.StandardError.ReadToEnd();
 p.WaitForExit();

The code example avoids the deadlock
condition by performing asynchronous
read operations on the StandardOutput
stream. A deadlock condition results
if the parent process calls
p.StandardOutput.ReadToEnd followed by
p.StandardError.ReadToEnd and the
child process writes enough text to
fill its error stream. The parent
process would wait indefinitely for
the child process to close its
StandardOutput stream. The child
process would wait indefinitely for
the parent to read from the full
StandardError stream.

You can use asynchronous read
operations to avoid these dependencies
and their deadlock potential.
Alternately, you can avoid the
deadlock condition by creating two
threads and reading the output of each
stream on a separate thread.

UPDATE: when I worked with ffmpeg, I wrote a wrapper to it. The main idea was to parse each output line from stderr. Due to this I was able to recognize conversion deadlocks and manually kill the conversion process when necessary.
It also useful to obtain additional media information like duration and codecs used.

UPDATE2(guess the last ;) ): as I mentioned above I used stderr in async mode to parse output. In addition stdout was used in normal(mean, not async) mode to get the result of video preview generation (a feature of ffmpeg) to get result without using of temporary file.

Hope, this helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文