最近研究用ffmpeg录制桌面视频,以下是研究时碰到的问题以及成果记录下。
FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。采用LGPL或GPL许可证。它提供了录制、转换以及流化音视频的完整解决方案。它包含了非常先进的音频/视频编解码库libavcodec,为了保证高可移植性和编解码质量,libavcodec里很多code都是从头开发的。
ffmpeg视频采集功能非常强大,不仅可以采集视频采集卡或USB摄像头的图像,还可以进行屏幕录制,同时还支持以RTP方式将视频流传送给支持RTSP的流媒体服务器,支持直播应用。
目前我们使用的是视频采集功能
从cmd命令中进入ffmpeg.exe所在的文件夹
如ffmpeg.exe在 E:\ffmpeg\bin\ffmpeg.exe
E:
cd E:\ffmpeg\bin
获取电脑的音频和摄像头设备:
ffmpeg -list_devices true -f dshow -i dummy
得到以下设备:
screen-capture-recorder 是视频设备
virtual-audio-capturer 是音频设备
如果有带中文乱码可以下载DirectShow SDK自带的工具GraphEdit
查看视频设备参数:
ffmpeg -f dshow -list_options true -i video="screen-capture-recorder"
pixel_format 像素格式
s 分辨率
-r 帧率
录制桌面视频有两种方法:
用dshow类型找到桌面输出的设备 要下载一个Screen Capturer Recorder程序 才会得到录制桌面的设备(捕捉视频的速度较快)
ffmpeg -f dshow -r 10 -i video="screen-capture-recorder" -vcodec libx264 -preset:v ultrafast -crf 36 a.mp4
-f 输出类型
-i 输出设备
-r 帧率
-vcodec 视频编码
-preset 视频速度(越快占用cpu越少)
-crf 压缩视频内存
用gdigrab 类型无需安装程序即可捕捉桌面(捕捉视频的速度没有dshow快)
ffmpeg -f gdigrab -framerate 10 -i desktop -vcodec libx264 -preset:v ultrafast -crf 36 a.mp4
-framerate 帧率
-video_size 视频大小
offset_x 设置x轴距离
offset_y 设置y轴距离
录制音频设备:
ffmpeg -f dshow -i audio="virtual-audio-capturer" -acodec aac -strict -2 a.aac
-acodec aac 是ffmpeg自制的AAC编码器,需要开启"-strict experimental"参数,音质也不差。
录制音视频:
ffmpeg -f gdigrab -framerate 10 -i desktop -f dshow -i audio="virtual-audio-capturer" -vcodec libx264 -preset:v ultrafast -crf 36 -acodec aac -strict -2 a.mp4
ffmpeg -f dshow -r 10 -i video="screen-capture-recorder":audio="virtual-audio-capturer" -vcodec libx264 -preset:v ultrafast -crf 36 -acodec aac -strict -2 a.mp4
代码示例如下:
获取音频设备:
var audioDevices = new FilterInfoCollection(FilterCategory.AudioInputDevice);
foreach (FilterInfo device in audioDevices )
{
devicesList.Add(device.Name);
}
获取视频设备:
var videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
foreach (FilterInfo device in videoDevices)
{
devicesList.Add(device.Name);
}
cmd :
Process p;
public void Init()
{
p = new Process();
//启动引用程序
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.CreateNoWindow = false;
p.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
p.OutputDataReceived += new DataReceivedEventHandler(p_OutputDataReceived);
p.ErrorDataReceived += new DataReceivedEventHandler(p_ErrorDataReceived);
p.Start();
p.BeginErrorReadLine();
p.BeginOutputReadLine();
}
void p_ErrorDataReceived(object sender, DataReceivedEventArgs e)
{
if (e.Data != null)
{
Console.WriteLine(e.Data);
}
//throw new NotImplementedException();
}
void p_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
if (e.Data != null)
{
Console.WriteLine(e.Data);
}
}
public void stopRecord()
{
p.StandardInput.WriteLine("q &exit");
}
public void RecordVideo(string audioDeviceName,string fileName)
{
string command = Application.StartupPath + "\\" + "ffmpeg.exe -f gdigrab -framerate 10 -i desktop -f dshow -i audio=" + audioDeviceName + " -vcodec libx264 -preset:v ultrafast -crf 36 -acodec aac -strict -2 " + fileName;
// 向cmd窗口发送输入信息
p.StandardInput.WriteLine(command);
p.StandardInput.AutoFlush = true;
}
多个视频合成一个视频(9宫格形式)
-re -i 1.mp4 -re -i 3.mp4 -re -i 5.mp4 -re -i 9.mp4 -filter_complex nullsrc=size=1920x1080[base];[0:v]scale=960x540[upperleft];[1:v]scale=960x540[upperright];[2:v]scale=960x540[lowerleft];[3:v]scale=960x540[lowerright];[base][upperleft]overlay=shortest=1[tmp1];[tmp1][upperright]overlay=shortest=1:x=960[tmp2];[tmp2][lowerleft]overlay=shortest=1:y=540[tmp3];[tmp3][lowerright]overlay=shortest=1:x=960:y=540 -c:v libx264 out.mp4