Unity 利用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 库。其中:
libavcodec 是一个包含用于音频/视频编解码器的解码器和编码器的库。
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、常用参数:
-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
ffmpeg -i input.avi -r 24 output.avi
(2)视频格式转换,将avi转成mp4
ffmpeg -i input.avi output.mp4
(3)从视频中提取音频
ffmpeg -i test.mp4 -acodec libmp3lame output.mp3
(4)视频剪切
ffmpeg -ss 00:00:15 -t 00:00:05 -i input.mp4 -vcodec copy -acodec copy output.mp4
(5)视频添加Logo
ffmpeg -i input.mp4 -i Logo.png -filter_complex overlay output.mp4
(6)视频去掉Logo
ffmpeg -i input.mp4 -vf delogo=0:0:220:90:100:1 output.mp4
(7)将100张图片合成视频,并为其添加背景音频(注意:图片要放在同一个文件夹下,并将图片按001--100的格式命名)
ffmpeg -i 001.mp3 -i %3d.jpg -s 1024x768 -author fy -vcodec mpeg4 darkdoor.avi
(8)将视频每隔一秒抽取一张图片,保存名字为 foo-001.jpeg, foo-002.jpeg, 等
ffmpeg -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 == ?
FFmpegParser.SUCCESS_CODE + AppendLog("Success!") :
FFmpegParser.FAILURE_CODE + AppendLog("Failure. Search details above")));
p.Close();
}
callback(FFmpegParser.COMMAND_CODE + FFmpegParser.FINISH_CODE + "\nFinished\n");
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 录屏、推流常用命令
//推流命令
//-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 //-f fmt 指定格式(音视频的格式)
//dshow
//-i 输入
//-vcodec 强制使用codec编解码方式('copy' to copy stream)
//libx264
//-acodec 指定音频编码('copy' to copy stream)
//copy
//-preset
//-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 "+ ClientController.rtspId;
//FFmpegCommands.DirectInput(command); //-re(输入)主要用于模拟抓取设备或实时输入流(例如,从文件读取时)。不应与实际的抓取设备或实时输入流一起使用(它可能导致数据包丢失)。默认情况下,ffmpeg尝试尽快读取输入。此选项将减慢输入读取到输入的本机帧速率。它对于实时输出(例如直播)非常有用。
//string command = "-re -i \"" + path + "\" -vcodec libx264 -preset ultrafast -pix_fmt yuv420p -f rtsp -rtsp_transport tcp " +ClientController.rtspId;
3、完整源码示例
点击这里获取你想要的源码。
Unity 利用FFmpeg实现录屏、直播推流、音频视频格式转换、剪裁等功能的更多相关文章
- Android设备一对多录屏直播--(UDP组播连接,Tcp传输)
原文:https://blog.csdn.net/sunmmer123/article/details/82734245 近期需要学习流媒体知识,做一个Android设备相互投屏Demo,因此找到了这 ...
- Android实现录屏直播(三)MediaProjection + VirtualDisplay + librtmp + MediaCodec实现视频编码并推流到rtmp服务器
请尊重分享成果,转载请注明出处,本文来自Coder包子哥,原文链接:http://blog.csdn.net/zxccxzzxz/article/details/55230272 Android实现录 ...
- Windows 11实现录屏直播,搭建Nginx的rtmp服务
先!下载几个工具呗 官方下载FFmpeg:http://www.ffmpeg.org 官方下载nginx-rtmp-module:https://github.com/arut/nginx-rtmp- ...
- Windows11实现录屏直播,H5页面直播 HLS ,不依赖Flash
这两天的一个小需求,需要实现桌面实时直播,前面讲了两种方式: 1.Windows 11实现录屏直播,搭建Nginx的rtmp服务 的方式需要依赖与Flash插件,使用场景有限 2.Windows 11 ...
- 手游录屏直播技术详解 | 直播 SDK 性能优化实践
在上期<直播推流端弱网优化策略 >中,我们介绍了直播推流端是如何优化的.本期,将介绍手游直播中录屏的实现方式. 直播经过一年左右的快速发展,衍生出越来越丰富的业务形式,也覆盖越来越广的应用 ...
- Android实现录屏直播(一)ScreenRecorder的简单分析
http://blog.csdn.net/zxccxzzxz/article/details/54150396 Android实现录屏直播(一)ScreenRecorder的简单分析 Android实 ...
- Android实现录屏直播(二)需求才是硬道理之产品功能调研
请尊重分享成果,转载请注明出处,本文来自Coder包子哥,原文链接:http://blog.csdn.net/zxccxzzxz/article/details/54254244 前面的Android ...
- 使用Camstudio和KeyCastOW来录屏制作软件Demo视频
博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:使用Camstudio和KeyCastOW来录屏制作软件Demo视频.
- iOS 直播-获取音频(视频)数据
iOS 直播-获取音频(视频)数据 // // ViewController.m // capture-test // // Created by caoxu on 16/6/3. // Copyri ...
随机推荐
- 【九章算法免费讲座第一期】转专业找CS工作的“打狗棒法”
讲座时间: 美西时间6月5日18:30-20:00(周五) 北京时间6月6日09:30-11:00(周六a.m) 讲座安排: 免费在线直播讲座 报名网址: http://t.cn/R2XgMSH,或猛 ...
- 小米手机 js 脚本取src为空的适配问题
今天測试提上来一个问题 我android webview 中运行了一段js脚本.去替换原来的图片.可是小米手机上竟然没起作用 花了一个中午的午休看问题 贴出来帮助下遇到相同的问题的朋友吧.我百度了半天 ...
- Android系统Recovery工作原理之使用update.zip升级过程分析(六)---Recovery服务流程细节【转】
本文转载自:http://blog.csdn.net/mu0206mu/article/details/7465439 Android系统Recovery工作原理之使用update.zip升级过程分 ...
- UESTC--758--P酱的冒险旅途(模拟)
P酱的冒险旅途 Time Limit: 1000MS Memory Limit: 65535KB 64bit IO Format: %lld & %llu Submit Status ...
- MySQL SQL优化教程
转自:https://www.cnblogs.com/duanxz/archive/2013/02/01/2889413.html 一,查询SQL执行效率 通过show status命令了解各种SQL ...
- PCB 周期日历
在PCB行业一直以来没找到适合我们这行业的日历,主要存在2个差异导致. 1.周期差异:由于PCB 周期计算的复杂性,市面上无法找到符合PCB行业计算周期方式 (另一遍博文中有写周期计算逻辑) http ...
- 洛谷P1077 摆花(背包dp)
P1077 摆花 题目描述 小明的花店新开张,为了吸引顾客,他想在花店的门口摆上一排花,共m盆.通过调查顾客的喜好,小明列出了顾客最喜欢的n种花,从1到n标号.为了在门口展出更多种花,规定第i种花不能 ...
- Spring Boot (20) 拦截器
动态资源和静态资源 拦截器可以算是aop的一种实现,专门拦截对动态资源的后台请求,也就是拦截对控制层的请求,主要用于判断用户是否有权限请求后台.拦截器不会拦截静态资源,如spring boot默认静态 ...
- JQuery 遍历没有id的控件
html代码: <tr> <td field="ck" > <div><input type="checkbox" / ...
- MySQL定期执行任务相关问题
在sqlyog某数据库下的事件里新建事件,并写入一下代码: DELIMITER $$ ALTER DEFINER=`root`@`%` EVENT `0` ON SCHEDULE EVERY 24 H ...