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 ...
随机推荐
- Qt graphic item日记
今天在用用graphic view 加入graphic item的时候要引入一个context menu,自然就要对context menu上的action进行slot处理.可是graphic ite ...
- Codeforces Round #281 (Div. 2) A. Vasya and Football 暴力
A. Vasya and Football Vasya has started watching football games. He has learned that for some foul ...
- SharePoint 2013 Silverlight中使用Netclient对象模型
1.创建Silverlight时,选择Silverlight 4.不要选择版本号5,试了非常久版本号5都调用不了,自己也不知道什么原因.谷歌也没找到答案.后来尝试版本号4,能够调用. 至于Host t ...
- oc31--new实现
// // main.m // new方法实现原理 #import <Foundation/Foundation.h> #import "Person.h" int m ...
- PCB MS SQL 小写转大写
由于SQL Server允许为小写进入 ,导致数据库中存在小写,在数据集成到MES或ERP时报错,Oracle要求大写导致, 需转换为大写,可通过以下语句,查询所有小写数据,再更新.
- Sorting It All Out(拓扑排序)
http://poj.org/problem?id=1094 1.判断所给关系是否为合法的拓扑序列,若存在环,输出 "Inconsistency found after %d relatio ...
- mysql如何查询最新插入的数据
在MySQL中,使用auto_increment类型的id字段作为表的主键,并用它作为其他表的外键,形成“主从表结构”,这是数据库设计中常见的用法.但是在具体生成id的时候,我们的操作顺序一般是:先在 ...
- 修改CAS源码是的基于DB的认证方式配置更灵活
最近在做CAS配置的时候,遇到了数据源不提供密码等数据的情况下,怎样实现密码输入认证呢? 第一步:新建Java项目,根据假面算法生成CAS加密工具 出于保密需要不提供自定义的加密工具,在您的实际项目中 ...
- Python-控制流
if #!/usr/bin/python number=23 guess=int(input('Enter an interger:')) #input返回的结果是string类型,需要用int()转 ...
- 显示程序输出并复制到文件(tee 命令)
Linux tee命令用于读取标准输入的数据,并将其内容输出成文件. tee指令会从标准输入设备读取数据,将其内容输出到标准输出设备,同时保存成文件. 语法 tee [-ai][--help][--v ...