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 "";
}
}
}
}