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中文文档

PHP图像处理相关知识

Exif 扩展

通过使用 exif 扩展,你可以操作图像元数据。 例如:你可以使用 exif 相关的函数从数码相机拍摄的图片文件中读取元数据。 通常 JPEG 和 TIFF 格式的图像文件都包含元数据。

可交换图像文件格式(英语:Exchangeable image file format,官方简称Exif),是专门为数码相机的照片设定的,可以记录数码照片的属性信息和拍摄数据。

GD 扩展

GD库是php处理图形的扩展库,GD库提供了一系列用来处理图片的API,使用GD库可以处理图片,或者生成图片,也可以给图片加水印

ImageMagick 扩展

ImageMagick图片处理是一套功能强大、稳定而且免费的工具集和开发包,可以用来读、写和处理超过90种的图片文件,包括流行的TIFF、JPEG、GIF、 PNG、PDF以及PhotoCD等格式。 [1]  利用ImageMagick,你可以根据web应用程序的需要动态生成图片, 还可以对一个(或一组)图片进行改变大小、旋转、锐化、减色或增加特效等操作,并将操作的结果以相同格式或其它格式保存,对图片的操作,即可以通过命令行进行,也可以用C/C++、Perl、Java、PHP、Python或Ruby编程来完成。同时ImageMagick提供了一个高质量的2D工具包,部分支持SVG。ImageMagic的主要精力集中在性能,减少bug以及提供稳定的API和ABI上。

php扩展 Imagick是用 ImageMagic API 来创建和修改图像的PHP官方扩展。所以使用时不需要安装ImageMagick 软件,只需要安装Imagick扩展就可以了

Gmagick 扩展

GraphicsMagick 是一个用来读写、生成超过90种图像格式的工具集合,支持包括 TIFF, JPEG, JPEG-2000,PNG, PDF, PhotoCD, SVG, 和GIF 等图像格式。GraphicsMagick 是基于 ImageMagick 开发的。

linux安装webp支持

不安装情况下,无法用php程序读取(或者转换成)webp图片

ubuntu

sudo apt install webp

centos

yum -y install libwebp-devel libwebp-tools

个人的经验总结

项目维护

接手旧项目时,不理解的代码,一定不要去乱碰。nginx配置也是一样的。你不知道它在哪里被用到了。不能抱有侥幸心理。

项目永远不会结束

不要相信客户和产品经理以后不会改需了这类话。产品(项目)存在意义就是解决人的需求(市场),让更多的人使用它,人的需求是变化的(市场竞争),项目只要存在就会有需求改动和功能增加。但是不能任由产品乱来。类比,好多人会追问生命的意义,生命的意义就是好好活着,生命一旦不能生存就只有死亡没有什么意义。

容灾

运营的项目一定要有容灾能力,服务,数据,文件 ,安全。不能抱有侥幸心理。这是常识。写在这里是为了提醒自己不再犯错。

关于测试

所有想法和解决方案,都必须经过代码的实践测试,不要相信没有经过测试的代码

我亦无他,惟手熟尔

遇到一个我认为是坑逼的程序员,认为他坑是接手了他写的项目,全是bug和问题,给公司造成损失了。框架工具没有熟练掌握,代码写的很敷衍,大部分代码都是复制粘贴别人项目里的代码。但是他花了十几分钟解决了一个我花了一天时间没有解决的问题,一个php5.5的比较古老商业CMS系统。因此想起了这句话。

作为一名程序员应该放下对”大神”和”大牛”的偏执,以及对”坑逼”的成见。不要以这些词汇来衡量技术水平。技术领域广阔,技术栈繁多,人的能力是有限的,所谓隔行如隔山。技术应该专业和专注,静下心来,专注于业务,问题和代码,放下情绪。能解决你擅长领域的问题的程序员就是好程序员。

开发环境和开发工具整理篇

Database Tools

mysql workbench | navicat 15 激活

PHP

开发环境 oneinstack

Javascript

开发环境 nvm

接口文档工具

showDoc php开发的几口文档管理工具,简介,支持shell脚本通过注释自动生成接口文档

YAPI YAPI是由去哪儿网移动架构组开发的可视化接口管理工具

参考链接 https://juejin.cn/post/6844903874046722055

Swagger

Eolinker

ApiDoc

IDE

vscode 常用插件

物理机安装Linux系统采坑记录

此处物理机指普通的PC电脑和笔记本非服务器

基础知识

boot是可引导bai光盘,iso是国际标du准光盘格式(全世界zhi能读DVD的设备都支持),udf是统一光盘dao格式(Universal Disc Format,全世界能读DVD的设备绝大多数都支持)

通常电脑主板支持两种模式 UEFI和BIOS

UEFI

百科

BIOS

百科

UEFI Bios支持两种启动模式

Legacy+UEFI启动模式和UEFI启动模式,其中Legacy+UEFI启动模指的是UEFI和传统BIOS共存模式,可以兼容传统BIOS引导模式启动操作系统;UEFI启动模式只是在UEFI引导模式启动操作系统。

  选定启动模式并安装操作系统,安装后只能使用设定的模式,用于启动操作系统;
  操作系统安装时使用Legacy+UEFI模式,兼容在传统BIOS引导模式启动操作系统;
  操作系统安装时使用UEFI引导模式,只能在UEFI引导模式启动操作系统。

Legacy+UEFI模式与UEFI模式的区别

    1、Legacy+UEFI启动模式是基于某些电脑硬件设备和操作系统(如WinXP/7)还不支持基于UEFI BIOS的情况,考虑从传统BIOS引导模式启动。传统BIOS引导模式允许Hba,模块设备使用Rom选项。

    2、UEFI启动模式用于操作系统自动从预启动的操作环境,加载到一种操作系统上,从而使开机程序化繁为简,节省时间。并且支持2T以上硬盘,加强对硬件的支持

boot.iso为网络安装版,dvd1为完整安装版

linux刻录

dd bs=4M if=ubuntu-19.10-desktop-amd64.iso of=/dev/sdc status=progress
2463842304字节(2.5 GB)已复制, 587.050253 s, 4.2 MB/s
记录了587+1 的读入
记录了587+1 的写出
2463842304字节(2.5 GB)已复制,587.361 秒,4.2 MB/秒

bs代表字节为单位的块大小 if镜像文件 of输出设备 status=progress 显示进度

刻录centos8时无法启动,iso文件正常是阿里云下载的使用file命令查看包含MBR分区信息,最后发现问题是文件系统问题,用linux刻录linux系统时推荐是ext4文件系统,也可能只有centos8的镜像有这个问题,其它版本和系统没有验证

file CentOS-8.2.2004-x86_64-dvd1.iso

CentOS-8.2.2004-x86_64-dvd1.iso: DOS/MBR boot sector; partition 2 : ID=0xef, start-CHS (0x3ff,254,63), end-CHS (0x3ff,254,63), startsector 23800, 20380 sectors

在dd后,需要把优盘再次格式化为fat32文件系统,参考

出现isolinux.bin missing or corrupt错误

参考

linux下制作u盘启动盘

是因为磁盘目录 of=/dev/sdc 末尾有数字需要去掉

Device     Boot Start       End   Sectors  Size Id Type
/dev/sdd4  *      256 125033618 125033363 59.6G  c W95 FAT32 (LBA)

fdisk -l 显示的磁盘末尾有4 刻录时选择输出路径则为 of=/dev/sdd

windows使用软碟通刻录

启动时汇报启动脚本超时无法发现/dev/root,原因是软碟通会把U盘的标签就是驱动器名称会截断比如centos-8-2-2004-x86_64 截断成centos8-2与启动项的不一致,解决方法百度有很多。个人推荐刻录windows启动盘就用windows支持的文件系统使用windows系统刻录,同理linux就用linux支持的文件系统使用dd刻录

Ubuntu 安装 Mysql-workbench 错误

mysql-workbench
Workbench can't find libproj.so, some options may be unavailable.
/usr/bin/mysql-workbench-bin: symbol lookup error: /usr/lib/mysql-workbench/libwbprivate.so.8.0.16: undefined symbol: 
_ZN7pcrecpp2RE4InitEPKcPKNS_10RE_OptionsE

ubuntu 安装mysql-workbench-comminuty 启动之后报上述错误,

原因是gtk绘图失败,安装所有有关gdk的更新(同理可安装gtk

sudo apt install gtk*

安装之后没有效果,还是失败,最后重装解决。

18.04及后续版本没有出现此问题

Virtual Box (Linux) 安装增强模式

参考

  • https://www.jianshu.com/p/7c556c783bb2
  • https://www.cnblogs.com/mychangee/p/12087954.html

centos

1.点击设备->安装增加功能->下载增加镜像,底部镜像按钮挂载VBoxGuestAddtions.iso 运行

2.运行后报错,没有安装内核,需要安装内核和gcc 并且保持kernel 和kernel-devel版本一致

yum install -y kernel-devel kernel-headers gcc make

yum -y upgrade kernel kernel-devel

reboot

uname -r //查看当前启动的内核版本

rpm -qa | grep kernel-[0-9] //查看全部的内核

yum remove xxxx //删除旧版本内核

或者可以使用下面两个命令中的一个安装和Linux内核版本匹配的kernel-devel

yum install -y "kernel-devel-uname-r == $(uname -r)"

yum install -y kernel-devel-xxxx 

centos 8 报错

https://github.com/geerlingguy/packer-centos-8/issues/4

$ cat /var/log/vboxadd-setup.log
Building the main Guest Additions 6.0.12 module for kernel 4.18.0-80.7.1.el8_0.x86_64.
Error building the module.  Build output follows.
make V=1 CONFIG_MODULE_SIG= -C /lib/modules/4.18.0-80.7.1.el8_0.x86_64/build M=/tmp/vbox.0 SRCROOT=/tmp/vbox.0 -j1 modules
Makefile:958: *** "Cannot generate ORC metadata for CONFIG_UNWINDER_ORC=y, please install libelf-dev, libelf-devel or elfutils-libelf-devel".  Stop.
make: *** [/tmp/vbox.0/Makefile-footer.gmk:111: vboxguest] Error 2
Could not find the X.Org or XFree86 Window System, skipping.
modprobe vboxguest failed
yum(dnf)install -y elfutils-libelf-devel elfutils-libelf-devel.x86_64

sh VBoxLinuxAdditions.run

ubuntu desktop

#先更新
sudo apt update && sudo apt upgrade

安装增加功能

同 centos 设备 >> 安装增强功能

#根据报错信息安装如下包
sudo apt install gcc make perl

共享文件夹

挂载点要设置到登录用户的家目录/home/xxx/dirname 下,会自动创建文件夹,使用chmod和chown 修改权限无效

使用如下命令手动挂载方式,可以更改权限目录

sudo mount -t vboxsf downloads /home/www/share

ubuntu server

PHP为项目配置单独的进程池

配置示例

基于oneinstack安装包生成的配置文件

php-fpm配置文件

位置/usr/local/php/etc/php/php-fpm.conf

;;;;;;;;;;;;;;;;;;;;;
; FPM Configuration ;
;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;
; Global Options ;
;;;;;;;;;;;;;;;;;;

[global]
pid = run/php-fpm.pid
error_log = log/php-fpm.log
log_level = warning

emergency_restart_threshold = 30
emergency_restart_interval = 60s
process_control_timeout = 5s
daemonize = yes

;;;;;;;;;;;;;;;;;;;;
; Pool Definitions ;
;;;;;;;;;;;;;;;;;;;;

include = /usr/local/php/etc/php-fpm.d/*.conf

线程池配置目录

develop.conf

[develop]
//不同的线程池使用不同的sock文件
//nginx配置文件监听对应的sock
listen = /dev/shm/php-cgi.sock 
listen.backlog = -1
listen.allowed_clients = 127.0.0.1
listen.owner = yangliuan
listen.group = yangliuan
listen.mode = 0666
user = yangliuan
group = yangliuan

pm = dynamic
pm.max_children = 6
pm.start_servers = 5
pm.min_spare_servers = 3
pm.max_spare_servers = 6
pm.max_requests = 2048
pm.process_idle_timeout = 10s
request_terminate_timeout = 600
request_slowlog_timeout = 0

pm.status_path = /php-fpm_status
slowlog = var/log/slow.log
rlimit_files = 51200
rlimit_core = 0

catch_workers_output = yes
env[HOSTNAME] = yangliuan-TM1707
env[PATH] = /usr/local/bin:/usr/bin:/bin
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp