参考资料
FFmpeg 官网
阮一峰-视频处理入门教程
Windows环境下FFmpeg推流命令集合_yunduan512的专栏-CSDN博客_ffmpeg推流命令
ffmpeg常用参数一览 - rlandj - 博客园
利用ffmpeg实现rtmp推流 - 简书
什么是FFmpeg?
这个名字的灵感来自 MPEG,意思是运动图像专家组,是一个专门针对运动图像和语音压缩制定国际标准的组织,指定了当前流行的很多基本视频标准。FF 的意思是快进。
FFmpeg是一个完整的,跨平台的,存储,转换、推拉音视频的解决方案。 FFmpeg包括ffmpeg、ffplay、ffprobe三个主要命令。
为什么使用 FFmpeg?
它通常被称为多媒体领域的瑞士军刀。我们可以使用 FFmpeg 来执行很多功能。代码是用 C 语言编写的,并针对最佳性能进行了优化。 FFmpeg具备编解码、转码、推拉流、过滤、播放等功能,几乎所有的音视频格式都支持。
FFmpeg 支持广泛的代码、格式、设备和协议,这使其成为转码引擎的理想选择。与许多已停产的项目不同,20 多年来它仍在积极开发 。有一个庞大的开发人员、用户和贡献者社区,他们不断开发新功能和修复程序。
FFmpeg 已被用于 YouTube 和 iTunes 等视频平台的核心处理。我们大多数人都使用像 VLC 这样的媒体播放器来播放视频文件。VLC 使用 FFmpeg 库作为其核心。一些视频编辑器和移动应用程序也在幕后使用 FFmpeg。
FFmpeg 库
FFmpeg 有几个有价值的库,你可以直接从你的应用程序代码中使用它们。每个库都包含与特定区域相关的不同功能。
一些著名的库是:
libavcodec — 包含 FFmpeg 支持的所有编码器和解码器。
libavformat — 拥有处理各种容器格式的所有复用器和解复用器。
libavfilter — 由许多过滤器组成,你可以根据需要使用它们来修改音频或视频。
libavdevice——支持多种不同的输入和输出设备。
libavutil — 辅助便携式多媒体编程。
libswscale — 执行高度优化的图像缩放以及色彩空间和像素格式转换操作。
libswresample — 执行高度优化的音频重采样、重新混合和样本格式转换操作。
FFmpeg 命令 ffmpeg、ffplay、ffprobe
其中最主要的命令是:
ffmpeg— 用于音视频转码。
ffplay —一个非常简单和可移植的媒体播放器。
ffprobe — 查看多媒体文件的信息
容器
视频文件本身其实是一个容器(container),里面包括了视频和音频,也可能有字幕等其他内容。
常见的容器格式有以下几种。一般来说,视频文件的后缀名反映了它的容器格式。
- MP4
- MKV
- WebM
- AVI
下面的命令查看 FFmpeg 支持的容器。
$ ffmpeg -formats
编码格式
视频和音频都需要经过编码,才能保存成文件。不同的编码格式(CODEC),有不同的压缩率,会导致文件大小和清晰度的差异。
常用的视频编码格式如下。
- H.262
- H.264
- H.265
上面的编码格式都是有版权的,但是可以免费使用。此外,还有几种无版权的视频编码格式。
- VP8
- VP9
- AV1
常用的音频编码格式如下。
- MP3
- AAC
上面所有这些都是有损的编码格式,编码后会损失一些细节,以换取压缩后较小的文件体积。无损的编码格式压缩出来的文件体积较大,这里就不介绍了。
下面的命令可以查看 FFmpeg 支持的编码格式,视频编码和音频编码都在内。
$ ffmpeg -codecs
编码器
编码器(encoders)是实现某种编码格式的库文件。只有安装了某种格式的编码器,才能实现该格式视频/音频的编码和解码。
以下是一些 FFmpeg 内置的视频编码器。
- libx264:最流行的开源 H.264 编码器
- NVENC:基于 NVIDIA GPU 的 H.264 编码器
- libx265:开源的 HEVC 编码器
- libvpx:谷歌的 VP8 和 VP9 编码器
- libaom:AV1 编码器
音频编码器如下。
- libfdk-aac
- aac
下面的命令可以查看 FFmpeg 已安装的编码器。
$ ffmpeg -encoders
与 Ubuntu 上的 APT 和 macOS 上的 Homebrew 不同,Windows 上没有可以用来快速安装 FFmpeg的包管理器。
可以在此处(https://www.gyan.dev/ffmpeg/builds/)找到 4 个 Windows FFmpeg 构建变体:
git full
– 从具有大量库的主分支构建。
git essentials
– 从带有常用库的主分支构建。
release full
– 从具有大量库的最新版本分支构建。
release essentials
– 使用常用库从最新版本分支构建。
在我们的案例中,我们将使用 FFmpeg 发布版。
在此处下载 FFmpeg 发布版:https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-essentials.zip
将文件解压缩到将来要使用它们的地方。就我而言,我将它们放在我的 E盘中。
里面的bin文件夹包含这些可执行文件。如果不需要将ffmpeg放到path路径或者本机存放多个版本的ffmpeg,就直接通过命令行进入到此目录,然后直接ffmpeg.exe、ffplay.exe、ffprobe/exe即可执行对应命令。
将bin文件夹添加到Windows环境路径变量中,这样我们就可以运行这个工具而不必每次都指定完整路径。在搜索栏中搜索环境变量,然后单击环境变量。
单击用户变量中的路径,单击新建,并粘贴bin的完整路径文件夹。
打开命令提示符并键入
ffmpeg -version
. 如果你看到打印出 FFmpeg 版本,则表示 FFmpeg 安装成功。我们还可以检查ffprobe -version
和ffplay -version
。。如果命令行在设置环境变量前打开,记得设置后重新打开命令行,否则,找不到ffmpeg。
ffmpeg的命令行参数非常多,可以分成五个部分。
$ ffmpeg {1} {2} -i {3} {4} {5}
上面命令中,五个部分的参数依次如下。
- 全局参数
- 输入文件参数
- 输入文件
- 输出文件参数
- 输出文件
参数太多的时候,为了便于查看,ffmpeg 命令可以写成多行。
ffmpeg \ [全局参数] \ [输入文件参数] \ -i [输入文件] \ [输出文件参数] \ [输出文件]
下面是一个例子。
ffmpeg \ -y \ # 全局参数 -c:a libfdk_aac -c:v libx264 \ # 输入文件参数 -i input.mp4 \ # 输入文件 -c:v libvpx-vp9 -c:a libvorbis \ # 输出文件参数 output.webm # 输出文件
上面的命令将 mp4 文件转成 webm 文件,这两个都是容器格式。输入的 mp4 文件的音频编码格式是 aac,视频编码格式是 H.264;输出的 webm 文件的视频编码格式是 VP9,音频格式是 Vorbis。
如果不指明编码格式,FFmpeg 会自己判断输入文件的编码。因此,上面的命令可以简单写成下面的样子。
ffmpeg -i input.avi output.mp4
FFmpeg 常用的命令行参数如下:【尤其在开发过程中,由于ffmpeg版本不同,ffmpeg参数也有少量出入,建议在命令行窗口输入“ffmpeg -h”查看本机部署的ffmpeg支持的参数】
-preset
:指定输出的视频质量,会影响文件的生成速度,有以下几个可用的值 ultrafast, superfast, veryfast, faster, fast, medium, slow, slower, veryslow。-y
:不经过确认,输出时直接覆盖同名文件。- -loglevel 或 -v
- quiet 不输出日志
- verbose 同info ,只是更详细
- info、warning、error 显示指定级别日志。
- -hide_banner精简模式查看
- -sample_fmt 设置语音文件位深
- -formats:列出支持的文件格式。
- -codecs:列出支持的编解码器。
- -decoders:列出支持的解码器。
- -encoders:列出支持的编码器。
- -protocols:列出支持的协议。
- -bsfs:列出支持的比特流过滤器。
- -filters:列出支持的滤镜。
- -pix_fmts:列出支持的图像采样格式。
- -sample_fmts:列出支持的声音采样格式。
- -i filename:指定输入文件名。
- -ffmt:强制设定文件格式,需使用能力集列表中的名称(缺省是根据扩展名选择的)。
- -ss hh:mm:ss[.xxx]:设定输入文件的起始时间点,启动后将跳转到此时间点然后开始读取数据。
下面codec为编码名,需使用ffmpeg -codecs 列表列出此ffmpeg支持的编码。如果codec值为copy,直接复制,不经过重新编码(这样比较快)
-c [:stream_specifier] codec 为指定流指定编码 。stream_specifier值为音频或者视频编码;a:1第2个音频,可能有中英文、多通道所以有多个流。
-codec[:stream_specifier] codec 为指定流指定编码,同 -c 。
- -acodec codec:指定声音的解码器,需便用能力集列表中的名称。同
-codec:a、
-c:a- -vcodec codec:指定视频的解码器,需使用能力集列表中的名称。同
-codec:a、
-c:v故常用 -c:a -c:v
-c copy 等同于 -c:a copy -c:v copy 同时设置语音、视频编码不改变。
- -stream_loop number 设置输入流重复次数,-0表示不重复,-1表示无限次重复发送。 ffmpeg 4.2.1版本有这个参数,低版本可能没有。
- -b:v bitrate:设定视频流的比特率,整数,单位bps。
- -r fps:设定视频流的帧率,整数,单位fps。
- -s WxH:设定视频的画面大小。也可以通过挂载画面缩放滤镜实现。
- -pix_fmt format:设定视频流的图像格式(如RGB还是YUV)。
- -ar sample rate:设定音频流的采样率,整数,单位Hz。
- -ab bitrate:设定音频流的比特率,整数,单位bps。
- -ac channels:设置音频流的声道数目。
- ·-pix_fmt format:设置视频编码器使用的图像格式(如RGB还是YUV)。
- -an忽略任何音频流。
- -vn忽略任何视频流。
- -t hh:mm:ss[.xxx]:设定输出文件的时间长度。
- -to hh:mm:ss[.xxx]:如果没有设定输出文件的时间长度的话可以设定终止时间点。
如果某个参数不清楚,可以去官网直接ctrl+f搜索查询文档。ffmpeg Documentation
注:ffmpeg不同版本 参数、支持的编码可能不同
使用rtmp方式推流
ffmpeg -stream_loop -1 -v verbose -re -i "/path/to/test.mp4" -c:v h264 -c:a aac -f flv rtmp://127.0.0.1/live/test # RTMP标准不支持H265,但是国内有自行扩展的,如果你想让FFmpeg支持RTMP-H265,请按照此文章编译:https://github.com/ksvc/FFmpeg/wiki/hevcpush -stream_loop -l 重复发送 1是一 ,不是el。 -v verbose 输出详细日志 -re : 默认情况下,ffmpeg尝试以尽可能快的速度读取输入。-re这个选项会将输入的读取速度降低到输入的本地帧速率。它对于实时输出(例如直播流)很有用。 -f:视频输出格式 -i:输入视频文件 -c:v 同-vcodec: -i参数后面的,表示视频转换后的编码;-i参数前的,表示要转换的视频的编码,可以自动识别,所以可以不指定。也可以指定为copy,表示编码和输入流相同,不变。 -c:a 同-acodec: -i参数后面的表示语音转换后的编码;-i参数前的,表示要转换的音频的编码,可以自动识别,所以可以不指定。也可以指定为copy,表示编码和输入流相同,不变。 如果编码不变 ,命令简化为 ffmpeg -stream_loop -l -v verbose -re -i "/path/to/test.mp4" -f flv rtmp://127.0.0.1/live/test
把视频推流至rtmp://127.0.0.1:1935/live/123,127.0.0.1:1935为rtmp服务器地址、live为流媒体服务器上的程序名、123流唯一id,推流拉流地址一样即可播放。
使用rtsp方式推流
# h264推流 ffmpeg -re -i "/path/to/test.mp4" -vcodec h264 -acodec aac -f rtsp -rtsp_transport tcp rtsp://127.0.0.1/live/test # h265推流 ffmpeg -re -i "/path/to/test.mp4" -vcodec h265 -acodec aac -f rtsp -rtsp_transport tcp rtsp://127.0.0.1/live/test
使用rtp方式推流
# h264推流 ffmpeg -re -i "/path/to/test.mp4" -vcodec h264 -acodec aac -f rtp_mpegts rtp://127.0.0.1:10000 # h265推流 ffmpeg -re -i "/path/to/test.mp4" -vcodec h265 -acodec aac -f rtp_mpegts rtp://127.0.0.1:10000
遇见问题
(1)Could not run graph (sometimes caused by a device already in use by other application)
[dshow @ 0000021fb05b6a80] Could not run graph (sometimes caused by a device already in use by other application)
audio=麦克风 (Realtek High Definition Audio): I/O error 解解决: 修改电脑麦克风权限
解决解决 : Win10使用FFmpeg推音频流报错Could not run graph解决办法_blueshaw的博客-CSDN博客
(2)too full or near too full (101% of size: 3041280 [rtbufsize parameter])! frame dropped!问题。
[dshow @ 00000222983eca80] real-time buffer [XiaoMi USB 2.0 Webcam] [video input] too full or near too full (101% of size: 3041280 [rtbufsize parameter])! frame dropped!
解决: 命令行增加配置项 -crf 22
解决ffmpeg 录屏命令_越努力越幸运~的博客-CSDN博客_ffmpeg录屏命令
VLC播放推流
下载安装VLC播放器
播放器---网络拉流地址,即上图推流中的地址 rtsp://127.0.0.1/live/test。
推送的同时,vlc即可播放
保存rtmp流到本地
ffmpeg -i rtmp://58.200.131.2:1935/livetv/hunantv -c copy -f flv /root/toy/d.flv
ffmpeg查看电脑设备
输入下面的语句即可列出电脑的设备
ffmpeg -list_devices true -f dshow -i dummy
测试摄像头是否可用
cmd中输入下面语句并回车(USB2.0 PC CAMERA为摄像头名称)
ffplay -f dshow -i video="XiaoMi USB 2.0 Webcam"
或者
ffplay -f vfwcap -i 0
如果成功弹出播放窗口,则代表设备可用,否则可能是设备不可用或者设备被占用
查看摄像头和麦克风信息
cmd中输入下面语句即可查询摄像头信息
ffmpeg -list_options true -f dshow -i video="XiaoMi USB 2.0 Webcam"
cmd中输入下面语句即可查询麦克风信息
ffmpeg -list_options true -f dshow -i audio="麦克风 (Realtek High Definition Audio)"
摄像头推流
接下来正式把对摄像头进行推流,从前面我们知道摄像头名称为USB2.0 PC CAMERA,而且推流服务器ip为127.0.0.1:1935,关键字为live,所以cmd中输入以下语句:
ffmpeg -f dshow -i video="XiaoMi USB 2.0 Webcam" -vcodec libx264 -preset:v ultrafast -tune:v zerolatency -f flv rtmp://127.0.0.1:1935/live/123
麦克风推流
前面介绍了摄像头画面推流,可是没有声音,这次我们把麦克风声音推流出去,cmd中输入下面语句
ffmpeg -f dshow -i audio="麦克风 (Realtek High Definition Audio)" -vcodec libx264 -preset:v ultrafast -tune:v zerolatency -f flv rtmp://127.0.0.1:1935/live/123
摄像头&麦克风推流rtmp
终于到最激动人心的时刻了,我们这次要实现同时推流摄像头画面与声音,此时我们的语句应该如下
ffmpeg -f dshow -i video="XiaoMi USB 2.0 Webcam" -f dshow -i audio="麦克风 (Realtek High Definition Audio)" -vcodec libx264 -preset:v ultrafast -tune:v zerolatency -f flv rtmp://127.0.0.1:1935/live/123
或者
ffmpeg -f dshow -i video="XiaoMi USB 2.0 Webcam":audio="麦克风 (Realtek High Definition Audio)" -vcodec libx264 -r 25 -preset:v ultrafast -tune:v zerolatency -f flv rtmp://127.0.0.1:1935/live/12
摄像头&麦克风推流rtsp
ffmpeg -rtbufsize 100M -f dshow -i video="XiaoMi USB 2.0 Webcam":audio="麦克风 (Realtek High Definition Audio)" -vcodec h264 -preset:v ultrafast -crf 22 -tune:v zerolatency -acodec aac -f rtsp -rtsp_transport tcp rtsp://127.0.0.1/live/123
转换编码格式(transcoding)指的是, 将视频文件从一种编码转成另一种编码。比如转成 H.264 编码,一般使用编码器
libx264
,所以只需指定输出文件的视频编码器即可。$ ffmpeg -i [input.file] -c:v libx264 output.mp4
下面是转成 H.265 编码的写法。
$ ffmpeg -i [input.file] -c:v libx265 output.mp4
转换容器格式(transmuxing)指的是,将视频文件从一种容器转到另一种容器。下面是 mp4 转 webm 的写法。
$ ffmpeg -i input.mp4 -c copy output.webm
上面例子中,只是转一下容器,内部的编码格式不变,所以使用
-c copy
指定直接拷贝,不经过转码,这样比较快。
16000 采样率,单通道,16bit 位深 wav 文件
ffmpeg -i 1.m4a -ar 16000 -ac 1 -sample_fmt s16 2.wav -loglevel quiet -y
-ar 采样率
-acodec 编码格式 可ffmpeg -codec查看目前支持的编码格式
-sample_fmt 设置位深 ffmpeg -i 1.m4a -sample_fmts 查看支持的位深
-ac 设置通道数。输出会默认和输入通道数相同。输入流是采音设备这个选项对于输入流才有效。
如下可查看音视频源数据。 -hide_banner精简模式查看
C:\Users\fang\Desktop>ffprobe -i 3.mp3 -hide_banner Input #0, mp3, from '3.mp3': Metadata: major_brand : mp42 minor_version : 0 compatible_brands: isommp42 com.android.version: 10 encoder : Lavf58.76.100 Duration: 00:02:28.10, start: 0.138125, bitrate: 24 kb/s Stream #0:0: Audio: mp3, 8000 Hz, stereo, fltp, 24 kb/s
ffmpeg -ss 00:00:03 -t 00:00:04 -i test.mpg -vcodec copy -acodec copy test_cut.mpg
1、屏幕录制并保存成文件
ffmpeg -f gdigrab -i desktop eguid.mp4
2、屏幕录制并推流
ffmpeg -f gdigrab -i desktop -vcodec libx264 -preset:v ultrafast -tune:v zerolatency -f flv rtmp://eguid.cc:1935/rtmp/destop
ffmpeg -i rtsp://184.72.239.149/vod/mp4://BigBuckBunny_175k.mov -rtsp_transport tcp -vcodec h264 -acodec aac -f flv rtmp://eguid.cc:1935/rtmp/eguid
ffprobe [OPTIONS] [INPUT_FILE]
man ffplay
— 请参阅手册。
ffplay -h
— 显示帮助。
-v error
— 除非出现错误,否则隐藏日志。
-show_format
— 使用标签显示格式化的视频元数据。
show_streams
— 显示文件中的所有流(视频和音频)。
-print_format
— 以特定格式(CSV/XML/JSON)打印元数据。
select_streams
-show_entries stream
= 仅显示特定属性及其嵌套依赖项。
-show_entries stream= default-noprint_wrappers=1
— 仅显示特定属性。-f format 强制使用某种格式
-sexagesimal 时间单元格式化 HOURS:MM:SS.MICROSECONDS
-pretty 格式美化
-print_format format 格式化(可选值:default,compact,csv, flat,ini, json,xml)
-of format -print_format别名
-select_streams stream_specifier 选择指定流
-sections 打印节的结构和信息
-show data 显示包数据
-show_data_hash 显示包数据哈希值
-show_error 显示文件探测/检测错误
-show_format 显示格式或者容器信息
-show_frames 显示帧信息
-show_format_entry entry 根据格式/容器信息显示指定entry
-show_packets 显示包信息
-show_programs 显示程序信息
-show_streams 显示流信息
-show_chapters 显示章节信息
-count frames 统计每个流的帧数
-count_packets 统计每个流的包数
-show_program_version 显示ffprobe版本
-show_library_versions show library versions
-show_versions show program and library versions
-show_pixel_formats 显示像素格式
-show_private_data show private data
-private same as show_private_data
-bitexact force bitexact output
-read_intervals read _intervals set read intervals
-default generic catch all option
(1)显示所有视频元数据。
(2)上面的示例,如果你只想获取 duration属性。
$ ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1 input.mp4
Output: size=368644
(3)如果你只想要没有键的值。
$ ffprobe -v error -show_entries format=size -of default=noprint_wrappers=1:nokey=1 input.mp4
Output: 368644
(4)正在获取视频的宽度和高度(分辨率)
$ ffprobe -v error -select_streams v:0 -show_entries stream=height,width -of csv=s=x:p=0 input.mp4
Output: 1280x720
ffplay [OPTIONS] [INPUT_FILE]
ffplay -h
— 显示支持命令参数。
ffplay
— 全屏播放视频。
-noborder
—在弹出窗口中播放视频时隐藏标题栏。
-[top/left/bottom/right]
— 在特定坐标中创建弹出窗口。默认情况下,它会在屏幕中央弹出。-x强制设置视频播放时显示窗口的宽度
-y强制设置视频播放时显示窗口的高度
-S设置视频显示的宽高
-fs强制全屏显示
-an屏蔽音频
-vn屏蔽视频
-Sn屏蔽字幕
-ss根据设置的秒进行定位拖动
-t 设置播放视频/音频长度
-Bytes设置定位拖动的策略,0为不可拖动,1为可拖动,-1为自动
-Nodisp关闭图形化显示窗口
-f 强制使用设置的格式进行解析
-window title设置显示窗口的标题
-af设置音频的滤镜
-Codec强制使用设置的codec进行解码
-autorotate 自动旋转视频
-ast设置将要播放的音频流
-vst设置将要播放的视频流
-sst设置将要播放的字幕流
-Stats输出多媒体播放状态
-Fast非标准化规范的多媒体兼容优化
-sync音视频同步设置可设置根据音频视频进行参考,视频时间参考,或者外部扩展时间进行参考
-autoexit多媒体播放完毕自动退出ffplay,ffplay默认播放完毕不退出播放器
-exitonkeydown 当有按键按下事件产生时退出ffplay
-exitonmousedown 当有鼠标按键事件产生时退出ffplay
-loop设置多媒体文件循环播放次数
-framedrop当CPU资源占用过高时,自动丢帧
-infbuf设置无极限的播放器buffer,这个选项常见于实时流媒体播放场景
-vf视频滤镜设置
-acodec强制使用设置的音频解码器
-vcodec 强制使用设置的视频解码器
你可以在这里找到更多的FFplay用法:https://ffmpeg.org/ffplay-all.html
(1)全屏播放名为video.mp4的视频文件。
$ ffplay video.mp4
(2)在弹出窗口中播放视频文件,大小为600宽,600高,没有标题栏。
$ ffplay video.mp4 -x 600 -y 600 -noborder