using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using VisioForge.Shared.NAudio.CoreAudioApi; using VisioForge.Shared.NAudio.Wave; namespace Common.system { /// /// ffmpeg帮助类 /// 需要安装\ffmpeg\bin\Setup Screen Capturer Recorder v0.12.10.exe /// 本地调试需要配置环境变量 将ffmpeg.exe位置配置到环境变量的path中 /// public class FFMpeg { Process myProcess = null; /// /// 录屏 /// /// 文件存储路径 public void RunFFmpeg(string PathName) { Process[] KillProcessArray = Process.GetProcessesByName("ffmpeg"); Debug.WriteLine(KillProcessArray.Length.ToString()); foreach (var KillProcess in KillProcessArray) { KillProcess.Kill(); } myProcess = new Process(); string MicrophoneName = GetMicrophone(); myProcess.StartInfo.FileName = FileToolsCommon.GetFileAbsolutePath(@"/ffmpeg/bin/ffmpeg.exe"); //ffmpeg.exe的绝对路径 if(string.IsNullOrWhiteSpace(MicrophoneName)) { myProcess.StartInfo.Arguments = "-f dshow -i video=\"screen-capture-recorder\" -f dshow -i audio=\"virtual-audio-capturer\" -vcodec libx264 -acodec libmp3lame -r 15 -crf 22 -f avi " + PathName; //ffmpeg的参数 } else { myProcess.StartInfo.Arguments = "-f dshow -i audio=\"virtual-audio-capturer\" -f dshow -i audio=\"" + MicrophoneName + "\" -filter_complex amix=inputs=2:duration=first:dropout_transition=2 -f dshow -i video=\"screen-capture-recorder\" -pix_fmt yuv420p -vcodec h264 -preset:v ultrafast -tune:v zerolatency -acodec aac -ar 44100 -ac 2 -f avi " + PathName; //ffmpeg的参数 } myProcess.StartInfo.UseShellExecute = false; //不使用操作系统外壳程序启动 myProcess.StartInfo.RedirectStandardError = true; //重定向标准错误输出 myProcess.StartInfo.CreateNoWindow = true; //不显示程序窗口 myProcess.StartInfo.RedirectStandardInput = true; //用于模拟该进程控制台的输入 myProcess.ErrorDataReceived += new DataReceivedEventHandler(Output); myProcess.Start(); myProcess.BeginErrorReadLine(); } /// /// 停止录制 /// public void StopFFmpeg() { //Thread.Sleep(3000); if (myProcess == null) return; myProcess.StandardInput.WriteLine("q");//在这个进程的控制台中模拟输入q,用于暂停录制 myProcess.Close(); myProcess.Dispose(); myProcess = null; //myProcess.Kill(); } /// /// 输出结果 /// /// /// private void Output(object sendProcess, DataReceivedEventArgs output) { if (!String.IsNullOrEmpty(output.Data)) Debug.WriteLine(output.Data.ToString()); } /// /// 合成视频 /// /// 图片列表位置 命名为1.png /// MP3音频位置 /// 视频保存位置 /// 每秒帧率 private void SynthesisVideo(string ImageListPath,string Mp3Path,string VideoSavePath,int frequency) { Process[] KillProcessArray = Process.GetProcessesByName("ffmpeg"); Debug.WriteLine(KillProcessArray.Length.ToString()); foreach (var KillProcess in KillProcessArray) { KillProcess.Kill(); } Process myProcess = new Process(); this.myProcess.StartInfo.FileName = FileToolsCommon.GetFileAbsolutePath(@"/ffmpeg/bin/ffmpeg.exe"); //ffmpeg.exe的绝对路径 myProcess.StartInfo.Arguments = @"-y -r "+ frequency + " -i " + ImageListPath + @"%d.png -i " + Mp3Path + @" -s 800x800 -vcodec mpeg4 " + VideoSavePath; myProcess.StartInfo.UseShellExecute = false; myProcess.StartInfo.RedirectStandardError = true; myProcess.StartInfo.CreateNoWindow = true; //外部程序(这里是FFMPEG)输出流时候产生的事件,这里是把流的处理过程转移到下面的方法中,详细请查阅MSDN myProcess.ErrorDataReceived += new DataReceivedEventHandler(Output); //p.ErrorDataReceived += new DataReceivedEventHandler((s, message) => { Console.WriteLine(message.Data); }); myProcess.Start();//启动线程 myProcess.BeginErrorReadLine();//开始异步读取 myProcess.WaitForExit();//阻塞等待进程结束 myProcess.Close();//关闭进程 myProcess.Dispose();//释放资源 } //private void P_ErrorDataReceived(object sender, DataReceivedEventArgs e) //{ // //+= new DataReceivedEventHandler((s, message) => { Console.WriteLine(message.Data); }) // using (StreamWriter fs = new StreamWriter("E:\\项目\\测试\\Wpf测试\\bin\\Debug\\ffmpeg\\log.txt", true)) // { // fs.WriteLine(e.Data); // } //} /// /// 获取麦克风 /// string GetMicrophone() { List devs = new List(); MMDeviceEnumerator enumberator = new MMDeviceEnumerator(); MMDeviceCollection deviceCollection = enumberator.EnumerateAudioEndPoints(DataFlow.Capture, DeviceState.All); for (int waveInDevice = 0; waveInDevice < WaveIn.DeviceCount; waveInDevice++) { WaveInCapabilities deviceInfo = WaveIn.GetCapabilities(waveInDevice); foreach (MMDevice device in deviceCollection) { try { if (device.FriendlyName.StartsWith(deviceInfo.ProductName)) { devs.Add(device.FriendlyName); break; } } catch (Exception) { } } } if (devs.Count > 0) { return devs[0]; } else { return ""; } } } }