FFmpeg 视频处理

简介

FFmpeg是一个开源的跨平台多媒体处理工具套件,它包含了一系列用于处理音频、视频、字幕和图像的库和程序。FFmpeg可以执行多种多媒体处理操作,如格式转换、编码、解码、流媒体传输等,它被广泛应用于视频编辑、转码、流媒体服务器以及其他多媒体处理领域。

FFmpeg的历史可以追溯到2000年,最初由法国程序员Fabrice Bellard创建。Fabrice Bellard最初创建了一个叫做FFmpeg的项目,以实现MPEG视频的解码。FFmpeg最初只是一个命令行工具,但随着时间的推移,它不断发展壮大,并且逐渐成为一个完整的多媒体处理工具套件。

应用场景和具体实现功能

格式转换:FFmpeg可以将一个多媒体文件转换为不同的格式,如将视频文件转换为不同的编码格式(如H.264、HEVC、VP9)或容器格式(如MP4、MKV、AVI)。

视频编码和解码:FFmpeg可以对视频进行编码和解码,以改变视频的编码格式或进行视频文件的压缩。

音频编码和解码:FFmpeg可以对音频进行编码和解码,以改变音频的编码格式或进行音频文件的压缩。

视频剪辑和裁剪:FFmpeg可以从视频文件中提取特定的片段,或对视频进行裁剪,以获得所需的时间段或尺寸。

视频合并和拼接:FFmpeg可以将多个视频文件合并成一个,或将多个视频片段拼接在一起,创建一个连续的视频。

视频转码和优化:FFmpeg可以对视频进行转码,改变其编码参数、分辨率、比特率等,以获得更好的视觉效果或适应特定的设备或平台需求。

视频处理和滤镜:FFmpeg提供了多种滤镜和效果,可以对视频进行处理,如添加水印、调整亮度、对比度、色彩等。

实时流媒体传输:FFmpeg可以将多媒体内容实时编码并流式传输到网络上,以实现实时视频直播、视频会议等应用。

屏幕录制:FFmpeg可以捕捉屏幕上的活动,并将其保存为视频文件,用于创建教学视频、演示文稿等。

生成缩略图:FFmpeg可以从视频或音频文件中提取关键帧图像

视频分析和处理:FFmpeg提供了一些工具和库,可以进行视频质量评估、视频编码参数分析、视频处理算法实现等。

Demo

肉眼无损压缩

参考 -crf 参数优化

FFmpeg视频转码技巧之-crf参数(H.264篇)

x265的编码参数preset级别对性能的影响

ffmpeg -i 坐船.mp4 -c:v libx264 -preset medium -crf 28 -c:a copy demo.mp4
原始大小
压缩后

给视频添加背景音乐

参考

截取音乐片段

ffmpeg -i 植地雅哉\ -\ 静寂.flac  -ss 00:00:19 -t 9 a2.mp3 -y

-i 输入文件
-ss 开始时间
-t 持续时间
-y 覆盖

去除视频原声音

ffmpeg -i 16072614418853318.mp4  -an v2.mp4 -y

合并视频和音频,时长要一致

ffmpeg -i a2.mp3 -i v2.mp4 demo2.mp4

合并视频和音乐,保留视频原声音

ffmpeg -i a3.mp3 -i 16072664036058512.mp4 -threads 2 -filter_complex amix=inputs=2:duration=first:dropout_transition=0 optout.mp4 -y

视频加水印

ffmpeg -i 视频输入路径 -vf "movie=水印图片路径 [watermark]; [in][watermark] overlay=x坐标:y坐标 [out]" -y 视频输出路径

获取转码进度

使用GPU加速

参考

ubuntu 查看显卡驱动

CUDA 工具包

sudo apt install nvidia-cuda-toolkit

本地安装

wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/cuda-ubuntu2004.pin
sudo mv cuda-ubuntu2004.pin /etc/apt/preferences.d/cuda-repository-pin-600
wget https://developer.download.nvidia.com/compute/cuda/11.1.0/local_installers/cuda-repo-ubuntu2004-11-1-local_11.1.0-455.23.05-1_amd64.deb
sudo dpkg -i cuda-repo-ubuntu2004-11-1-local_11.1.0-455.23.05-1_amd64.deb
sudo apt-key add /var/cuda-repo-ubuntu2004-11-1-local/7fa2af80.pub
sudo apt-get update
sudo apt-get -y install cuda

报错提示

The following packages have unmet dependencies:
 cuda : Depends: cuda-11-1 (>= 11.1.0) but it is not going to be installed
E: Unable to correct problems, you have held broken packages.

解决

sudo apt install cuda-11-1

网络安装

wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/cuda-ubuntu2004.pin
sudo mv cuda-ubuntu2004.pin /etc/apt/preferences.d/cuda-repository-pin-600
sudo apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/7fa2af80.pub
sudo add-apt-repository "deb https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/ /"
sudo apt-get update
sudo apt-get -y install cuda

验证是否安装成功

验证安装

~$ /usr/local/cuda-11.1/bin/nvcc -V
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2020 NVIDIA Corporation
Built on Tue_Sep_15_19:10:02_PDT_2020
Cuda compilation tools, release 11.1, V11.1.74
Build cuda_11.1.TC455_06.29069683_0

重新编译ffmpeg 安装nv-codec-headers库

ffmpeg -hwaccels命令查看支持的硬件加速选项

~$ ffmpeg -hwaccels

Hardware acceleration methods:
vdpau
cuda
vaapi
drm
opencl
cuvid

cuvid的硬件加速选项,这就是CUDA提供的GPU视频编解码加速选项

查看cuvid提供的GPU编解码器ffmpeg -codecs | grep cuvid

DEV.LS h264                 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (decoders: h264 h264_v4l2m2m h264_cuvid ) (encoders: libx264 libx264rgb h264_nvenc h264_omx h264_v4l2m2m h264_vaapi nvenc nvenc_h264 )
 DEV.L. hevc                 H.265 / HEVC (High Efficiency Video Coding) (decoders: hevc hevc_v4l2m2m hevc_cuvid ) (encoders: libx265 nvenc_hevc hevc_nvenc hevc_v4l2m2m hevc_vaapi )
 DEVIL. mjpeg                Motion JPEG (decoders: mjpeg mjpeg_cuvid ) (encoders: mjpeg mjpeg_vaapi )
 DEV.L. mpeg1video           MPEG-1 video (decoders: mpeg1video mpeg1_v4l2m2m mpeg1_cuvid )
 DEV.L. mpeg2video           MPEG-2 video (decoders: mpeg2video mpegvideo mpeg2_v4l2m2m mpeg2_cuvid ) (encoders: mpeg2video mpeg2_vaapi )
 DEV.L. mpeg4                MPEG-4 part 2 (decoders: mpeg4 mpeg4_v4l2m2m mpeg4_cuvid ) (encoders: mpeg4 libxvid mpeg4_v4l2m2m )
 D.V.L. vc1                  SMPTE VC-1 (decoders: vc1 vc1_v4l2m2m vc1_cuvid )
 DEV.L. vp8                  On2 VP8 (decoders: vp8 vp8_v4l2m2m libvpx vp8_cuvid ) (encoders: libvpx vp8_v4l2m2m vp8_vaapi )
 DEV.L. vp9                  Google VP9 (decoders: vp9 vp9_v4l2m2m libvpx-vp9 vp9_cuvid ) (encoders: libvpx-vp9 vp9_vaapi )
nvidia-smi 查看GPU使用情况

watch -n 1 nvidia-smi 定时间隔一秒查看信息

测试

ffmpeg -hwaccel cuvid -c:v h264_cuvid -i 坐船.mp4 -c:v h264_nvenc -preset medium -crf 28 -c:a copy -y gpu.mp4

如果是手机拍摄的视频会报上述错误,说明视频有旋转信息,手机拍摄的视频自带90°旋转。需要加 -noautorotate 参数

ffmpeg -hwaccel cuvid -c:v h264_cuvid -noautorotate -i 坐船.mp4 -c:v h264_nvenc -preset medium -crf 28 -c:a copy -y gpu.mp4
  • -hwaccel cuvid 指定使用cuvid硬件加速
  • -c:v h264_cuvid:使用h264_cuvid进行视频解码
  • -c:v h264_nvenc:使用h264_nvenc进行视频编码
  • -noautorotate 去除视频旋转信息

去除视频旋转信息后视频,文件大小变得很小,但是画质很糊

ffmpeg -hwaccel cuvid -c:v h264_cuvid -noautorotate -i 2019.mp4 -c:v h264_nvenc -preset medium -crf 28 -c:a copy -y 2019gpu.mp4

使用GPU压缩视频最后文件大小没变,crf参数相同。

以目前掌握的知识来说,推荐使用CPU压缩,缺点是比GPU慢。后续深入了解后再补充

截取封面图

要使用FFmpeg截取视频的封面,可以使用以下命令:

ffmpeg -i input.mp4 -vframes 1 -q:v 2 output.jpg

这个命令的含义是:

-i input.mp4 指定输入文件为 input.mp4,你可以将其替换为你实际的视频文件名。
-vframes 1 指定要提取的帧数量,这里设置为1,即只提取一帧,也就是封面。
-q:v 2 指定输出图像的质量,范围是0-31,其中0表示最高质量。这里设置为2,表示输出较高质量的图像。
output.jpg 指定输出文件名,这里设置为 output.jpg,你可以根据需要修改。
执行命令后,FFmpeg将从输入视频中提取一帧,并将其保存为JPEG图像文件(封面),命名为 output.jpg

视频导出图片

首先使用ffmpeg -i xxx.mp4 查看 视频fps 信息 56.20 fps

然后执行

ffmpeg -i IMG_1529.MP4 -f image2 -vf fps=56.20 -qscale:v 2 IMG_1529/img%04d.jpg

参数说明

-i: 视频路径 -f: 图片格式 fps=5: 每5s取一帧 fps=1/5: 每1s取5帧 img%04d.jpg: 生成的图片命名格式 IMG_1529为输出目录

图片序列合并成视频

ffmpeg -f image2 -i image%d.jpg video.mpg

截取视频片段

使用 -ss 和 -t 选项,从第0秒开始,向后截取31秒视频,并保存

ffmpeg -ss 00:00:00 -i video.mp4 -vcodec copy -acodec copy -t 00:00:31 output1.mp4

从第01:33:30 开始,向后截取 00:47:16 视频,并保存

ffmpeg -ss 01:33:30 -i video.mp4 -vcodec copy -acodec copy -t 00:47:16 output2.mp4

合并视频

  把剪切得到的两个视频合并成一个视频

  使用 TS格式拼接视频

  先将 mp4 转化为同样编码形式的 ts 流,因为 ts流是可以 concate 的,先把 mp4 封装成 ts ,然后 concate ts 流, 最后再把 ts 流转化为 mp4。

ffmpeg -i output1.mp4 -vcodec copy -acodec copy -vbsf h264_mp4toannexb output1.ts
ffmpeg -i output2.mp4 -vcodec copy -acodec copy -vbsf h264_mp4toannexb output2.ts

 为了减少命令的输入,需要一个filelist.txt文件,里面内容如下

file 'output1.ts'
file 'output2.ts'

合并视频命令

ffmpeg -f concat -i filelist.txt -acodec copy -vcodec copy -absf aac_adtstoasc output.mp4

视频快速转MP3

ffmpeg -i 让一切情绪流动.MP4 -f mp3 让一切情绪流动.mp3

FFMpeg无损合并视频的多种方法

FFmpeg批量提取视频的某一帧作为封面

ffmpeg中文文档