背景
事情是这样的......前两天突然接到 leader 给的一个任务:给视频加上图片 logo
水印。我这种剪映老司机当然迷之一笑了哈哈哈哈哈,沉浸在简单的任务中还没反应过来巴掌就如洪水般涌来,因为 leader 给了几十个视频......作为一个计算机人,当然要搞脚本了!!!于是便有了今天的这篇博客。
ffmpeg
什么是 ffmpeg
FFmpeg is a free and open-source software project consisting of a suite of libraries and programs for handling video, audio, and other multimedia files and streams. Its core is the command-line ffmpeg tool itself, designed for processing video and audio files. @https://en.wikipedia.org/wiki/FFmpeg
说白了 ffmpeg
就是一套用于处理视频、音频的工具。
为什么要使用 ffmpeg
ffmpeg
是许多多媒体库和工具(例如 Python
的 moviepy
、opencv
)的核心组件,用于处理底层音视频操作。对于程序员来说,它可以通过代码实现复杂的多媒体处理功能,非常高效。
ffmpeg 官网
既然是很大的开源软件,那一定有自己的官网:https://www.ffmpeg.org/
MacOS 安装 ffmpeg
直接在mac
的 Terminal
中按照如下步骤安装:
- Step1:使用
Homebrew
安装ffmpeg
bash
brew install ffmpeg
- Step 2: 验证安装
bash
ffmpeg -version
使用 ffmpeg 给视频加图片水印
在要加水印的视频所在文件夹打开 Terminal
,输入以下指令即可:
bash
ffmpeg -i input.mp4 -i watermark.png -filter_complex "[1:v]scale=iw*0.5:-1[wm];[wm]format=rgba,colorchannelmixer=aa=1[wm_alpha];[0:v][wm_alpha]overlay=15:-50" -c:v libx264 -preset slow -crf 18 -c:a copy output.mp4
各项参数含义如下:
-i
指定输入文件。两个-i
一个输入要加水印的视频,一个指定水印图片-filter_complex
用于定义复杂的过滤器链,包含多个处理步骤[1:v]scale=iw*0.5:-1[vm]
[1:v]
表示使用第二个输入watermark.png
的视频流
scale=iw*0.5:-1
表示将水印图片的宽度(iw
即input width
)缩小到原始宽度的50%,高度自动按比例调整(-1
表示自动保持宽高比)
[wm]
定义了一个临时名称,表示缩放后的水印输出。[wm]format=rgba,colorchannelmixer=aa=1[wm_alpha]
[wm]
接收上一步生成的水印
format = rgba
确保水印的格式是RGBA
支持透明通道 (不支持透明通道的图片格式为RGB
)
colorchannelmixer=aa=1
调整水印的透明度,aa=1
表示设置水印完全不透明
[wm_alpha]
定义一个临时名称,表示处理后的水印输出[0:v][wm_alpha]overlay=15:-50
[0:v]
使用第一个输入input.mp4
的视频流
[wm_alpha]
使用刚刚处理后的水印
overlay = 15:-50
将水印图片叠加到视频上时,overlay
用于确定位置,15
表示水印距离视频左侧15像素。-50
表示水印距离视频上方50像素(负值表示超出视频范围)。
如果想让水印放在视频的右下角,可以使用overlay = W-w-10:H-h-10
,其中W
是视频的宽度,H
是视频的高度,w
是水印图片的宽度,h
是水印图片的高度,10
是距离右下角的边距,可以根据需求调整。-c:v libx264
指定使用libx264
编码器对输出视频进行压缩,libx264
是一种高效的视频编码格式,支持多种质量和压缩比配置。-preset slow
设置编码速度与压缩效率的平衡。slow
设置编码速度较慢,但能提供更高的压缩率和更好的视频质量。-crf 18
指定编码的恒定质量参数(CRF,Constant Rate Factor)。18
是一个较低的 CRF 值,表示更高的视频质量(范围是 0-51,值越低质量越高,文件越大)。-c:a copy
保留输入视频的音频流,直接拷贝到输出文件中,避免重新编码。output.mp4
输出文件,不过这里不用-o
这些参数可以按需调整。
批量加水印
创建一个名为add_watermark.sh
的脚本文件,内容如下:
bash
#!/bin/bash
# 设置文件夹路径和水印图片路径
INPUT_DIR="path/to/your/input/folder"
WATERMARK="path/to/your/watermark.png"
OUTPUT_DIR="path/to/your/output/folder"
# 创建输出文件夹(如果不存在)
mkdir -p "$OUTPUT_DIR"
# 遍历文件夹中的所有视频文件
for video_file in "$INPUT_DIR"/*.mp4; do
# 获取视频文件名
filename=$(basename -- "$video_file")
filename_no_ext="${filename%.*}"
# 输出文件路径
output_file="$OUTPUT_DIR/$filename_no_ext-watermarked.mp4"
# 使用 ffmpeg 添加水印
ffmpeg -i "$video_file" -i "$WATERMARK" -filter_complex "overlay=10:15" "$output_file"
done
- 替换
"path/to/your/input/folder"
为视频文件的实际路径。 - 替换
"path/to/your/watermark.png"
为水印的图片路径。 - 设置
"path/to/your/output/folder"
为保存处理过的视频文件的路径。
在命令行中进入到脚本所在的目录,并运行:
bash
chmod +x add_watermark.sh
./add_watermark.sh
这段脚本会遍历文件夹下的所有 .mp4
视频文件,将每个视频文件加上水印并保存到指定的输出文件夹中。
补充小知识
为什么 [1:v]
是使用第二个输入流
在 ffmpeg
中,输入流的索引是从 0
开始计数的,按照输入文件的顺序进行编号。第一个输入文件 -i input.mp4
的索引为 0
,第二个输入文件 -i watermark.png
的索引为 1。所以 [0:v]
表示第一个文件的视频流,[1:v]
表示第二个文件的视频流。如果mp4
文件还有音频,则 [0:a]
表示它的音频流。
例如,如果我们有如下命令:
bash
ffmpeg -i video.mp4 -i audio.mp3 -i logo.png ...
流的索引会是:
video.mp4
:
[0:v]
:视频流。[0:a]
:音频流(如果有)。
audio.mp3
:
[1:a]
:音频流(mp3 文件只有音频,没有视频)。
logo.png
:
[2:v]
:图片流(图片被视为单帧视频流)。