您当前的位置: 首页 > 

DS小龙哥

暂无认证

  • 9浏览

    0关注

    679博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

FFmpeg从入门到精通-云享读书会

DS小龙哥 发布时间:2022-09-26 14:09:51 ,浏览量:9

前言

FFmpeg是一款开源软件,用于生成处理多媒体数据的各类库和程序。FFmpeg可以转码、处理视频和图片(调整视频、图片大小,去噪等)、打包、传输及播放视频。作为最受欢迎的视频和图像处理软件,它被来自各行各业的不同公司所广泛使用。

FFmpeg被称作是音视频领域的瑞士军刀,是音视频及相关领域是无人不晓,无人不知的项目, 只要了解多媒体音视频处理的人,都会感叹这个项目的强大。

FFmpeg项目由 Fabrice Bellard在2000年创立,到目前为止,经历了21年的演化。FFmpeg社区和其他多媒体项目互动频繁,这也是它成功的原因之一。在创立之初,有很多开发者同时活跃在Mplayer项目,到目前为止,FFmpeg项目的开发者仍然与VLC、MPV、dav1d、x264等多媒体开源项目有着广泛的重叠。2004年以后,FFmpeg社区基本由Michael Niedermayer领导。

在这近22年的风风雨雨中,FFmpeg一路走来也是经历过不少挫折,在2011年 FFmpeg 就因为核心成员意见不一导致分裂,差点最终导致整个项目消亡殆尽。最终的结果就是,项目创始人法布里斯贝拉选择了离开FFmpeg,但是随后他与其他一起出走的开发者创建另一知名开源编解码库项目Libav。 FFmpeg和 Libav ,就像南慕容和北乔峰一样,是当下所有主流播放器必备的编解码库,并且这些编解码库全部开源可免费使用无需额外付费。不过,虽然说是免费使用,但FFmpeg是基于LGPL/GPL开源的,这意味着如果某软件使用了FFmpeg的代码,那么这个软件涉及这些代码的部分,也必须开源,并且需要在使用其项目源代码和编解码库时注明来源。目前,FFmpeg不仅被大量免费软件使用,同时使用的,还有很多大型公司,例如:YouTube、iTunes、腾讯旗下产品、字节跳动旗下产品等。

当前文章内容来至 华为云 · 云享读书会 第13期 《FFmpeg从入门到精通》读书会直播视频的资料整理,《FFmpeg从入门到精通》的作者是一位典型的音视频技术爱好者,前后就职于广电巨头和音视频互联网公司,具有丰富的音视频直播和点播相关经验,对 WebRTC、FFmpeg 和 Electron 有非常深入的了解。

接下来会陆续按照几个章节由浅入深地介绍FFmpeg处理音视频的常用方法, 对音视频技术感兴趣的小伙伴能从中学到很多干货。

当前文章能学习的知识点:

(1)了解多媒体处理工具FFmpeg工具集

(2)了解音频文件的封装格式、编码格式

(3)了解视频文件的封装格式、编码格式

(4)掌握FFmpeg查看音视频媒体信息的方法

(5)掌握FFmpeg处理音视频文件的常用方法

一、多媒体处理工具 FFmpeg 工具集 (1)FFmpeg的发展

FFmpeg 是一个多媒体开源项目,项目地址:https://github.com/FFmpeg/FFmpeg

FFmpeg 最早是由法国天才程序员法布里斯·贝拉在 2000年时开发的,后来一直快速发展至今,当前最新的版本是 5.0。

目前,FFmpeg 已经被很多开源项目所采用,比如 ijkplayer、VLC、MPlayer、Blender、Google Chrome等。

(2)FFmpeg的组成

FFmpeg 工程内部根据功能划分了不同的模块,包括 AVFormat、AVCodec、AVFilter、AVDevice、AVUtil、swresample、swscale。

image-20220919230123846

(3)FFmpeg的模块介绍

【1】AVFormat 是 FFmpeg 的封装模块,其中实现了目前多媒体领域中的绝大多数媒体 封装格式,包括封装和解封装,比如 MP4、FLV、MKV、TS 等文件封装格式,RTMP、 RTSP、HLS 等网络协议封装格式。另外,也支持自定义封装格式。

【2】AVCodec 是 FFmpeg 的编解码模块,其中实现了目前多媒体领域中的绝大多数媒体 编解码格式,包括编码和解码两大部分,比如 MPEG4、H264、H265 等视频格式,AAC、 MP3 等音频格式。另外,也支持自定义编解码格式。

【3】AVFilter 是 FFmpeg 的滤镜模块,其中实现了目前通用的音频、视频、字幕等滤 镜处理框架。

【4】AVDevice 是 FFmpeg 的设备管理模块,包括音频设备和视频设备。

【5】AVUtil 是 FFmpeg 的工具模块。

【6】swresample 是 FFmpeg 的音频转换模块,包括音频重采样、声道数调整等。

【7】swscale 是 FFmpeg 的视频图像转换模块,包括图像缩放、像素格式转换等。

FFmpeg开发库:

(1)、libavutil是一个包含简化程序功能的库,其中包括随机数生成器,数据结构,数学例程,核心多媒体实用程序等。
(2)、libavcodec是一个库,其中包含音频/视频编解码器的解码器和编码器。
(3)、libavformat是一个包含用于多媒体容器格式的解复用器和复用器的库。
(4)、libavdevice是一个包含输入和输出设备的库,用于从许多常见的多媒体输入/输出软件框架(包Video4Linux,Video4Linux2,VfW和ALSA)中获取和呈现。
(5)、libavfilter是一个包含媒体过滤器的库。
(6)、libswscale是一个执行高度优化的图像缩放和颜色空间/像素格式转换操作的库。
(7)、libswresample是一个执行高度优化的音频重采样,重矩阵化和样本格式转换操作的库。
(4)FFmpeg的工具集

image-20220919233959107

【1】ffmpeg 是 FFmpeg 工具集中的编解码工具。

【2】ffplay 是 FFmpeg 工具集中的播放器。

【3】ffprobe 是 FFmpeg 工具集中的多媒体分析工具。

(5)FFmpeg编译安装(linux)

【1】下载地址

https://ffmpeg.org/download.html

【2】配置FFMPEG

[root@wbyq ffmpeg-3.0.2]#./configure --enable-shared --enable-static --prefix=$PWD/_install --enable-gpl --extra-cflags=-I/home/wbyq/pc_work/x264-snapshot-20160527-2245/_install/include --extra-ldflags=-L/home/wbyq/pc_work/x264-snapshot-20160527-2245/_install/lib --enable-ffserver --enable-ffmpeg --enable-libx264
编译安装:
[root@wbyq ffmpeg-3.0.2]# make
[root@wbyq ffmpeg-3.0.2]# make install

FFMPEG最新版本4.2.2编译配置:
截止编写文档时,FFMPEG最新版本是4.2.2。
 
编译配置方法如下:
[root@wbyq ffmpeg-4.2.2]# ./configure --enable-static --enable-shared --prefix=$PWD/_install --extra-cflags=-I/home/wbyq/pc_work/x264-snapshot-20160527-2245/_install/include --extra-ldflags=-L/home/wbyq/pc_work/x264-snapshot-20160527-2245/_install/lib --enable-ffmpeg --enable-libx264 --enable-gpl
[root@wbyq ffmpeg-4.2.2]#make
[root@wbyq ffmpeg-4.2.2]#make install
二、视频文件的封装格式

FFmpeg 支持很多封装格式,包括 MP4、FLV、MKV、TS 等视频封装格式、MP3、AAC 等音频封装格式以及 RTMP、RTSP、HLS 等网络协议封装格式。 接下来,重点介绍 MP4 视频封装格式。

(1)MP4 封装格式

MP4 封装格式基本上可以认为是日常生活和工作中最常见的视频文件格式,主要是由于其广泛的适用性,不仅在PC端(windows、mac、linux)支持的非常好,而且在移动端(Android、iOS)也能流畅播放。

(2)MP4 格式标准

MP4 格式标准为 ISO-14496 Part 12 和 ISO-14496 Part 14,具体特征如下:

【1】MP4 文件由许多 Box 和 FullBox。

【2】FullBox 是 Box 的扩展,在 Header 中增加了8位version信息和24位的flags信息。

【3】每个 Box 由 Header 和 Data 两部分组成。

【4】Header 中包含了整个 Box 的长度大小(size)和类型(type)。

【5】Data 中包含了实际的数据,可以是纯数据,也可以是子 Box。当 Box 中的 Data 是一系列子Box 时,这个 Box 又被称为 Container(容器)。

image-20220920225417783

(3)MP4 ftyp Box

ftyp Box,一般位于文件开始位置,其中包含了 MP4 视频文件的类型、版本、兼容协议等信息。

image-20220920225501393

(4)MP4 moov容器

moov 容器中包含了 MP4 视频文件的媒体数据信息,内部又包含两个子容器:mvhd和trak,前者定义了文件头信息,后者定义了媒体文件中的track信息。

moov 容器一般默认会生成在 MP4 文件结尾,在线播放时需要加载完整个文件才能正常打开,为了能够快速打开视频,需要把 moov 容器放在 MP4 文件的前面。

image-20220920225535349

(5)MP4 mdat Box

mdat Box,用来存放媒体文件的实际数据内容。

image-20220920225605322

三、视频文件的编码格式

FFmpeg 支持很多视频编码格式,比如:MPEG4、H263、H264、H265、VP8、VP9 等。

接下来,重点介绍 H264 视频编码格式。

(1)H264的码率控制

【1】VBR:Variable BitRate,动态码率模式,其码率可以随着图像的复杂程度的不同 而变化,因此其编码效率比较高。

【2】CBR:Constant BitRate,恒定码率模式,由于码率恒定,有画面剧烈变化时,QP 参数会增大,图像质量会变差,当场景静止时,又浪费带宽。该模式的整体图像质量 不稳定。

【3】ABR:Average BitRate,平均码率模式,是 VBR 的一种衍生形式,在指定的文件 大小内,静态或者接近静态的画面部分使用相对较低的流量,复杂画面部分使用较高 的流量,可以视为是 VBR 和 CBR 的一种折衷方案。

(2)H264 的I帧类型

【1】一个GOP序列的第一个图像叫做 IDR 图像(立即刷新图像),IDR 图像都是 I 帧图像,但I帧不一定都是IDR帧,只有GOP序列的第1个I帧是IDR帧。

【2】I帧,又叫帧内参考帧 ,保留一帧完整的画面。

【3】解码时仅用I帧的数据就可重构出完整的图像。

【4】I帧不需要参考其他画面而生成。

【5】I帧是P帧和B帧的参考帧。

【6】I帧不需要考虑运动矢量。

【7】I帧所占数据的信息量最大。

(3)H264 的B帧类型

【1】B帧,又叫双向参考帧,也就是B帧记录的是本帧与前后帧的差别,要解码B帧,不 仅要取得之前的缓存画面,还要解码之后的画面,通过前后画面的与本帧数据的叠加 取得最终的画面。

【2】B帧的压缩率最高,但是解码时CPU使用率会比较高。

【3】B帧是由前面的I或P帧和后面的P帧来进行预测的。

【4】B帧传送的是它与前面的I或P帧和后面的P帧之间的预测误差及运动矢量。

【5】B帧不是参考帧,不会造成解码错误的扩散。

(4)H264 的P帧类型

【1】P帧,又叫前向参考帧,表示的是这一帧跟之前的一个关键帧(或P帧)的差别,解 码时需要用之前缓存的画面叠加上本帧定义的差别,生成最终画面,P帧没有完整画面 数据,只有与前一帧的画面差异的数据。

【2】P帧是I帧后面相隔1~2帧的编码帧。

【3】P帧采用运动补偿的方法传送它与前面的I或P帧的差值及运动矢量(预测误差)。

【4】P帧属于前向预测的帧间编码。它只参考前面最靠近它的I帧或P帧。

【5】P帧可以是其后面P帧的参考帧,也可以是其前后的B帧的参考帧。

【6】P帧是参考帧,可能会造成解码错误的扩散。

【7】P帧的压缩比介于I帧和B帧之间。

(5)H264 帧参考关系

image-20220920223238630

四、音频文件的封装格式和编码格式 (1)FFmpeg的音频封装格式

MP3 是我们在日常生活中最常见的音频格式之一,也是一种音频封装格式。

日常生活中,我们经常可以看到 *.mp3 的音频文件,就像 mp4、flv 的视频封装格式一样。

MP3 封装格式

使用如下命令查看 ffmpeg 支持的封装格式列表: ffmpeg -formats | grep mp3

image-20220920223427624

使用如下命令播放一个 mp3 音乐文件:

普通模式: ffplay 少年.mp3

波形图模式:ffplay -showmode 1 少年.mp3

频谱图模式:ffplay -showmode 2 少年.mp3

image-20220921212208392

image-20220921212303124

(2)FFmpeg的音频编码格式

FFmpeg 支持很多编码格式,包括 MP3、AAC、AC3 等。

接下来,重点介绍 MP3 音频编码格式。

MP3 编码格式

MP3 也是一种音频编码格式。

和视频不同,视频编码格式,比如 H264,一般会封装 MP4 或者 FLV 这种封装格式中被使用。音频编码格MP3,则是封装在同名的 MP3 的封装格式中。二者容易混淆,注意区分。

MP3 编码格式

使用如下命令查看ffmpeg支持的编码格式列表:

image-20220920223905827

MP3 文件结构

image-20220920223954979

MP3 文件结构

image-20220920224017983

五、FFmpeg 查看媒体信息和处理音视频文件的常用方法 (1)FFmpeg的工程化方案

音频文件和视频文件的转码处理一般称为多媒体处理,华为云也有相应的媒体处理服务——Media Processing Center,简称 MPC,是一种多媒体数据处理服务,基于华为云云计算服务构建,解决客户自建音视频处理能力不可避免的投入成本高昂、技术门槛高等问题,帮助客户专注于业务能力构建,快速交付上线。

【1】视频处理

image-20220920224329982

【2】音频处理

image-20220920224354962

(2)FFmpeg视频转码

采用 FFmpeg 对音视频处理,主要是转码、视频参数、音频参数三部分内容。

传统的转码程序工作原理如下图所示:

image-20220921215912379

【1】音视频转码示例:

1. 音频转码
ffmpeg -i 少年.mp3 -acodec aac -ab 3000 -ac 1 -ar 8000 output.aac

2. 视频转码
ffmpeg -i big_buck_bunny.mp4 -vcodec h263 -b:v 256000 -r 15 -s 352x288 -acodec copy
output.ts

【2】最简单的方式转码

ffmpeg -i 123.mp4 out.flv

【3】任意格式转为MP4

转码视频格式并设置音频采样率和输出视频尺寸: mpg-->mp4
C:\FFMPEG\ffmpeg_x86_4.2.2\bin\ffmpeg.exe -i 1.mpg -y -qscale 0 -vcodec libx264 -acodec aac -ac 1 -ar 22050 -s 300*300  1_1.mp4
 
 
转码视频格式并设置音频采样率和输出视频尺寸(软解可以播放-硬解无法播放): wmv-->wmv
C:\FFMPEG\ffmpeg_x86_4.2.2\bin\ffmpeg.exe -i 2.wmv -y -qscale 0 -vcodec libx264 -acodec aac -ac 1 -ar 48000 -s 300*300  2_1.wmv
 
 
转码视频格式并设置音频采样率和输出视频尺寸: wmv-->mp4
C:\FFMPEG\ffmpeg_x86_4.2.2\bin\ffmpeg.exe -i 2.wmv -y -qscale 0 -vcodec libx264 -acodec aac -ac 1 -ar 48000 -s 300*300  2_1.mp4
 
 
转码视频格式并设置音频采样率: wmv-->mp4
C:\FFMPEG\ffmpeg_x86_4.2.2\bin\ffmpeg.exe -i 2.wmv -y -qscale 0 -vcodec libx264 -acodec aac -ac 1 -ar 48000 2_1.mp4
 
 
转码视频格式并设置音频采样率: wmv-->mp4
C:\FFMPEG\ffmpeg_x86_4.2.2\bin\ffmpeg.exe -i Video_2020-10-11_2.wmv -y -qscale 0 -vcodec libx264 -acodec aac -ac 1 -ar 22050 Video_2020-10-11_2_1.mp4
 
 
转码视频格式并设置音频采样率和输出视频尺寸、修改码率: mpg-->mp4
C:\FFMPEG\ffmpeg_x86_4.2.2\bin\ffmpeg.exe -i 1.mpg -y -qscale 0 -vcodec libx264 -acodec aac -ac 1 -ar 22050 -b:v 400k -s 300*300  1_1.mp4
(3)音视频合并

【1】视频拼接

这种方式需要保证所有的视频的格式、音频码率一样,不然无法正常合并。

C:\FFMPEG\ffmpeg_x86_4.2.2\bin\ffmpeg.exe  -f concat -safe 0 -i filelist.txt -c copy demo.mp4
 
filelist.txt文件内容---里面的视频路径使用相对路径:
file 'd8381671f616468c9193defcd55eeb3b.mp4'
file 'ad6beef4b9e14bcf8f4c07d802cae360.mp4'
file '1d15bf4c221c4e429413568d5c2e58e4.mp4'
 
转码视频格式并设置音频采样率和输出视频尺寸、设置输出帧率: 
C:\FFMPEG\ffmpeg_x86_4.2.2\bin\ffmpeg.exe -i 1.mp4 -y -qscale 0 -vcodec libx264 -acodec aac -ac 1 -ar 22050 -s 300*300 -r 30 -aspect 1_1.mp4

【2】不同分辨率的源视频合成一个视频,设置画面的中心位置

C:\FFMPEG\ffmpeg_x86_4.2.2\bin\ffmpeg.exe -i 1.mp4 -i 1.mpg -i 123.mp4 -f lavfi -i color=black -filter_complex "[0:v]format=pix_fmts=yuva420p,rotate=PI*0/180:c=none:ow=rotw(PI*0/180):oh=roth(PI*0/180),pad=1920:1080:(ow-iw)/2:(oh-ih)/2:black,setpts=PTS-STARTPTS+0/TB[va0];[1:v]format=pix_fmts=yuva420p,rotate=PI*0/180:c=none:ow=rotw(PI*0/180):oh=roth(PI*0/180),pad=1920:1080:(ow-iw)/2:(oh-ih)/2:black,setpts=PTS-STARTPTS+3/TB[va1];[2:v]format=pix_fmts=yuva420p,rotate=PI*0/180:c=none:ow=rotw(PI*0/180):oh=roth(PI*0/180),pad=1920:1080:(ow-iw)/2:(oh-ih)/2:black,setpts=PTS-STARTPTS+7/TB[va2];[3:v]scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2:black,trim=duration=12[over0];[over0][va0]overlay[over1];[over1][va1]overlay[over2];[over2][va2]overlay=format=yuv420[outv];[0:a][1:a][2:a] concat=n=3:v=0:a=1[outa]" -aspect 1920:1080 -vcodec libx264 -map "[outv]" -map "[outa]" -y out.mp4

【3】音频混合合成

ffmpeg -i 1.mp3 -i 2.mp3 -filter_complex amix=inputs=2:duration=first:dropout_transition=2 -f mp3 remix.mp3
    
参数说明:
-i 文件 1.mp3 和 2.mp3 为待合成的两个源文件;
-filter_complex 过滤器参数;
amix=inputs 配置输入的整体样本数;
duration,first:长度取决于第一个文件,longest:长度取决于时间最长文件,shortest:长度取决于时间最短文件;
dropout_transition:输入流结束时用于体积重新规范化的过渡时间;
-f mp3 设置导出文件格式;

【4】音频连接合成

ffmpeg -i "concat:headerNew.mp3|006.mp3" -acodec copy demo6.mp3
    
参数说明:
concat 合并文件指令;

【5】音频淡出效果

ffmpeg -i bgm3.mp3  -filter_complex afade=t=out:st=16:d=4 bgm31.mp3

参数说明:
afade 淡入淡出指令;
从 st 秒开始,经过 d 秒钟的淡出效果;

【6】使用 FFmpeg concat 过滤器重新编码(有损)

语法有点复杂,但是其实不难。这个方法可以合并不同编码器的视频片段,也可以作为其他方法失效的后备措施。

ffmpeg -i input1.mp4 -i input2.webm -i input3.avi -filter_complex '[0:0] [0:1] [1:0] [1:1] [2:0] [2:1] concat=n=3:v=1:a=1 [v] [a]' -map '[v]' -map '[a]'  output.mkv

上面的命令合并了三种不同格式的文件,FFmpeg concat 过滤器会重新编码它们。注意这是有损压缩。

[0:0] [0:1] [1:0] [1:1] [2:0] [2:1] 分别表示第一个输入文件的视频、音频、第二个输入文件的视频、音频、第三个输入文件的视频、音频。concat=n=3:v=1:a=1 表示有三个输入文件,输出一条视频流和一条音频流。[v] [a] 就是得到的视频流和音频流的名字,注意在 bash 等 shell 中需要用引号,防止通配符扩展。

【7】使用amix合并两种声音

ffmpeg -i g001_2.wav -i tx.wav -filter_complex amix=inputs=2:duration=longest:dropout_transition=2 tx_new.wav
(4)视频倒放
//视频倒放,无音频
C:\FFMPEG\ffmpeg_x86_4.2.2\bin\ffmpeg.exe -i 123.mp4 -filter_complex [0:v]reverse[v] -map [v] -preset superfast out.mp4
//视频倒放,音频不变
C:\FFMPEG\ffmpeg_x86_4.2.2\bin\ffmpeg.exe -i 123.mp4 -vf reverse out.mp4
//音频倒放,视频不变
C:\FFMPEG\ffmpeg_x86_4.2.2\bin\ffmpeg.exe -i 123.mp4 -map 0 -c:v copy -af "areverse" out.mp4
//音视频同时倒放
C:\FFMPEG\ffmpeg_x86_4.2.2\bin\ffmpeg.exe -i 123.mp4 -vf reverse -af areverse -preset superfast out.mp4
(5)视频转GIF
1. 最简单的方式
ffmpeg -i 123.mp4 out.gif
    
2.将视频 MP4 转化为 GIF
ffmpeg -i OUTPUT_VIDEO.mp4 OUTPUT_VIDEO.gif

3.将视频中的一部分转换为GIF
// 从视频中第二秒开始,截取时长为3秒的片段转化为 gif
ffmpeg -t 3 -ss 00:00:02 -i small.mp4 small-clip.gif


4.转化高质量 GIF
ffmpeg -i  OUTPUT_VIDEO.mp4 -b 2048k OUTPUT_VIDEO.gif

5.将 GIF 转化为 MP4

ffmpeg -f gif -i animation.gif animation.mp4
ffmpeg -f gif -i animation.gif animation.mpeg
ffmpeg -f gif -i animation.gif animation.webm

6. 设置时间
通常我们只需要转换视频的某一个时间片段,所以不能像上图中的命令那样直接转换,需要使用-ss(设置起始时间),-t(设置持续时间)。

ffmpeg -ss 起始时间 -t 持续时间 -i 输入文件 输出文件

比如:ffmpeg -ss 9 -t 5 -i 1.mp4 1.gif,将会从视频的9秒开始截取5秒片段转换为gif图片。-ss也可以设置为00:00:00.000的形式,为小时、分钟、秒、毫秒,例如00:00:09.000。

7. 设置循环次数

-loop 循环次数,比如设置-loop 1,生成的gif图片将只会播放一次,0为无限次(默认)。

ffmpeg -ss 起始时间 -t 持续时间 -i 输入文件 -loop 循环次数 输出文件

比如ffmpeg -ss 9 -t 5 -i 1.mp4 -loop 0 1.gif。

8. 设置缩放

如果是高分辨率视频,可能需要将画面缩放,不然gif图片就太大了,可以使用scale控制。比如scale=iw/2:-1:flags=lanczos(lanczos为缩放算法),将会设置gif图片的宽度为源视频一半,高度为比例缩放,也可以强制设置宽高像素。

ffmpeg -ss 起始时间 -t 持续时间 -i 输入文件 -loop 循环次数 -vf scale=宽:高:flags=lanczos 输出文件

例如ffmpeg -ss 9 -t 5 -i 1.mp4 -loop 0 -vf scale=iw/2:-1:flags=lanczos 1.gif。

9. 设置fps(每秒帧数)
设置低一些的fps可以压缩gif的体积,使用fps=指定的fps数值,保持流畅即可。
ffmpeg -ss 起始时间 -t 持续时间 -i 输入文件 -loop 循环次数 -vf "scale=宽:高:flags=lanczos,fps=数值" 输出文件

例如ffmpeg -ss 9 -t 5 -i 1.mp4 -loop 0 -vf "scale=iw/2:-1:flags=lanczos,fps=15" 1.gif

10. 裁剪画面

可能我们只需要将视频画面的一部分转成gif图片,可以使用crop,具体为crop=宽度:高度:宽度起始:高度起始,比如crop=200:200:0:0,将会从横向0像素,纵向0像素开始,从画面裁剪200x200的区域。

ffmpeg -ss 起始时间 -t 持续时间 -i 输入文件 -loop 循环次数 -vf "scale=宽:高:flags=lanczos,fps=数值,crop=宽度:高度:宽度起始:高度起始" 输出文件

例如: ffmpeg -ss 9 -t 5 -i 1.mp4 -loop 0 -vf "scale=iw/2:-1:flags=lanczos,fps=15,crop=iw/2:ih:0:0" 1.gif,将裁剪视频的左半边画面。

11. 提高gif画面质量

你可能发现通过上面的方法直接生成的gif图片质量不怎么好,可以使用split和palette过滤器进行改善。

ffmpeg -ss 起始时间 -t 持续时间 -i 输入文件 -loop 循环次数 -vf "scale=宽:高:flags=lanczos,fps=数值,crop=宽度:高度:宽度起始:高度起始,split[s1][s2];[s1]palettegen[p];[s2][p]paletteuse" 输出文件

如ffmpeg -ss 9 -t 5 -i 1.mp4 -loop 0 -vf "scale=iw/2:-1:flags=lanczos,fps=15,crop=iw/2:ih:0:0,split[s1][s2];[s1]palettegen[p];[s2][p]paletteuse" 1.gif。

上面的参数和过滤器可根据自己的需要自由选择及设置。
(6)给视频添加图片水印

【1】添加图片水印

//添加图片水印
C:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -i D:/666.mp4 -vf "movie=image/123.png[wm];[in][wm]overlay=30:10[out]" D:/linux-share-dir/video_file/test/output.mp4
 
参数解析:
1. D:/666.mp4 输入的视频
2. image/123.png 要添加进去的图片水印
3. D:/linux-share-dir/video_file/test/output.mp4 合成水印之后输出的视频

image-20220921214306682

image-20220921214318441

【2】在视频左下角添加GIF动态水印

ffmpeg -y -i test2.mp4 -i gnore_loop 0 -i test.gif  -filter_complex overlay=0:H-h test_out2.mp4

【3】水印显示时间变化

1. 设置水印显示时长
ffmpeg -hide_banner -i big_buck_bunny.mp4 -i doggie2.png -filter_complex "overlay=enable=\'lte(t,5)\'" out.mp4 -y
上面命令作用是:让水印只显示5秒,5秒后消失。

2. 设置水印显示时间段
ffmpeg -hide_banner -i big_buck_bunny.mp4 -i doggie2.png -filter_complex "overlay=enable=\'between(t,5,10)\'" out.mp4 -y
上面的命令作用是:让水印在视频的5~10秒时间段内显示

3. 设置两个水印轮番出现
ffmpeg -i big_buck_bunny.mp4 -i doggie1.png -i doggie2.png -filter_complex "overlay=enable=\'lte(mod(t,10),4)\',overlay=enable=\'gt(mod(t,10),6)\'" out.mp4 -y
上面的命令作用是:第一个水印显示4秒后消失,2秒后第二个水印显示4秒后消失。
这里布置个作业?huaji 请让两个水印一个在左上角,一个在右上角

【4】水印位置变化

设置水印随时间向右移动
ffmpeg -i big_buck_bunny.mp4 -ignore_loop 0 -i doggie3.gif -lavfi "overlay=x=t*20" -shortest out.mp4 -y
上面命令的作用是:让水印每秒向右移动20像素,直到消失。

设置水印每隔10秒钟从左移动右直至消失
 ffmpeg -i big_buck_bunny.mp4 -ignore_loop 0 -i doggie3.gif -lavfi "overlay=enable=\'mod(t,10)\':x=\'100*mod(t,10)-w\'" -shortest out.mp4 -y

【5】GIF水印循环播放方式

第一种:设置gif的-ignore_loop为0,让gif保持循环播放即可,命令如下:
ffmpeg -hide_banner -i big_buck_bunny.mp4 -ignore_loop 0 -i doggie3.gif -filter_complex  overlay -shortest out.mp4 -y
但是这种方式,只适用于gif格式的图像,如果滤镜是一小段视频就无能为力了。

第二种:使用movie滤镜,同样是让gif循环播放,虽然这种方式复杂点,不过这种解决方案支持视频水印,命令如下:
ffmpeg -hide_banner -i big_buck_bunny.mp4 -vf "movie=doggie3.gif:loop=0,setpts=N/FRAME_RATE/TB[out];[0:v][out]overlay=x=main_w-overlay_w:y=0" -shortest out.mp4 -y
上面的命令有两个地方比较关键:

loop=0,setpts=N/FRAME_RATE/TB :设置水印gif无限循环
-shortest :将输出文件的时长设置为第一个视频文件的时长,如果不设置,你会发现命令会一直执行根本不会停下来,因为gif图的循环是无限的
这样gif图/短视频就会一直不停的播放了。


希望水印播放一次就不播放了,那就设置上面的eof_action为pass就可以了,如下:
ffmpeg -hide_banner -i big_buck_bunny.mp4 -i doggie3.gif -filter_complex "overlay=x=0:y=0:eof_action=pass" out.mp4 -y

如果视频一开始就播放且只播放一次,假如水印比较短可能根本就没被注意就过去了,这时可以设置水印出现的延迟时间,使用-itsoffset选项,如下:
ffmpeg -hide_banner -i big_buck_bunny.mp4 -itsoffset 3 -i doggie3.gif -filter_complex "overlay=x=0:y=0:eof_action=pass" out.mp4 -y
这样,视频播放3秒后,水印才会出现。

【6】水印旋转

如果想实现旋转的功能,需要使用ffmpeg过滤器的链式功能,即:先把作为水印的图片旋转,再覆盖到视频上。

1. 水印旋转一次
ffmpeg -i buck.mp4 -i s1.jpg -lavfi "[1:v]format=rgba,rotate='PI/6:c=0x00000000:ow=hypot(iw,ih):oh=ow'[out];[0:v][out]overlay=10:10" out.mp4 -y

思路是:
调整水印宽高,根据勾股定律计算图片对角长度(hypot),将这个值设置为水印的宽高,这样,图片无论如何旋转,都不会超过设定的宽高,也就不会出现图片部分丢失的情况了
将图片显示的像素格式转换为rgba格式,如果做过前端的小伙伴会很熟悉的,最后的a表示透明度,如此一来,c=0x00000000的作用就是将图片旋转后的背景变为白色且完全透明,这样就不会遮挡视频了

2. 让旋转停不下,具体命令如下:
ffmpeg -i buck.mp4 -loop 1 -i s1.jpg -lavfi "[1:v]format=rgba,rotate='PI/2*t:c=0x00000000:ow=hypot(iw,ih):oh=ow'[out];[0:v][out]overlay=10:10" -shortest out.mp4 -y
这次水印图片前面添加了-loop 1,正常情况下水印图片默认在播放一次后就停下来,保留最后一帧,所以要让水印图片保持循环才行。
(7)使用ffprobe获取媒体信息

【1】输出媒体信息

PS D:\> ffprobe -i .\jiyi.mp4
ffprobe version 4.2.2 Copyright (c) 2007-2019 the FFmpeg developers
  built with gcc 9.2.1 (GCC) 20200122
  configuration: --disable-static --enable-shared --enable-gpl --enable-version3 --enable-sdl2 --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libdav1d --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvorbis --enable-libvo-amrwbenc --enable-libmysofa --enable-libspeex --enable-libxvid --enable-libaom --enable-libmfx --enable-amf --enable-ffnvcodec --enable-cuvid --enable-d3d11va --enable-nvenc --enable-nvdec --enable-dxva2 --enable-avisynth --enable-libopenmpt
  libavutil      56. 31.100 / 56. 31.100
  libavcodec     58. 54.100 / 58. 54.100
  libavformat    58. 29.100 / 58. 29.100
  libavdevice    58.  8.100 / 58.  8.100
  libavfilter     7. 57.100 /  7. 57.100
  libswscale      5.  5.100 /  5.  5.100
  libswresample   3.  5.100 /  3.  5.100
  libpostproc    55.  5.100 / 55.  5.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '.\jiyi.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf58.29.100
  Duration: 00:00:54.15, start: 0.000000, bitrate: 574 kb/s
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709), 960x544, 518 kb/s, 29.97 fps, 29.97 tbr, 19200 tbn, 38400 tbc (default)
    Metadata:
      handler_name    : Core Media Video
    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, mono, fltp, 47 kb/s (default)
    Metadata:
      handler_name    : Core Media Audio
PS D:\>

【2】输出媒体信息

PS D:\> ffprobe -v quiet -of json -i .\jiyi.mp4  -show_streams

{
    "streams": [
        {
            "index": 0,
            "codec_name": "h264",
            "codec_long_name": "H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10",
            "profile": "High",
            "codec_type": "video",
            "codec_time_base": "8123/486900",
            "codec_tag_string": "avc1",
            "codec_tag": "0x31637661",
            "width": 960,
            "height": 544,
            "coded_width": 960,
            "coded_height": 544,
            "has_b_frames": 1,
            "pix_fmt": "yuv420p",
            "level": 31,
            "color_range": "tv",
            "color_space": "bt709",
            "color_transfer": "bt709",
            "color_primaries": "bt709",
            "chroma_location": "left",
            "refs": 1,
            "is_avc": "true",
            "nal_length_size": "4",
            "r_frame_rate": "30000/1001",
            "avg_frame_rate": "243450/8123",
            "time_base": "1/19200",
            "start_pts": 0,
            "start_time": "0.000000",
            "duration_ts": 1039744,
            "duration": "54.153333",
            "bit_rate": "518796",
            "bits_per_raw_sample": "8",
            "nb_frames": "1623",
            "disposition": {
                "default": 1,
                "dub": 0,
                "original": 0,
                "comment": 0,
                "lyrics": 0,
                "karaoke": 0,
                "forced": 0,
                "hearing_impaired": 0,
                "visual_impaired": 0,
                "clean_effects": 0,
                "attached_pic": 0,
                "timed_thumbnails": 0
            },
            "tags": {
                "language": "und",
                "handler_name": "Core Media Video"
            }
        },
        {
            "index": 1,
            "codec_name": "aac",
            "codec_long_name": "AAC (Advanced Audio Coding)",
            "profile": "LC",
            "codec_type": "audio",
            "codec_time_base": "1/44100",
            "codec_tag_string": "mp4a",
            "codec_tag": "0x6134706d",
            "sample_fmt": "fltp",
            "sample_rate": "44100",
            "channels": 1,
            "channel_layout": "mono",
            "bits_per_sample": 0,
            "r_frame_rate": "0/0",
            "avg_frame_rate": "0/0",
            "time_base": "1/44100",
            "start_pts": 0,
            "start_time": "0.000000",
            "duration_ts": 2387471,
            "duration": "54.137664",
            "bit_rate": "47025",
            "max_bit_rate": "47025",
            "nb_frames": "2332",
            "disposition": {
                "default": 1,
                "dub": 0,
                "original": 0,
                "comment": 0,
                "lyrics": 0,
                "karaoke": 0,
                "forced": 0,
                "hearing_impaired": 0,
                "visual_impaired": 0,
                "clean_effects": 0,
                "attached_pic": 0,
                "timed_thumbnails": 0
            },
            "tags": {
                "language": "und",
                "handler_name": "Core Media Audio"
            }
        }
    ]
}
(8)采集桌面屏幕、摄像头保存为视频

【1】 列出当前电脑上音频设备、摄像头设备列表

C:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -list_devices true -f dshow -i dummy

【2】录制桌面全屏图像+音频

C:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -f gdigrab -i desktop -f dshow -i audio="@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{6E399CBA-5F7D-443F-9071-1657DE0F5483}" -vcodec libx264 -acodec libmp3lame -s 1280x720 -r 15 D:/linux-share-dir/video_file/6666.mp4
 
其中: 
audio= "" 这里填麦克风设备. 第一条指令就是查询电脑上音频设备。把名字复制过来即可。

【3】录制摄像头+音频

示例1:
C:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -f dshow -i video="@device_pnp_\\?\usb#vid_5986&pid_2113&mi_00#6&3326332&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global" -f dshow -i audio="@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{6E399CBA-5F7D-443F-9071-1657DE0F5483}" -vcodec libx264 -acodec libmp3lame -s 1280x720 -r 15 D:/linux-share-dir/video_file/6666.mp4
 
 
其中:
video="" 视频摄像头设备名称
audio="" 视频音频设备名称
 
 
示例2:
C:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -f dshow -i video="@device_pnp_\\?\usb#vid_5986&pid_2113&mi_00#6&3326332&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global" -f dshow -i audio="@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{6E399CBA-5F7D-443F-9071-1657DE0F5483}" D:/linux-share-dir/video_file/test/202108161456.mp4

【4】 采集桌面指定区域(无音频)

C:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -f gdigrab -framerate 6 -offset_x 50 -offset_y 50 -video_size 400x400 -i desktop D:/linux-share-dir/video_file/test/202108161448.mp4

img

【5】采集桌面指定区域+音频

//录制指定范围--采集图像+音频
C:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -f gdigrab -framerate 6 -offset_x 50 -offset_y 50 -video_size 400x400 -i desktop -f dshow -i audio="@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{6E399CBA-5F7D-443F-9071-1657DE0F5483}" D:/linux-share-dir/video_file/test/202108161514.mp4

【6】案例

列出设备列表
ffmpeg -list_devices true -f dshow -i dummy

全屏录像 ( dshow录屏, H264编码 )
ffmpeg -f dshow -i video="screen-capture-recorder" -f dshow -i audio="virtual-audio-capturer" -vcodec libx264 -acodec libmp3lame -s 1280x720 -r 15 e:/temp/temp.mkv

全屏录像 ( gdigrab录屏, H264编码 )
ffmpeg -f gdigrab -i desktop -f dshow -i audio="virtual-audio-capturer" -vcodec libx264 -acodec libmp3lame -s 1280x720 -r 15 e:/temp/temp.mkv

全屏录像 ( gdigrab录屏, vp9编码 )( 注 : dshow不支持vp9 )
ffmpeg -f gdigrab -i desktop -f dshow -i audio="virtual-audio-capturer" -vcodec libvpx-vp9 -acodec libmp3lame -s 1280x720 -r 15 e:/temp/temp.mkv

区域录像 ( 起点:100,60 width:600 width:480 )
ffmpeg -f gdigrab -i desktop -f dshow -i audio="virtual-audio-capturer" -vcodec libx264 -acodec libmp3lame -video_size 600x480 -offset_x 100 -offset_y 60 -r 15 e:/temp/temp.mkvC:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -f dshow  -i video="screen-capture-recorder"  screen-capture.mp4




window (安装dshow)
ffmpeg -rtbufsize 100M -f dshow -i video="screen-capture-recorder":audio="virtual-audio-capturer" -vcodec libx264  -preset veryfast -crf 22 -tune:v zerolatency  -pix_fmt yuv420p  -s  '+size+r'  -acodec libmp3lame  -t  ' + str(times) + '  ' + filename



列出当前电脑上音频设备、摄像头设备列表
C:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -list_devices true -f dshow -i dummy

//录制全屏
C:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -f gdigrab -i desktop -f dshow -i audio="@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{6E399CBA-5F7D-443F-9071-1657DE0F5483}" -vcodec libx264 -acodec libmp3lame -s 1280x720 -r 15 D:/linux-share-dir/video_file/6666.mp4
    
    
C:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -f dshow  -i video="screen-capture-recorder"  screen-capture.mp4




window (安装dshow)
ffmpeg -rtbufsize 100M -f dshow -i video="screen-capture-recorder":audio="virtual-audio-capturer" -vcodec libx264  -preset veryfast -crf 22 -tune:v zerolatency  -pix_fmt yuv420p  -s  '+size+r'  -acodec libmp3lame  -t  ' + str(times) + '  ' + filename



列出当前电脑上音频设备、摄像头设备列表
C:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -list_devices true -f dshow -i dummy

//录制全屏
C:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -f gdigrab -i desktop -f dshow -i audio="@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{6E399CBA-5F7D-443F-9071-1657DE0F5483}" -vcodec libx264 -acodec libmp3lame -s 1280x720 -r 15 D:/linux-share-dir/video_file/6666.mp4
    
    
这是OK的--录制全屏无音频
C:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -f gdigrab -framerate 10 -i desktop D:/linux-share-dir/video_file/test/666.mp4


这是OK的---但是捕获的位置有问题
C:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -f dshow  -i video="screen-capture-recorder" -crf 22 -r 10 D:/linux-share-dir/video_file/test/666.mp4



C:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -f gdigrab -i desktop -f dshow -i audio="@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{6E399CBA-5F7D-443F-9071-1657DE0F5483}" -vcodec libx264 -acodec aac -s 1280x720 -r 10 D:/linux-share-dir/video_file/6666.mp4
 
其中: 
audio= "" 这里填麦克风设备. 第一条指令就是查询电脑上音频设备。把名字复制过来即可。


C:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -f gdigrab -i desktop -f dshow -i audio="麦克风阵列 (Conexant SmartAudio HD)" -vcodec libx264 -acodec aac -s 1280x720 -r 10 D:/linux-share-dir/video_file/test/6666.mp4


C:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -f gdigrab -i desktop -f dshow -i audio="麦克风阵列 (Conexant SmartAudio HD)" -vcodec libx264 -acodec aac -video_size 100x100 -offset_x 500 -offset_y 500 -r 10 D:/linux-share-dir/video_file/6666.mp4
    
    
    //采集摄像头 
C:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -f dshow -i video="Integrated Camera" -f dshow -i audio="virtual-audio-capturer" D:/linux-share-dir/video_file/test/202108161421.mp4


//采集摄像头和电脑音频. 这是OK的
C:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -f dshow -i video="Integrated Camera" -f dshow -i audio="@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{6E399CBA-5F7D-443F-9071-1657DE0F5483}" D:/linux-share-dir/video_file/test/202108161443.mp4



//录制指定范围--采集图像--这是OK的
C:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -f gdigrab -framerate 6 -offset_x 50 -offset_y 50 -video_size 400x400 -i desktop D:/linux-share-dir/video_file/test/202108161448.mp4


//采集摄像头和电脑音频. 这是OK的
C:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -f dshow -i video="@device_pnp_\\?\usb#vid_5986&pid_2113&mi_00#6&3326332&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global" -f dshow -i audio="@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{6E399CBA-5F7D-443F-9071-1657DE0F5483}" D:/linux-share-dir/video_file/test/202108161456.mp4


//录制指定范围--采集图像+音频
C:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -f gdigrab -framerate 6 -offset_x 50 -offset_y 50 -video_size 400x400 -i desktop -f dshow -i audio="@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{6E399CBA-5F7D-443F-9071-1657DE0F5483}" D:/linux-share-dir/video_file/test/202108161514.mp4


fmpeg.exe -f dshow -i video=\"@device:pnp:\\\\?\\usb#vid_5986&pid_2113&mi_00#6&3326332&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\\global\" -f dshow -i audio=\"麦克风阵列 (Conexant SmartAudio HD)\" C:/Users/11266/Videos/2021-8-16-16-35-44-426.mp4\n"
(9)视频音频替换

【1】去掉视频原声再添加新的音频

(1)去掉视频原声:
C:\FFMPEG\ffmpeg_x86_4.2.2\bin>ffmpeg.exe -i 123.mp4 -c:v copy -an out1.mp4
 
(2)合并音频到视频:
C:\FFMPEG\ffmpeg_x86_4.2.2\bin>ffmpeg.exe -i out1.mp4 -i 花僮-笑纳.mp3 out2.mp4
 
可以指定合成时间:
C:\FFMPEG\ffmpeg_x86_4.2.2\bin>ffmpeg.exe -i out1.mp4 -i 花僮-笑纳.mp3 -t 30 out3.mp4
其中-t参数是指定时间.单位是秒.

【2】保留视频原生添加新的音频

ffmpeg -i 花僮-笑纳.mp3 -i 123.mp4 -filter_complex amix=inputs=2 output.mp4

【3】替换原来影片的音讯

ffmpeg -i tx_new.wav -i r001_2.flv -shortest -c copy n001_2.flv
(10)给视频添加文字水印

【1】在图片的左上角(横坐标10.纵坐标100)添加水印:

wbyq@wbyq:/mnt/hgfs/linux-share-dir$ ffmpeg -i 123.mp4 -vf "drawtext=fontfile=simhei.ttf: text=‘DS小龙哥’:x=100:y=10:fontsize=24:fontcolor=white:shadowy=2" output.mp4
 
参数说明
fontfile:字体类型  --simhei.ttf如果没有找到,可以在windows下的Fonts目录下拷贝过来,放到程序执行目录下-
text:要添加的文字内容
fontsize:字体大小
fontcolor:字体颜色

image-20220921215457628

【2】常见案例

水印位置:(x,y)=(10,10)            
关注
打赏
1664009229
查看更多评论
0.0516s