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

时间:2010-03-18 16:37:59

标签: c# asp.net ffmpeg pipe deadlock

ffmpeg感觉好像花了很长时间。然后我看看我的输出文件,我看到它在6到8mb之间停止。完全编码的文件大约是14mb。为什么ffmpeg会停止?我的代码锁定了StandardOutput.ReadToEnd();.我不得不杀死这个过程(看到它不会移动超过10秒,当我看到它每秒更新一次)然后我得到stdout和错误的结果。 stdout是“”stderr在下面。

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

注意:我必须先退出并检查是否有错误。

    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;
    }

stderr的输出。 stdout是空的。

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    

1 个答案:

答案 0 :(得分:6)

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

来自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();
  

代码示例避免了死锁   条件通过执行异步   读取StandardOutput上的操作   流。导致死锁情况   如果父进程调用   p.StandardOutput.ReadToEnd后跟   p.StandardError.ReadToEnd和   子进程写入足够的文本   填写错误流。父母   过程会无限期地等待   孩子关闭它的过程   StandardOutput流。孩子   过程会无限期地等待   父母要完整阅读   StandardError流。

     

您可以使用异步读取   避免这些依赖关系的操作   和他们的僵局潜力。   或者,你可以避免   通过创建两个来实现死锁条件   线程和读取每个的输出   在一个单独的线程上流。

UPDATE :当我使用ffmpeg时,我为它编写了一个包装器。主要思想是解析stderr的每个输出行。因此,我能够识别转换死锁并在必要时手动终止转换过程。 它还可用于获取其他媒体信息,如持续时间和使用的编解码器。

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

希望,这有帮助。