FFmpeg库之ffmpeg

文章目录

ffmpeg命令行使用

ffmpeg是一个通用的媒体转换器。它可以读取各种输入(包括实时抓取/录制设备),对其进行过滤,并将它们转码为多种输出格式。

语法格式:

复制代码
ffmpeg [global_options] {[input_file_options] -i input_url} ... {[output_file_options] output_url}...

基本命令

命令名称 作用
-version 显示ffmpeg版本
-formats 显示可用的格式
-demuxers 显示可用的解复用器
-protocols 显示可用的协议
-muxers 显示可用的复用器
-filters 显示可用的过滤器
-devices 显示可用的设备
-pix_fmts 显示可用的像素格式
-codecs 显示所有的编解码器
-sample_fmts 显示可用的采样格式
-decoders 显示可用的解码器
-layouts 显示声道名称
-encoders 显示所有的编码器
-colors 显示识别的颜色名称
-bsfs 显示比特流filter

选择流 -map选项

-map选项用于手动控制每个输出文件中的流选择。用户可以跳过-map,让ffmpeg执行如下所述的自动流选择。-vn/-an/-sn/-dn选项可用于分别跳过包含视频、音频、字母和数据流。

使用格式如下:

-map 文件索引位置:流索引位置

-map 文件索引位置:流的类型

-map 文件索引位置:流的类型:流的索引位置

流类型:

  • a 表示音频流
  • v 表示视频流
  • s 表示字幕流
  • d 表示数据流
  • t 表示附件六
    注意:索引位置从0开始

在特定输出文件没有任何映射选项的情况下,ffmpeg检查输出格式以检查哪种类型的流可以包含在其中,即视频,音频或字母。对于每个可接受的流类型,ffmpeg将从所有输入中选择一个可用的流。

它将根据以下标准选择该流:

  • 对于视频来说,它是分辨率最高的流媒体
  • 对于音频,它是具有最多通道的流
  • 对于字母,这是找到的第一个字幕流,但有一个警告,输出的格式的默认字幕编码器可以是基于文本的,也可以是基于图像的,并且只会选择相同类型的字幕流
  • 在相同类型的多个流速率相等的情况下,选择索引最低的流
    注意:数据或附件流不会自动选择,只能使用-map包含

例如:假设有如下几个视频文件

复制代码
input file 'A.avi'
		stream 0: video 640x360
		stream 1: audio 2 channels

input file 'B.mp4'
		stream 0: video 1920x1080
		stream 1: audio 2 channels
		stream 2: subtitles (text)
		stream 3: audio 5.1 channels
		stream 4: subtitles (text)

input file 'C.mkv'
		stream 0: video 1280x720
		stream 1: audio 2 channels
		stream 2: subtitles (image)

执行如下命令
ffmpeg -i A.avi -i B.mp4 out1.mkv out2.wav -map 1:a -c:a copy out3.mov

指定了3个输出文件,对于前2个,没有设置-map选项,因此ffmpeg将自动为这两个文件选择流(会选择最好的那个流)。

out1.mkv是一个Matroska容器文件,它接受视频、音频和字幕流,因此ffmpeg将尝试在每种类型中选择一种。

对于视频,它将从B.mp4中选择流0,它所在所有输入视频流中具有最高的分辨率。

对于音频,它将从B.mp4中选择流3,因为它有最多的通道。

对于字幕,它将从B.mp4中选择流2,这是A.avi和B.mp4之间的第一个字幕流。

out2.wav只接受音频流,所以只选择B.mp4的流3。

out3.Mov,由于设置了-map选项,因此不会发生自动流选择。-map 1:a选项将选择来自第二个输入B.mp4的所有音频流。此输出文件中不会包含其他流。

对于前两个输出,所有包含的流都将被转码。所选择的编码器将是每个输出格式注册的默认编码器,它可能与所选输入流的编码器不匹配。

对于第三个速出,音频流的编解码器选项已经设置为复制,因此不会发生或可能发生解码-过滤-编码操作。所选流的数据包应从输入文件传送,并在输出文件中进行混合。

主要命令

命令名称 作用
-f fmt (input/output) 强制输入或输出文件格式。通常会自动检测输入文件的格式,并从输出文件的文件扩展名中猜测格式,因此在大多数情况下不需要此选项
-i url (input) 输入文件的URL
-stream_loop number (input) 设置输入流循环的次数。循环0表示没有循环,循环-1表示无限循环
-t duration (input/output) 当用作输入选项(在-i之前)时,限制从输入文件读取数据的持续时间。当用作输出选项(在url之前)时,在其持续时间达到duration后停止写入输出。duration必须是时间持续时间规格,请参阅ffmpeg-utils(1)手册中的时间持续时间部分。
-to position (input/output) 在该位置停止写入输出或读取输出-to和-t是互斥的,-t具有优先级
-ss positon (input/output) 当用作输入选项(在-i前)时,在此输入文件中查找位置。当用作输出选项(在url前)时,解码但丢弃输入,直到时间戳到达指定位置
-c:stream_specifier codec (input/output,per-stream) 为一个或多个流选择编码器(在输出文件前使用)或解码器(在输入文件前使用)。

实例:

  1. 从视频中分离音频

    执行完后生成了aac文件

    2.把上述音频改成mp3,并限制到3秒结束

视频选项

命令名称 作用
-vframes number (output) 设置输出的视频帧数。
-r:stream_specifier fps (input/output,per-stream) 设置帧速率
-s:stream_specifier size (input/output,per-stream) 设置分辨率
-vcodec codec(output) 设置视频编解码器
-pix_fmt:stream_specifier format (input/output,per-stream) 设置像素格式

音频选项

命令名称 作用
-aframes number (output) 设置输出的音频帧数
-ar:stream_specifier freq (input/output,per-stream) 设置音频采样率
-ac:stream_specifier channels (input/output,per-stream) 设置音频通道的数量
-acodec codec (input/output) 设置音频编解码器
-sample_fmt:stream_specifier sample_fmt (input/output,per-stream) 设置音频样本格式

多媒体格式转换

命令名称 作用
ffmpeg -i 输入文件路径 输出文件路径 容器格式转换
ffmpeg -i 输入文件路径 -c:v copy -an 输出文件路径 提取视频流
ffmpeg -i 输入文件路径1 -i 输入文件路径2 ... -map 文件索引1:v -c:v copy -map 文件索引2:v -c:v copy ... 输出文件路径 提取多个视频流到一个文件中
ffmpeg -i 输入文件路径 -c:a copy -vn 输出文件路径 提取音频流
ffmpeg -i 输入文件路径 -c:v 视频编码器名称 输出文件路径 视频转码
ffmpeg -i 输出文件路径 -c:v 视频编码器名称 -an 输出文件路径 抽取视频流转码
ffmpeg -i 输入文件路径 -c:a 音频编码器名称 输出文件路径 音频转码
ffmpeg -i 输入文件路径 -an -c:v rawvideo -s 分辨率 -pix_fmt 像素格式 out.yuv 抽取视频文件的视频原始数据
ffmpeg -s 原始图像分辨率 -pix_fmt 原始图像格式 -i 输入文件路径 -s 目标图像分辨率 -pix_fmt 目标图像格式 输出文件路径 YUV和RGB互相转换
ffmpeg -i 输入文件路径 -vn -ar 采样率 -ac 声道数 -c:a 编码器名称 输出文件路径 抽取视频文件中原始音频数据
ffmpeg -i 输入文件路径 -s 分辨率 输出文件路径 修改视频分辨率
ffmpeg -i 输入文件路径 -b:a 码率 输出文件路径 修改音频码率
ffmpeg -i 输入文件路径 -ar 采样率 输出文件路径 修改音频采样率
ffmpeg -ss 00:00:10 -i 输入文件路径 -t 时长 输出文件路径 从第10秒截取视频,视频时长是后面指定的时长
ffmpeg -i 输入文件路径 输出文件路径(.ts) 视频转ts流
ffmpeg -f concat -i 文件列表.txt 输出文件路径 视频拼接。文件列表.txt格式如下: file 'video-30fps.MP4' 一行一个路径
ffmpeg -i 输入文件路径 -y -f 图片格式 -vframes 帧数 输出文件路径(如果图片超过1张,需要使用%d) 提取视频中的图片
ffmpeg -i 输入文件路径 输出文件路径 图片转视频,例ffmpeg -i img%d.jpg out.mp4
ffmpeg -i 输入文件路径 -t 视频时长 -r 帧率 输出文件路径 视频转GIF
ffmpeg -i 输入文件路径 -f 格式名称 输出文件路径 GIF转视频

滤镜

简单过滤图是指只有一个输入和输出且类型相同的过滤图。它们可以通过在解码和编码之间插入一个额外的步骤来表示:

css 复制代码
 _________                        ______________
|         |                      |              |
| decoded |                      | encoded data |
| frames  |\                   _ | packets      |
|_________| \                  /||______________|
             \   __________   /
  simple     _\||          | /  encoder
  filtergraph   | filtered |/
                | frames   |
                |__________|

简单的过滤器图配置有每个流-筛选选项(与-vf和-af分别为视频和音频的别名)。一个简单的视频过滤图可以如下所示:

css 复制代码
 _______        _____________        _______        ________
|       |      |             |      |       |      |        |
| input | ---> | deinterlace | ---> | scale | ---> | output |
|_______|      |_____________|      |_______|      |________|

请注意,某些过滤器会更改框架属性,但不会更改框架内容。例如, fps上例中的过滤器更改帧数,但不触及帧内容。另一个例子是setpts过滤器,它只设置时间戳,否则不改变地传递帧。

复杂的过滤器图不能简单地描述为应用于一个流的线性处理链。例如,当图具有多个输入和/或输出时,或者当输出流类型与输入不同时,就会出现这种情况。它们可以用下图表示:```

css 复制代码
 _________
|         |
| input 0 |\                    __________
|_________| \                  |          |
             \   _________    /| output 0 |
              \ |         |  / |__________|
 _________     \| complex | /
|         |     |         |/
| input 1 |---->| filter  |\
|_________|     |         | \   __________
               /| graph   |  \ |          |
              / |         |   \| output 1 |
 _________   /  |_________|    |__________|
|         | /
| input 2 |/
|_________|

复杂的过滤图配置为-filter_complex选项。请注意,此选项是全局的,因为复杂的过滤器图本质上不能与单个流或文件明确关联。

-lavfi选项相当于-filter_complex。

复杂过滤器图的一个简单示例是overlay过滤器,它具有两个视频输入和一个视频输出,其中一个视频叠加在另一个视频之上。它的音频对应部分是amix滤波器。

裁剪

bash 复制代码
-vf crop=ow[:oh[:x[:y[:keep_aspect]]]]
  • -vf:使用视频滤镜
  • ow:输出视频的宽度
  • oh:输出视频的高度
  • x:指定裁剪的位置x
  • y:指定裁剪的位置y
  • keep_aspect:是否保持纵横比

例如:指定从(100,200)位置,保持纵横比,裁剪大小为640x480

bash 复制代码
 ffmpeg -i .\video-30fps.MP4 -vf crop=640:480:100:200:0 裁剪.mp4

加水印

bash 复制代码
ffmpeg -i 输入文件路径 -vf drawtext:"fontsize=字体大小:fontfile=字体文件路径:text="水印内容":fontcolor=字体颜色:x=字体位置:y=字体位置" 输出文件路径

#例如
ffmpeg -i .\裁剪.mp4 -vf drawtext="fontfile=SIMLI.TTF: text='你好,世界!':fontcolor=red:x=200:y=300:fontsize=50" 水印.mp4

画中画

bash 复制代码
ffmpeg -i 输入文件路径 -vf movie="画中画视频文件路径,scale=缩放大小[sub];[in][sub]overlay=x=位置:y=位置[out]" 输出文件位置
#例如
ffmpeg -i .\video-60fps.MP4 -vf movie="水印.mp4, scale=320x240[sub];[in][sub]overlay=x=100:y=150[out]" 画中画.mp4

录制

windows需要安装dshow软件,才能录制系统声音。以下命令只针对windows

查看可用的录制设备

bash 复制代码
ffmpeg -list_devices true -f dshow -i dummy

查看录制设备选项参数

bash 复制代码
ffmpeg -f dshow -list_options true -i 类型="设备名称"
#例如
查看摄像头参数
ffmpeg -f dshow -list_options true -i video="USB Camera"
查看麦克风参数
ffmpeg -f dshow -list_options true -i audio="麦克风 (Realtek(R) Audio)"
查看桌面录制参数
ffmpeg -f gdigrab -list_options true -i desktop

录制桌面

bash 复制代码
录制整个桌面
ffmpeg -f gdigrab -i desktop -pix_fmt 图像格式 输出路径
#例如
ffmpeg -f gdigrab -i desktop 桌面录制.mp4

录制指定区域
ffmpeg -r 帧率 -f gdigrab -s 分辨率 -offset_x 宽度偏移量 -offset_y 高度偏移量 -i desktop -vcodec 编码器名称 文件路径
#例如
ffmpeg -f gdigrab -i desktop -s 800x600 -offset_x 100 -offset_y 200  桌面录制2.mp4

录制窗口

bash 复制代码
ffmpeg -f gdigrab -i title="窗口名称" 输出路径

由于大多数程序隐藏了原来的边框,录制出来经常是黑屏

录制摄像头

bash 复制代码
ffmpeg -f dshow -i video="摄像设备名称" 输出路径

#例如
ffmpeg -f dshow -i video="USB Camera" 摄像头录制.mp4

录制麦克风

bash 复制代码
ffmpeg -f dshow -i audio="麦克风 (Realtek(R) Audio)" 麦克风录制.mp3

录制系统声音

bash 复制代码
ffmpeg -f dshow -i audio="立体声混音 (Realtek(R) Audio)" 麦克风录制2.mp3
# audio=的是声卡设备名称

同时录制桌面和麦克风

bash 复制代码
ffmpeg -f gdigrab -i desktop -f dshow -i audio="麦克风 (Realtek(R) Audio)" 桌面加麦克风.mp4

直播

推流

直播推流需要先开启服务器

bash 复制代码
ffmpeg -re -i 输入文件路径 -c copy -f flv rtmp地址
#例如
ffmpeg -re -i video.mp4 -c copy -f flv rtmp://127.0.0.1:1935/live/room
#然后用ffplay观看直播

拉流

bash 复制代码
ffmpeg -i rtmp地址 -c copy 输出文件路径
#例如 
ffmpeg -i rtmp://ns8.indexforce.com/home/mystream -c copy 拉流.flv
#播放拉到的内容
ffplay .\拉流.flv -x 800 -y 600
相关推荐
sycmancia15 分钟前
Qt——多线程间的互斥
开发语言·qt
FlightYe5 小时前
FFmpeg移动端硬解机制
linux·网络·ffmpeg·音视频·实时音视频·视频编解码
尘中远5 小时前
【Qwt 7.0 系列】常用图表类型实战 —— 柱状图、散点图、箱线图与直方图
qt·qwt·工业软件·科学绘图
尘中远6 小时前
【Qwt 7.0 系列】交互功能详解 —— 平移、缩放、坐标轴交互与数据拾取
qt·数据可视化·绘图·qcustomplot·qwt·科学绘图
sycmancia6 小时前
Qt——进程与线程的概念
qt
郝学胜-神的一滴7 小时前
Qt 高级编程 034:深耕QWidget底层内核—彻底吃透无边框窗口设计核心原理
开发语言·c++·qt·程序人生·软件开发·用户界面
尘中远7 小时前
【Qwt 7.0 系列】3D 数据可视化 —— OpenGL 高性能三维绘图
qt·3d·qcustomplot·qwt·科学绘图·高性能绘图
满天星83035778 小时前
【Qt】控件(二) (geometry及与frameGeometry的区别)
开发语言·qt
大气的小蜜蜂8 小时前
基于Python+PyQt5+SQLite的药房管理系统实现:事务一致性与界面解耦全流程解析
python·qt·sqlite
尘中远8 小时前
【Qwt 7.0 系列】总体架构解析 —— 从单体到三库模块化的演进
qt·matplotlib·绘图·qwt·科学绘图