C#FFMPEG流程和多个文件

时间:2016-11-03 00:53:59

标签: c# winforms asynchronous process ffmpeg

我正在开发一个C#Form工具,它可以帮助我将所有手机和DSLR视频转换为HEVC,目前,我有一个程序,每次连接到我的家庭服务器时,都会将照片和视频上传到我的家庭服务器的不同目录WiFi。一个月左右,我手动转换所有视频,但我想我会自动化这个过程..我有完美的表格处理1文件。但是在处理目录(包括可能的子目录)时会遇到麻烦..

对不起,这很长,只想彻底。这是按钮调用

private void processFile_Click(object sender, EventArgs e)
    {
        OpenFileDialog file = new OpenFileDialog();
        file.InitialDirectory = baseMediaDirectory;
        if (file.ShowDialog() == DialogResult.OK)
        {
            ProcessSinlgeFile(file.FileName);
        }
    }

(上面)用于一个文件,(下面)用于目录

private void processDirectory_Click(object sender, EventArgs e)
{
    FolderBrowserDialog file = new FolderBrowserDialog();
    file.SelectedPath = baseMediaDirectory;
    if(file.ShowDialog() == DialogResult.OK)
    {
       ProcessDirectoryOfFiles(file.SelectedPath);
    }
}

private void ProcessDirectoryOfFiles(string selectedPath)
    {
        List<string> listOfFiles = GetAllFiles(selectedPath);
        foreach (string s in listOfFiles)
        {
            ProcessSinlgeFile(s);
        }
    }

最终都会调用此方法,进行一些检查和设置

private void ProcessSinlgeFile(string fileName)
    {

        if (IsAcceptableMediaFile(fileName))
        {
            outputWindow.AppendText("File to Process: " + fileName);
            processMediaFile = 
                new MediaFileWrapper(this.outputWindow, new MediaFile(fileName), new NReco.VideoInfo.FFProbe());
            if (processMediaFile.OkToProcess)
            {
                int initialCRFValue = 15;
                //ultrafast superfast veryfast faster fast medium slow slower veryslow placebo
                string intialSpeed = "veryfast";
                try {

                    ConvertToMPEG(processMediaFile.getFFMPEGCommand(initialCRFValue, intialSpeed), processMediaFile);
                }
                catch
                {
                    // at somepoint, we'll catch a bad file size (or compression)
                    // then change the CRF value and/or compression speed
                }
            }
        }
    }

最终我接触到这个方法并遇到麻烦。

    private async void ConvertToMPEG(string arguments, MediaFileWrapper processMediaFile)
    {
        startTime = DateTime.Now;
        watch = new Stopwatch();
        watch.Start();
        progressBar1.Minimum = 0;
        progressBar1.Maximum = processMediaFile.GetTotalMilliseconds();

        // Start the child process.
        p = new Process();

        //Setup filename and arguments
        outputWindow.AppendText("ffmpeg " + arguments);
        p.StartInfo.Arguments = arguments;
        p.StartInfo.FileName = "ffmpeg.exe";
        p.StartInfo.UseShellExecute = false;

        // Redirect the output stream of the child process.
        p.StartInfo.RedirectStandardOutput = true;
        p.StartInfo.RedirectStandardError = true;
        p.StartInfo.RedirectStandardInput = true;

        // capture the date for stdout and std error
        // note FFMPEG uses Stderr exclusively
        p.ErrorDataReceived += new DataReceivedEventHandler(ErrorDataReceived);
        p.OutputDataReceived += new DataReceivedEventHandler(OutputDataReceived);

        // Hide Console Window
        p.StartInfo.CreateNoWindow = true;
        p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;

        p.Start();
        p.BeginErrorReadLine();
        p.BeginOutputReadLine();
        await p.WaitForExitAsync();
    }

和WaitForExitAsync在另一个类中,因为在这里不能使用Form

    public static Task WaitForExitAsync(this Process process,
        CancellationToken cancellationToken = default(CancellationToken))
    {
        var tcs = new TaskCompletionSource<object>();
        process.EnableRaisingEvents = true;
        process.Exited += (sender, args) => tcs.TrySetResult(null);
        if (cancellationToken != default(CancellationToken))
            cancellationToken.Register(tcs.SetCanceled);

        return tcs.Task;
    }

但是,单个文件工作正常,当我调用目录时,它会不断启动每个文件的进程,同时尝试全部运行它们。你可以看到我尝试实现这个 process.WaitForExit() asynchronously 没有运气。

0 个答案:

没有答案