c# winforms 显示 ffmpeg 输出

c# winforms display ffmpeg output

我正在开发一个可以使用网络摄像头和麦克风录制 video/audio 的应用程序,同时还可以在 winforms 上显示它。

Process.Start(new ProcessStartInfo
            {
                FileName = "ffmpeg",
                Arguments = $"-f dshow -video_size 1280x720 -framerate 30 -vcodec mjpeg -i video=\"{video device}\":audio=\"{audio device}\" -pix_fmt yuv420p -f mp4 -movflags frag_keyframe+empty_moov {output}"
                RedirectStandardError = true,
                RedirectStandardOutput = true,
                UseShellExecute = false,
                CreateNoWindow = true
            });

目前正在使用这个 ffmpeg 命令来录制和保存 mp4。我想知道如果我使用 pipe:1 作为输出而不是文件路径,如何在 winforms 中显示输出流。我以前用过 aforge.Directshow 但是保存的视频质量很差。欢迎就如何执行此操作提出任何其他建议。

这是一个 class,它启动 FF 并将事件处理程序附加到相关的流程事件,以便它可以在生成时查看输出数据。它用于了解音频是否已开始或停止的有趣上下文,这依赖于 ff 有一个扩展程序来监视音频通道并在静音开始或停止时发送消息,但它演示了如何拥有自己的事件在此 class 上,并在 ffmpeg 发送感兴趣的消息时引发它们。大多数情况下 class 只是将输出捕获到日志中

public class FfmpegRecorder 
{
    public event Action SilenceDetected;
    public event Action NoiseDetected;

    private StringBuilder _ffLog = new StringBuilder();
    private Process _ffmpeg;
    private string _streamStats;

    public override void StartRecording()
    {
        ProcessStartInfo psi = new ProcessStartInfo
        {
            FileName = Properties.Settings.Default.CommandLineFfmpegPath,
            Arguments = string.Format(
                Properties.Settings.Default.CommandLineFfmpegArgs,
                OutputPath
            ),
            WindowStyle = ProcessWindowStyle.Hidden,
            CreateNoWindow = true,
            UseShellExecute = false,
            RedirectStandardInput = true,
            RedirectStandardOutput = true,
            RedirectStandardError = true
        };

        _ffmpeg = System.Diagnostics.Process.Start(psi);
        _ffmpeg.OutputDataReceived += Ffmpeg_OutputDataReceived;
        _ffmpeg.ErrorDataReceived += Ffmpeg_ErrorDataReceived;
        _ffmpeg.BeginOutputReadLine();
        _ffmpeg.BeginErrorReadLine();

        _ffmpeg.PriorityClass = ProcessPriorityClass.High;
    }

    void Ffmpeg_OutputDataReceived(object sender, DataReceivedEventArgs e)
    {
        if (e.Data != null && IsInteresting(e.Data))
        {
            _ffLog.Append("STDOUT: ").AppendLine(e.Data);
        }
    }
    void Ffmpeg_ErrorDataReceived(object sender, DataReceivedEventArgs e)
    {
        if (e.Data != null && IsInteresting(e.Data))
        {
            _ffLog.Append("STDERR: ").AppendLine(e.Data);
        }
    }

    bool IsInteresting(string data)
    {
        if (data.StartsWith("frame="))
        {
            _streamStats = data;
            return false;
        }

        try
        {
            if (SilenceDetected != null && data.Contains("silence_start"))
                SilenceDetected();
            else if (NoiseDetected != null && data.Contains("silence_end"))
                NoiseDetected();
        }
        catch { }

        return true;
    }

   

   
}

}

发现vlc 有一个用于winforms 的库。 here is a tutorial on how to add it. for the VlcLibDirectory property you will need to download vlc。 只需将 ffmpeg.StandardOutput.BaseStream 传递到它的播放方法中即可。