# ffmpeg入门篇 ## 简单了解视频组成 ![视频流和音频流信息](https://files.getquicker.net/_sitefiles/kc/kb/2023/10/09/151455_234516_%E8%A7%86%E9%A2%91%E6%88%AA%E5%9B%BE.jpg) 如图所示 **1.「视频」由「视频流」和「音频流」信息组成** **2.「总比特率」=视频流的「数据速率」+音频的「比特率」** **3.数据速率、帧速率和视频时长三者之间关系** - 文件大小 = 数据速率 x 视频时长 - 总帧数 = 帧速率 x 视频时长 - 数据速率和帧速率之间没有直接的关系,但是它们都会影响视频的质量和文件大小。 浅白说法(不一定对):数据速率:画质,帧速率:流畅度 **4.视频流是由帧组成的** 4.1帧的宽度和高度构成画布分辨率由`-s` 、`-video_size` 、 `-vf scale`参数控制, - -s 640x480:用于设置**输出**视频的分辨率 - - -vf scale=640:480:用于设置**输出**视频的分辨率 - - -video\_size 640x480:用于设置**输入**视频的分辨率 4.2帧速率指每秒输出帧数量,由参数是`-r`或`-fps`控制,两者作用相同,写法不同。 - -r 30 - - -vf fps=30 4.3 数据速率(码率)由`-b:v`参数控制,如:`-b:v 3000k` **5.音频流** 5.1比特率由`-b:a`参数控制,如:`-b:a 128k` ## 命令行参数 大体可以分成五个部分。 ``` $ 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 -h`来查看所有可用的选项和参数,以获取更详细的信息。 ### -vcodec 相关参数 | `-vcodec`参数 | 含义 | | --- | --- | | `copy` | 复制原始视频编解码器,不重新编码。 | | `libx264` | 将视频压缩为H.264格式。 | | `libx265` | 将视频压缩为H.265/HEVC格式。 | | `h264_nvenc` | 使用NVIDIA GPU硬件加速进行H.264编码。 | | `hevc_nvenc` | 使用NVIDIA GPU硬件加速进行H.265/HEVC编码。 | | `h264_qsv` | 使用Intel Quick Sync Video硬件加速进行H.264编码。 | | `hevc_qsv` | 使用Intel Quick Sync Video硬件加速进行H.265/HEVC编码。 | | `libvpx` | 将视频压缩为VP8或VP9格式(通过`-b:v`指定压缩比特率)。 | | `huffyuv` | 生成无损视频。 | ### -acodec 相关参数 | `-acodec`参数 | 含义 | | --- | --- | | `copy` | 复制原始音频编解码器,不重新编码。 | | `aac` | 将音频压缩为AAC格式。 | | `libmp3lame` | 将音频压缩为MP3格式。 | | `libopus` | 将音频压缩为Opus格式。 | | `libvorbis` | 将音频压缩为Vorbis格式。 | | `pcm_s16le` | 生成16-bit线性PCM音频。 | | `flac` | 将音频压缩为FLAC格式(无损)。 | # 视频解码 ## 视频解码方式(Dcodec) | 解码器选项 | 描述 | | --- | --- | | h264\_cuvid | NVIDIA CUDA加速的H.264解码器 | | hevc\_cuvid | NVIDIA CUDA加速的HEVC解码器 | | mpeg2\_cuvid | NVIDIA CUDA加速的MPEG-2解码器 | | vp9\_cuvid | NVIDIA CUDA加速的VP9解码器 | | h264\_qsv | Intel Quick Sync Video加速的H.264解码器 | | hevc\_qsv | Intel Quick Sync Video加速的HEVC解码器 | | mpeg2\_qsv | Intel Quick Sync Video加速的MPEG-2解码器 | | vp9\_qsv | Intel Quick Sync Video加速的VP9解码器 | | h264\_vdpau | NVIDIA VDPAU加速的H.264解码器 | | mpeg2\_vdpau | NVIDIA VDPAU加速的MPEG-2解码器 | | vc1\_vdpau | NVIDIA VDPAU加速的VC-1解码器 | | h264\_amf | AMD AMF加速的H.264解码器 | | hevc\_amf | AMD AMF加速的HEVC解码器 | 示例: ``` ffmpeg -hwaccel cuvid -c:v h264_cuvid -i input.mp4 -c:v h264_nvenc -preset fast -tune hq -rc constqp -c:a copy -y output.mp4 ffmpeg -hwaccel cuvid -c:v hevc_cuvid -i input.mp4 -c:v copy -c:a copy output.mp4 ffmpeg -hwaccel qsv -c:v h264_qsv -i input.mp4 -c:v copy -c:a copy output.mp4 ffmpeg -hwaccel amf -c:v h264_amf -i input.mp4 -c:v copy -c:a copy output.mp4 ``` # 视频编码 ## 一、视频编码方式(Ecodec) cpu(h264和h265),显卡,核显,如`-c:v libx264`或`-vcodec libx264` | 编码方式 | 参数 | 优点 | 缺点 | | --- | --- | --- | --- | | CPU H.264 | libx264 | 兼容性好,可用于各种设备 | 编码速度较慢,对CPU性能要求较高 | | CPU H.265 | libx265 | 压缩率高,文件体积小 | 编码速度较慢,对CPU性能要求较高 | | NVIDIA NVENC | h264\_nvenc | 编码速度快,对CPU占用低 | 兼容性较差,只能在英伟达显卡上使用 | | NVIDIA NVENC | hevc\_nvenc | 压缩率高,文件体积小,编码速度快 | 兼容性较差,只能在英伟达显卡上使用 | | AMD VCE | h264\_amf | 编码速度快,对CPU占用低 | 兼容性较差,只能在AMD显卡上使用 | | AMD VCE | hevc\_amf | 压缩率高,文件体积小,编码速度快 | 兼容性较差,只能在AMD显卡上使用 | | Intel Quick Sync Video | h264\_qsv | 编码速度快,对CPU占用低 | 兼容性较差,只能在搭载Intel核显的设备上使用 | | Intel Quick Sync Video | hevc\_qsv | 压缩率高,文件体积小,编码速度快 | 兼容性较差,只能在搭载Intel核显的设备上使用 | 使用显卡和核显一定要安装好匹配的驱动!! ### H.264编码 要保持H.264编码的**视频视觉无损**,你可以使用以下参数来最大程度地减少编码引入的失真: ``` ffmpeg -i input.mp4 -c:v libx264 -preset slow -crf 0 -c:a copy output.mp4 ``` 这个命令将输入视频文件`input.mp4`使用libx264编码器进行重新编码,设置预设为`slow`以获得更好的质量。`-crf 0`参数指定了恒定质量因子为0,表示最高的质量。音频流将直接复制到输出文件中,保持无损。 ### NVIDIA显卡 可以使用`-hwaccel`参数来指定使用的硬件加速器,例如: ``` ffmpeg -hwaccel cuvid -i input.mp4 -c:v h264_nvenc -preset slow -tune hq -rc constqp -crf 18 -c:a copy output.mp4 ``` 在这个命令中,`-hwaccel cuvid`表示使用NVIDIA显卡的硬件加速器来加速视频解码。同时,`-c:v h264_nvenc`表示使用NVIDIA显卡的硬件加速器来加速视频编码。这样可以大大提高视频编码和解码的速度,同时获得更好的视频质量。 ### AMD显卡 可以使用AMF SDK来实现。下面是一个示例代码: ``` ffmpeg -hwaccel amf -i input.mp4 -c:v h264_amf -b:v 5M -c:a copy output.mp4 ``` 其中,-hwaccel amf表示使用AMF SDK加速编码,-c:v h264\_amf表示使用AMD的H.264编码器,-b:v 5M表示设置视频比特率为5Mbps。其他参数可以根据需要进行调整。 ### intel核显 如果您的电脑配备了Intel集成显卡,可以使用以下代码进行核显加速编码: ``` ffmpeg -i input.mp4 -c:v h264_qsv -global_quality 25 -c:a copy output.mp4 ``` ### 使用动态线程数来优化混合编码的性能 NVIDIA显卡+CPU 在FFmpeg中,可以使用`-threads`选项来指定线程数,也可以使用`-threads auto`选项来自动检测系统的CPU核心数,并根据核心数动态调整线程数。 ``` ffmpeg -hwaccel cuvid -i input.mp4 -c:v h264_nvenc -preset slow -tune hq -rc constqp -crf 18 -c:a copy -threads auto output.mp4 ``` 这样,FFmpeg将自动根据系统的CPU核心数来动态调整线程数,以获得更好的性能和效率。 要同时使用NVIDIA的NVENC和CPU进行转码加速,你可以配置`ffmpeg`来利用系统中的多个处理器(CPU)和GPU资源。以下是一个示例命令,演示在转码过程中同时使用NVENC和CPU加速: ``` ffmpeg -i input.mp4 -c:v h264_nvenc -c:a copy -c:v hevc -preset faster -c:a copy output.mp4 ``` ## 二、音频编码 如:`-c:a mp3`或`-acodec libmp3lame` | 编码方式 | 参数 | 优点 | 缺点 | | --- | --- | --- | --- | | AAC | - | 压缩率高,文件大小小,兼容性好 | 对CPU性能要求较高 | | MP3 | `libmp3lame` | 兼容性好,可用于各种设备 | 压缩率较低,文件大小较大 | | FLAC | - | 无损压缩,音质高 | 压缩率较低,文件大小较大 | | Opus | - | 压缩率高,文件大小小,适用于网络传输 | 兼容性较差,只能在支持Opus的设备上使用 | | Vorbis | - | 压缩率高,文件大小小,兼容性好 | 对CPU性能要求较高 | ## 三、编码速度 下表列出了ffmpeg中-preset参数的常用取值及其对应的编码效果: | 参数 | 速度 | 质量 | 说明 | | --- | --- | --- | --- | | ultrafast | 最快 | 最差 | 适用于实时编码或者对速度要求较高的场景 | | superfast | 较快 | 较差 | 适用于对速度要求较高,但对质量要求不高的场景 | | veryfast | 快 | 一般 | 适用于对速度要求较高,但对质量要求一般的场景 | | faster | 较快 | 一般 | 适用于对速度要求较高,但对质量要求一般的场景 | | fast | 中等 | 一般 | 适用于对速度和质量都有一定要求的场景 | | medium | 中等 | 中等 | 适用于对速度和质量都有一定要求的场景 | | slow | 较慢 | 较好 | 适用于对质量要求较高,但对速度要求不高的场景 | | slower | 慢 | 较好 | 适用于对质量要求较高,但对速度要求不高的场景 | | veryslow | 最慢 | 最好 | 适用于对质量要求最高,对速度要求不高的场景 | 需要注意的是,编码速度越慢,质量越好,相应耗时越长。如`-preset slow` ## 四、控制参数 ### 控制视频质量编码参数 ffmpeg中`-crf`、`-qp`和 `-b:v`是用于控制视频编码质量的参数,当使用x264或x265编码器时,**在不设置参数的情况下,FFmpeg默认使用**\*\*`-crf`\*\***参数进行编码。** ### -crf、-qp和-b:v的区别和关系 下表展示了它们各自的优缺点和作用: | 参数 | 作用 | 取值范围 | 优点 | 缺点 | | --- | --- | --- | --- | --- | | -crf | 恒定**质量**因子;crf值越小,视频质量越高,但文件大小也越大。适用于需要保证视频质量的场景,如`-crf 18` | 取值范围:0-51 推荐使用:18-28 | 可以自动调整比特率,在一定程度上控制视频质量和文件大小的平衡,适用于大多数情况,保证视频质量 | 文件大小不可控,不够精确,可能会出现一些视觉上的失真 | | -qp | 恒定**量化**参数;qp值越小,视频质量越高,但文件大小也越大。适用于需要控制文件大小的场景,如`-qp 12` | 取值范围:0-69 推荐使用:12-28 | 直接控制量化参数,可以精确控制视频质量,可控制文件大小 | 不够直观,需要根据经验或测试来确定最佳取值,不易掌握 | | -b:v | 控制**比特率**;比特率越高,视频质量越高,但文件大小也越大。适用于需要控制文件大小的场景,如`-b:v 4000k` | - 1080p @ 30fps: 3,000 - 6,000 kbps - 1080p @ 60fps: 4,500 - 9,000 kbps - 720p @ 30fps: 1,500 - 4,000 kbps - 720p @ 60fps: 2,250 - 6,000 kbps - 480p @ 30fps: 500 - 2,000 kbps - 480p @ 60fps: 750 - 3,000 kbps | 直接控制**比特率**,可控制文件大小 | 视频质量不可控 | - 如果同时使用-crf和-qp,那么-crf会自动调整压缩质量,而-qp则会按照设置的量化参数进行压缩,这两种方式会产生冲突。 - 如果同时使用-crf和-b:v,那么-crf会自动调整压缩质量,而-b:v则会按照设置的比特率进行压缩,这两种方式也会产生冲突。 - 如果同时使用-qp和-b:v,那么-qp会按照设置的量化参数进行压缩,而-b:v则会按照设置的比特率进行压缩,这两种方式也会产生冲突。 因此,建议在使用ffmpeg时只选择其中一种压缩方式,以避免产生冲突。 示例 `-crf`参数 ``` ffmpeg -i input.mp4 -c:v libx264 -preset slow -crf 18 -c:a copy output.mp4 ``` `-qp`参数 ``` ffmpeg -i input.mp4 -c:v libx264 -preset slow -qp 22 -c:a copy output.mp4 ``` 解释: - `-i input.mp4`:指定输入文件为input.mp4。 - `-c:v libx264`:指定视频编码器为libx264。 - `-preset slow`:指定编码速度为慢速,以获得更好的质量。`` - `-qp 18`:指定视频质量为18,数值越小,视频质量越好,但文件大小也越大。 - `-c:a copy`:指定音频编码器为copy,即不进行音频转码。 - `output.mp4`:指定输出文件为output.mp4。 这个命令将会将input.mp4文件转码为H.264格式的output.mp4文件,并且尽可能地保留视频的清晰度。