C#调用FFMPEG实现桌面录制(视频+音频+生成本地文件)【笔记】
2016-01-21 16:25
1206 查看
不得不说FFMPEG真是个神奇的玩意,所接触的部分不过万一。网上有个很火的例子是c++方面的,当然这个功能还是用c++来实现比较妥当。
然而我不会c++
因为我的功能需求比较简单,只要实现基本的录制就可以了,其实就是一句命令的事
先来代码:RecordHelper类
开始那几个api接口是用来模拟ctrl+c命令的。本来以为在停止录制的时候直接kill掉进程就好,结果导致生成的视频文件直接损坏了。手动使用ffmpeg.exe的时候发现ctrl+c可以直接结束录制并且不会损坏视频文件,于是采用这种方法,在点击停止按钮时模拟ctrl+c来退出ffmpeg。
ffmpeg的命令参数里,gdigrab是ffmpeg内置的屏幕录制设备,但是这个设备不能同时采集音频,于是又用到了后面的dshow。这里有个问题很奇怪,用ffmpeg获取音频设备列表时,设备的名称如果超过31个字符的话会被截断,而若是将完整的设备名传到参数里则无法进行音频采集,只能将截断的设备名称传进去,不知道为什么……
然而我不会c++
因为我的功能需求比较简单,只要实现基本的录制就可以了,其实就是一句命令的事
先来代码:RecordHelper类
using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using Microsoft.DirectX; using Microsoft.DirectX.DirectSound; using System.Runtime.InteropServices; namespace ClassTool { public class RecordHelper { #region 模拟控制台信号需要使用的api [DllImport("kernel32.dll")] static extern bool GenerateConsoleCtrlEvent(int dwCtrlEvent, int dwProcessGroupId); [DllImport("kernel32.dll")] static extern bool SetConsoleCtrlHandler(IntPtr handlerRoutine, bool add); [DllImport("kernel32.dll")] static extern bool AttachConsole(int dwProcessId); [DllImport("kernel32.dll")] static extern bool FreeConsole(); #endregion // ffmpeg进程 static Process p = new Process(); // ffmpeg.exe实体文件路径 static string ffmpegPath = AppDomain.CurrentDomain.BaseDirectory + "ffmpeg\\ffmpeg.exe"; /// <summary> /// 获取声音输入设备列表 /// </summary> /// <returns>声音输入设备列表</returns> public static CaptureDevicesCollection GetAudioList() { CaptureDevicesCollection collection = new CaptureDevicesCollection(); return collection; } /// <summary> /// 功能: 开始录制 /// </summary> public static void Start(string audioDevice, string outFilePath) { if (File.Exists(outFilePath)) { File.Delete(outFilePath); } /*转码,视频录制设备:gdigrab;录制对象:桌面; * 音频录制方式:dshow; * 视频编码格式:h.264;*/ ProcessStartInfo startInfo = new ProcessStartInfo(ffmpegPath); startInfo.WindowStyle = ProcessWindowStyle.Normal; startInfo.Arguments = "-f gdigrab -framerate 15 -i desktop -f dshow -i audio=\"" + audioDevice + "\" -vcodec libx264 -preset:v ultrafast -tune:v zerolatency -acodec libmp3lame \"" + outFilePath + "\""; p.StartInfo = startInfo; p.Start(); } /// <summary> /// 功能: 停止录制 /// </summary> public static void Stop() { AttachConsole(p.Id); SetConsoleCtrlHandler(IntPtr.Zero, true); GenerateConsoleCtrlEvent(0, 0); FreeConsole(); } } }
开始那几个api接口是用来模拟ctrl+c命令的。本来以为在停止录制的时候直接kill掉进程就好,结果导致生成的视频文件直接损坏了。手动使用ffmpeg.exe的时候发现ctrl+c可以直接结束录制并且不会损坏视频文件,于是采用这种方法,在点击停止按钮时模拟ctrl+c来退出ffmpeg。
ffmpeg的命令参数里,gdigrab是ffmpeg内置的屏幕录制设备,但是这个设备不能同时采集音频,于是又用到了后面的dshow。这里有个问题很奇怪,用ffmpeg获取音频设备列表时,设备的名称如果超过31个字符的话会被截断,而若是将完整的设备名传到参数里则无法进行音频采集,只能将截断的设备名称传进去,不知道为什么……
相关文章推荐
- AWS 之 S3篇<.NET(c#)批量上传文件>
- C# 利用 OpenCV 进行视频捕获 (笔记)
- RickTextBox控件基础用法
- 伸展二叉树树(C#)
- C#的Enum——枚举
- C#获取当前日期时间(转)
- C#delegate委托
- c# 导入Excel 存到DataTable并进行行转列操作及合并DataTable相同行的值
- C# new用法总结
- C#创建、安装一个Windows服务
- C#数组初始化(全)
- C#反射
- C#中计算时间差
- C# - ref
- C# word 操作页脚书签
- C# 线程知识--使用Task执行异步操作
- C#中数据类型的基本了解
- string.Format对C#字符串格式化
- C# 改变图片尺寸(压缩),Image Resize
- C#内存分配学习