利用FFmpeg实现录屏、直播推流、音频视频格式转换、剪裁等功能

news/2024/11/29 9:36:03/

一、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

 三、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");
                isRunning = false;
            }).Start();
        }

        /// 

        /// 主动退出进程
        /// 

        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;


http://www.ppmy.cn/news/363390.html

相关文章

hdoj 5952 Counting Cliques

题目链接:Counting Cliques 题目大意:给你一张n个点,m条边的无向图,问尺寸为s的完全图有多少个,尺寸即为这张完全图有多少个点,完全图是值每两点之间都有边 题目思路:这题吃时间吃的比较紧,想…

HDU 5952 搜索

题意 给一个无向图,所有点的度小于等于20。问这个图中有多少个完全子图。 题解 完全图就是一个图任意两点之间都有边相连。由于所有点的度都很小,我们可以暴力枚举完全图。 枚举过程首先从1号点开始,然后枚举与1号点相邻的点,…

HDU 5952

题意:给出一个无向图, 问其中的结点数为s的完全图有多少个 思路:我最初的思路是不管重复直接搜,然后最后答案除一个s的阶乘, 但是超时, 后来发现其实可以不算重复的, 就是将搜索有序化, 举个例子: 你现在有4个数 4 2 3 1, 那么你要选出其中3个, 那么选择的顺序就是 4 2 3 ,…

HDU5952

题目链接: HDU 5952 题意:给一个N个点M条边的的图, 求有多少个大小为S 的完全子图, (题目trick:一个点度最多为20), 爆搜即可 (需要单向建图(U->V &…

HDU 5952 Counting Cliques dfs + 思维

传送门:HDU5952 题意:给出一个无向图,问其中点集大小为S的无向完全子图的个数。 思路:就是暴搜,但是建图有技巧,因为搜索过程中很容易出现重复序列,比如我们第一次搜到的答案是1 2 3&#xff…

基于Python的AutoSAR代码生成器---COM

基于Python的AutoSAR代码生成器---COM 1. 模板引擎-Jinja22. 开发环境准备3. JinJa2 模板(Com_PbCfg.c)3. 代码生成器4. 测试使用 1. 模板引擎-Jinja2 Jinja2是基于python的模板引擎,功能比较类似于于PHP的smarty,J2ee的Freemark…

科技政策 | 《深圳市加快加快推动人工智能高质量发展高水平应用行动方案(2023—2024年)》发布

原创 | 文 BFT机器人 导语 Introduction 近日,深圳市发布了《深圳市加快推动人工智能高质量发展高水平应用行动方案(2023-2024年)》旨在以更大热情拥抱创新,打造最好生态,推动人工智能高质量发展和全方位各领域高水平…

JS的最佳实践 - 在href或onclick中的window.open()?

本文介绍了JS的最佳实践 - 在href或onclick中的window.open()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着来一起学习吧! 问题描述 关于优化的问题,在: &l…