利⽤FFmpeg实现录屏、直播推流、⾳频视频格式转换、剪裁等
功能
⽬录
⼀、FFmpeg简介。
⼆、FFmpeg常⽤参数及命令。
三、FFmpeg在Unity 3D中的使⽤。
1、FFmpeg 录屏。
2、FFmpeg 推流。
3、FFmpeg 其他功能简述。
⼀、FFmpeg简介
对于FFmpeg,其上是这样介绍的:
FFmpeg is the leading multimedia framework, able to decode, encode, transcode, mux, demux, stream, filter and play pretty much anything that humans and machines have created.
FFmpeg能够实现对视频⾳频编码、解码、转码、流传输等等⼀系列功能。它包含有libavcodec, libavutil, libavformat, libavfilter, libavdevice, libswscale,libswresample 库。其中:
1 2 3 4 5 6 7libavcodec 是⼀个包含⽤于⾳频/视频编解码器的解码器和编码器的库。
libavutil 是⼀个包含简化编程功能的库,包括随机数⽣成器,数据结构,数学例程,核⼼多媒体实⽤程序等等。
libavformat 是⼀个包含多媒体容器格式的解复⽤器和复⽤器的库。
libavdevice 是⼀个包含输⼊和输出设备的库,⽤于从许多常见的多媒体输⼊/输出软件框架中获取和呈现,包括Video4Linux,Video4Linux2,VfW和ALSA。libavfilter 是⼀个包含媒体过滤器的库。
libswscale 是⼀个执⾏⾼度优化的图像缩放和⾊彩空间/像素格式转换操作的库。
libswresample 是⼀个执⾏⾼度优化的⾳频重采样,重新矩阵化和样本格式转换操作的库。
⼆、FFmpeg常⽤参数及命令
1、命令的格式:
ffmpeg [global_options] {[input_file_options] -i input_url} ... {[output_file_options] output_url} ...
2、常⽤参数:
1
2 3 4 5 6 7 8 9 10 11 12-f fmt (input/output) 强制设定输⼊或输出⽂件格式。通常会⾃动检测输⼊⽂件的格式,并从输出⽂件的⽂件扩展名猜测格式,因此⼤多数情况下不需要这个选项。-i url (input) 输⼊
-y (global) 在没有请求的情况下覆盖输出⽂件。
-n (global) 不要覆盖输出⽂件,如果指定的输出⽂件已经存在,则会⽴即退出。
-stream_loop number 设定输⼊流循环的次数。循环0表⽰没有循环,循环1表⽰⽆限循环
-codec/-c 设置编码格式
-r fps 设置帧速率
-vcodec codec (output) 设置视频编码格式,同-codec:v
-pix_fmt format 设置像素格式
-ar freq 设置⾳频采样频率
-aq q (output) 设置⾳频质量
-acodec codec 设置⾳频编解码器,同-codec:a
3、常⽤命令
(1)将视频的帧速率改为24
1ffmpeg -i input.avi -r 24 output.avi
(2)视频格式转换,将avi转成mp4 1ffmpeg -i input.avi output.mp4
(3)从视频中提取⾳频
1ffmpeg -i test.mp4 -acodec libmp3lame output.mp3
(4)视频剪切
1ffmpeg -ss 00:00:15 -t 00:00:05 -i input.mp4 -vcodec copy -acodec copy output.mp4
(5)视频添加Logo
1ffmpeg -i input.mp4 -i Logo.png -filter_complex overlay output.mp4
(6)视频去掉Logo
1ffmpeg -i input.mp4 -vf delogo=0:0:220:90:100:1 output.mp4
(7)将100张图⽚合成视频,并为其添加背景⾳频(注意:图⽚要放在同⼀个⽂件夹下,并将图⽚按001--100的格式命名)
1ffmpeg -i 001.mp3 -i %3d.jpg -s 1024x768 -author fy -vcodec mpeg4 darkdoor.avi
(8)将视频每隔⼀秒抽取⼀张图⽚,保存名字为foo-001.jpeg, foo-002.jpeg, 等
1ffmpeg -i foo.avi -r 1 -s WxH -f image2 foo-%03d.jpeg
(2019.03.29 更新)
三、FFmpeg在Unity 3D中的使⽤
有⽹友问我如何在Unity中使⽤FFmpeg呢,趁今天⽼⼤出差了,忙⾥偷闲更新⼀下博客。
使⽤FFmpeg⾸先得有FFmpeg,可以直接从官⽹免费下载,也可以从Unity Store花费85美元下载插件FFmpeg Unity Bind,
如果你有插件FFmpeg Unity Bind,那你就不⽤再往下看了,因为本⽂使⽤的就是FFmpeg Unity Bind的思想:⽤命令⾏参数实现FFmpeg的调⽤。
1、命令⾏调⽤FFmpeg的核⼼代码如下:
public static void Execute(string command)
{
if (isRunning)
return;
//Clear output buffer
buffer = new StringBuilder(short.MaxValue);
new Thread(() =>
{
isRunning = true;
Thread.CurrentThread.IsBackground = true;
//Execute binary
p = new Process();
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.FileName = binaryPath;
p.StartInfo.Arguments = command;
p.StartInfo.RedirectStandardInput = true;//这句⼀定需要,⽤于模拟该进程控制台的输⼊
p.OutputDataReceived += (s, e) =>
{
callback(FFmpegParser.COMMAND_CODE + FFmpegParser.PROGRESS_CODE + AppendLog(e.Data));
};
p.ErrorDataReceived += (s, e) =>
{
if (!string.IsNullOrEmpty(e.Data) && e.Data.ToLower().Contains("error"))
callback(FFmpegParser.ERROR_CODE + AppendLog(e.Data));
else
callback(FFmpegParser.COMMAND_CODE + FFmpegParser.PROGRESS_CODE + AppendLog(e.Data));
};
p.Start();
callback(FFmpegParser.COMMAND_CODE + FFmpegParser.START_CODE + "\nStarted\n");
p.BeginOutputReadLine();
p.BeginErrorReadLine();
p.WaitForExit();
if (isStopProcessWhatIthink)
{
callback(FFmpegParser.COMMAND_CODE + FFmpegParser.SUCCESS_CODE + AppendLog("主动关闭 FFmpeg 进程") ); isStopProcessWhatIthink = false;
}
else
{
callback(FFmpegParser.COMMAND_CODE +
(p.ExitCode == 0 ?
FFmpegParser.SUCCESS_CODE + AppendLog("Success!") :
FFmpegParser.FAILURE_CODE + AppendLog("Failure. Search details above")));
p.Close();
}
callback(FFmpegParser.COMMAND_CODE + FFmpegParser.FINISH_CODE + "\nFinished\n");writeline方法的作用
isRunning = false;
}).Start();
}
/// <summary>
/// 主动退出进程
/// </summary>
public static void CloseFFmpegProcess()
{
if (p!=null)
{
try
{
p.StandardInput.WriteLine("q");//在这个进程的控制台中模拟输⼊q,⽤于暂停录制
p.Close();
p.Dispose();
isRunning = false;
isStopProcessWhatIthink = true;
p = null;
UnityEngine.Debug.Log("主动退出FFmpeg进程");
}
catch (Exception)
{
UnityEngine.Debug.Log("No process to kill");
}
}
else
{
UnityEngine.Debug.Log("FFmpeg process is null");
}
}
2、FFmpeg 录屏、推流常⽤命令
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18//推流命令
/
/-re -i C:\output.mp4 -vcodec libx264 -acodec copy -f flv -y rtmp://***/live/chid
//拉流
//-i rtmp://127.0.0.1/live/chid -acodec copy -vcodec copy -f flv -y chid.mp4
//-i rtmp://127.0.0.1/live/chid -c copy dump.flv
// rtsp 推流
// -i C:\output.mp4 -vcodec libx264 -f rtsp rtsp://***/myid
//-f gdigrab -i desktop -vcodec libx264 -preset ultrafast -acodec libmp3lame -ar 44100 -ac 1 -f rtsp rtsp://***/myid
//推摄像头
//-f dshow -i video="HD Pro Webcam C920" -vcodec libx264 -acodec copy -preset:v ultrafast -tune:v zerolatency -f rtsp rtsp://***/myid
//⾳视频录制
//-f dshow -video_size 1680x1050 -framerate 30 -pixel_format yuv420p -i audio="麦克风 (HD Pro Webcam C920)" av-out.mp4<br><br> //-f fmt 指定格式(⾳视频的格式)
//dshow
//-i 输⼊
//-vcodec 强制使⽤codec编解码⽅式('copy' to copy stream)
//libx264
//-acodec 指定⾳频编码('copy' to copy stream)
//copy
//-preset
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45//-tune
//-y 覆盖已有⽂件
//-c
//传输的图像为灰⾊的解决办法,添加:-pix_fmt yuv420p
//录制桌⾯:desktop
//录制窗⼝:title=窗⼝名
// av_interleaved_write_frame(): Broken pipe 问题:在-f rtsp后⾯加⼀个-rtsp_transport tcp
//录制整个程序窗⼝
//string command = "-f gdigrab -i title=test -vcodec libx264 -preset ultrafast -pix_fmt yuv420p -acodec libmp3lame -ar 44100 -ac 1 -f rtsp -rtsp_transport tcp
rtsp://***/myid";
//录制某⼀区域(这⾥是摄像头区域)
//-offset_x 10 -offset_y 20 -video_size 640x480 从屏幕的(10,20)点处开始,抓取640x480的屏幕
//-s 640x480 指定分辨率 (640x480)
//-r 60 设置帧率(和程序的fps保持⼀致,解决Past duration 0.692253 too large的问题)
//string command = "-f gdigrab -offset_x 920 -offset_y 85 -video_size 320*240 -s 320*240 -i title=test -vcodec libx264 -preset ultrafast -pix_fmt yuv420p -r 60 -acodec libmp3lame -ar 44100 -ac 1 -f rtsp -rtsp_transport tcp rtsp://***/myid";
//string command = "-f gdigrab -offset_x 920 -offset_y 85 -video_size 320*240 -s 320*240 -i title=test -f dshow -i audio=\""+ micName + "\" -vcodec libx264 -preset ultrafast -pix_fmt yuv420p -r 60 -acodec aac -ar 16000 -ac 1 -f rtsp -rtsp_transport tcp rtsp://***/myid";
//输⼊交换视频和⾳频的位置,画⾯不卡顿了
//string command = "-f dshow -i audio=\"" + micName + "\" -f gdigrab -offset_x 920 -offset_y 85 -video_size 320*240 -s 320*240 -i title=test -vcodec libx264 -preset ultrafast -pix_fmt yuv420p -f rtsp -rtsp_transport tcp "+ spId;
//FFmpegCommands.DirectInput(command);
//-re(输⼊)主要⽤于模拟抓取设备或实时输⼊流(例如,从⽂件读取时)。不应与实际的抓取设备或实时输⼊流⼀起使⽤(它可能导致数据包丢失)。默认情况
下,ffmpeg尝试尽快读取输⼊。此选项将减慢输⼊读取到输⼊的本机帧速率。它对于实时输出(例如
直播)⾮常有⽤。
//string command = "-re -i \"" + path + "\" -vcodec libx264 -preset ultrafast -pix_fmt yuv420p -f rtsp -rtsp_transport tcp " +spId;
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论