Почему ffmpeg останавливается случайно в середине процесса? - PullRequest
2 голосов
/ 18 марта 2010

ffmpeg чувствует, что это занимает много времени. Затем я смотрю на свой выходной файл и вижу, что он останавливается между 6 и 8 Мбит / с. Полностью закодированный файл составляет около 14 МБ. Почему ffmpeg останавливается? Мой код блокируется на StandardOutput.ReadToEnd () ;. Мне пришлось убить процесс (увидев, что он не двигается более 10 секунд, когда я вижу, что он обновляется каждую секунду ранее), затем я получаю результаты stdout и err. стандартный вывод "" стандартный вывод ниже.

Выходные сообщения показывают, что размер файла завершен. Я также вижу падение использования моего процессора, когда он останавливается. Я скопировал аргумент из визуальных студий. 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. стандартный вывод пуст.

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 Ответ

6 голосов
/ 18 марта 2010

Предположим, вы зашли в тупик.

Ссылка от 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 и дочерний процесс пишет достаточно текста заполните поток ошибок. Родитель процесс будет ждать бесконечно дочерний процесс, чтобы закрыть его Стандартный выходной поток. Ребенок процесс будет ждать бесконечно родитель читать полностью Стандартный поток ошибок.

Вы можете использовать асинхронное чтение операции, чтобы избежать этих зависимостей и их тупиковый потенциал. С другой стороны, вы можете избежать тупиковое состояние путем создания двух темы и чтение результатов каждого поток в отдельном потоке.

ОБНОВЛЕНИЕ : когда я работал с ffmpeg, я написал для него оболочку. Основная идея заключалась в том, чтобы разобрать каждую строку вывода с stderr. Благодаря этому я смог распознать тупики конверсии и вручную убить процесс конвертации при необходимости. Также полезно получить дополнительную информацию о мультимедиа, такую ​​как длительность и используемые кодеки.

UPDATE2 (угадайте последнее;)): как я упоминал выше, я использовал stderr в асинхронном режиме для разбора вывода. Кроме того, stdout использовался в обычном (среднем, а не асинхронном) режиме для получения результата генерации предварительного просмотра видео (функция ffmpeg) для получения результата без использования временного файла.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...