星火微课系统客户端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

FFMpeg.cs 6.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.Linq;
  5. using System.Text;
  6. using VisioForge.Shared.NAudio.CoreAudioApi;
  7. using VisioForge.Shared.NAudio.Wave;
  8. namespace Common.system
  9. {
  10. /// <summary>
  11. /// ffmpeg帮助类
  12. /// 需要安装\ffmpeg\bin\Setup Screen Capturer Recorder v0.12.10.exe
  13. /// 本地调试需要配置环境变量 将ffmpeg.exe位置配置到环境变量的path中
  14. /// </summary>
  15. public class FFMpeg
  16. {
  17. Process myProcess = null;
  18. /// <summary>
  19. /// 录屏
  20. /// </summary>
  21. /// <param name="PathName">文件存储路径</param>
  22. public void RunFFmpeg(string PathName)
  23. {
  24. Process[] KillProcessArray = Process.GetProcessesByName("ffmpeg");
  25. Debug.WriteLine(KillProcessArray.Length.ToString());
  26. foreach (var KillProcess in KillProcessArray)
  27. {
  28. KillProcess.Kill();
  29. }
  30. myProcess = new Process();
  31. string MicrophoneName = GetMicrophone();
  32. myProcess.StartInfo.FileName = FileToolsCommon.GetFileAbsolutePath(@"/ffmpeg/bin/ffmpeg.exe"); //ffmpeg.exe的绝对路径
  33. if(string.IsNullOrWhiteSpace(MicrophoneName))
  34. {
  35. 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的参数
  36. }
  37. else
  38. {
  39. 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的参数
  40. }
  41. myProcess.StartInfo.UseShellExecute = false; //不使用操作系统外壳程序启动
  42. myProcess.StartInfo.RedirectStandardError = true; //重定向标准错误输出
  43. myProcess.StartInfo.CreateNoWindow = true; //不显示程序窗口
  44. myProcess.StartInfo.RedirectStandardInput = true; //用于模拟该进程控制台的输入
  45. myProcess.ErrorDataReceived += new DataReceivedEventHandler(Output);
  46. myProcess.Start();
  47. myProcess.BeginErrorReadLine();
  48. }
  49. /// <summary>
  50. /// 停止录制
  51. /// </summary>
  52. public void StopFFmpeg()
  53. {
  54. //Thread.Sleep(3000);
  55. if (myProcess == null)
  56. return;
  57. myProcess.StandardInput.WriteLine("q");//在这个进程的控制台中模拟输入q,用于暂停录制
  58. myProcess.Close();
  59. myProcess.Dispose();
  60. myProcess = null;
  61. //myProcess.Kill();
  62. }
  63. /// <summary>
  64. /// 输出结果
  65. /// </summary>
  66. /// <param name="sendProcess"></param>
  67. /// <param name="output"></param>
  68. private void Output(object sendProcess, DataReceivedEventArgs output)
  69. {
  70. if (!String.IsNullOrEmpty(output.Data))
  71. Debug.WriteLine(output.Data.ToString());
  72. }
  73. /// <summary>
  74. /// 合成视频
  75. /// </summary>
  76. /// <param name="ImageListPath">图片列表位置 命名为1.png</param>
  77. /// <param name="Mp3Path">MP3音频位置</param>
  78. /// <param name="VideoSavePath">视频保存位置</param>
  79. /// <param name="frequency">每秒帧率</param>
  80. private void SynthesisVideo(string ImageListPath,string Mp3Path,string VideoSavePath,int frequency)
  81. {
  82. Process[] KillProcessArray = Process.GetProcessesByName("ffmpeg");
  83. Debug.WriteLine(KillProcessArray.Length.ToString());
  84. foreach (var KillProcess in KillProcessArray)
  85. {
  86. KillProcess.Kill();
  87. }
  88. Process myProcess = new Process();
  89. this.myProcess.StartInfo.FileName = FileToolsCommon.GetFileAbsolutePath(@"/ffmpeg/bin/ffmpeg.exe"); //ffmpeg.exe的绝对路径
  90. myProcess.StartInfo.Arguments = @"-y -r "+ frequency + " -i " +
  91. ImageListPath + @"%d.png -i " +
  92. Mp3Path + @" -s 800x800 -vcodec mpeg4 " +
  93. VideoSavePath;
  94. myProcess.StartInfo.UseShellExecute = false;
  95. myProcess.StartInfo.RedirectStandardError = true;
  96. myProcess.StartInfo.CreateNoWindow = true;
  97. //外部程序(这里是FFMPEG)输出流时候产生的事件,这里是把流的处理过程转移到下面的方法中,详细请查阅MSDN
  98. myProcess.ErrorDataReceived += new DataReceivedEventHandler(Output);
  99. //p.ErrorDataReceived += new DataReceivedEventHandler((s, message) => { Console.WriteLine(message.Data); });
  100. myProcess.Start();//启动线程
  101. myProcess.BeginErrorReadLine();//开始异步读取
  102. myProcess.WaitForExit();//阻塞等待进程结束
  103. myProcess.Close();//关闭进程
  104. myProcess.Dispose();//释放资源
  105. }
  106. //private void P_ErrorDataReceived(object sender, DataReceivedEventArgs e)
  107. //{
  108. // //+= new DataReceivedEventHandler((s, message) => { Console.WriteLine(message.Data); })
  109. // using (StreamWriter fs = new StreamWriter("E:\\项目\\测试\\Wpf测试\\bin\\Debug\\ffmpeg\\log.txt", true))
  110. // {
  111. // fs.WriteLine(e.Data);
  112. // }
  113. //}
  114. /// <summary>
  115. /// 获取麦克风
  116. /// </summary>
  117. string GetMicrophone()
  118. {
  119. List<string> devs = new List<string>();
  120. MMDeviceEnumerator enumberator = new MMDeviceEnumerator();
  121. MMDeviceCollection deviceCollection = enumberator.EnumerateAudioEndPoints(DataFlow.Capture, DeviceState.All);
  122. for (int waveInDevice = 0; waveInDevice < WaveIn.DeviceCount; waveInDevice++)
  123. {
  124. WaveInCapabilities deviceInfo = WaveIn.GetCapabilities(waveInDevice);
  125. foreach (MMDevice device in deviceCollection)
  126. {
  127. try
  128. {
  129. if (device.FriendlyName.StartsWith(deviceInfo.ProductName))
  130. {
  131. devs.Add(device.FriendlyName);
  132. break;
  133. }
  134. }
  135. catch (Exception)
  136. {
  137. }
  138. }
  139. }
  140. if (devs.Count > 0)
  141. {
  142. return devs[0];
  143. }
  144. else
  145. {
  146. return "";
  147. }
  148. }
  149. }
  150. }