短视频时代,内容创作者每天都要处理大量视频素材。手动添加水印、拼接片头不仅耗时耗力,还容易出错。今天我们就用Python+FFmpeg打造一套自动化视频处理流水线,让机器帮你完成这些重复劳动。
首先确保你的系统已经安装FFmpeg。在终端运行ffmpeg -version检查是否安装成功。如果没有安装,可以通过以下命令快速安装:
bash复制# Ubuntu/Debian
sudo apt-get install ffmpeg
# macOS
brew install ffmpeg
# Windows
choco install ffmpeg
Python环境推荐使用3.7+版本,主要依赖库如下:
python复制pip install ffmpeg-python tqdm
ffmpeg-python是FFmpeg的Python封装,比直接调用subprocess更友好;tqdm用于显示进度条
最简单的文字水印可以通过drawtext滤镜实现:
python复制import ffmpeg
(
ffmpeg
.input('input.mp4')
.filter('drawtext',
text='©YourBrand',
x='(w-text_w)/2',
y='(h-text_h)/2',
fontsize=24,
fontcolor='white',
box=1,
boxcolor='black@0.5')
.output('output.mp4')
.run()
)
关键参数说明:
x/y:水印位置,支持动态表达式box:是否添加背景框enable:可以设置时间段显示水印让Logo在视频中沿对角线移动:
python复制overlay_opts = {
'x': 'if(gte(t,0), -w+(t)*20, NAN)',
'y': 'if(gte(t,0), -h+(t)*10, NAN)'
}
(
ffmpeg
.input('input.mp4')
.overlay(ffmpeg.input('logo.png'), **overlay_opts)
.output('output.mp4')
.run()
)
结合多个滤镜实现专业级效果:
python复制ffmpeg_cmd = (
ffmpeg
.input('input.mp4')
.filter('colorchannelmixer', aa=0.5)
.filter('drawtext',
text='{:%Y-%m-%d %H:%M:%S}'.format(datetime.now()),
x='w-tw-10',
y='h-th-10',
fontsize=20,
fontcolor='white',
timecode='00:00:00')
.overlay(ffmpeg.input('logo.png'), x='main_w-overlay_w-10', y='10')
.output('output.mp4', vcodec='libx264', crf=18)
)
python复制intro = ffmpeg.input('intro.mp4')
main = ffmpeg.input('content.mp4')
ffmpeg.concat(
intro,
main
).output('final.mp4').run()
添加淡入淡出转场:
python复制intro = ffmpeg.input('intro.mp4').filter('fade', type='out', duration=1, start_time=4)
main = ffmpeg.input('content.mp4').filter('fade', type='in', duration=1)
ffmpeg.concat(
intro,
main,
v=1,
a=1
).output('final.mp4').run()
python复制from pathlib import Path
videos = Path('videos').glob('*.mp4')
intro = ffmpeg.input('intro.mp4')
for idx, video in enumerate(videos):
main = ffmpeg.input(str(video))
(
ffmpeg.concat(intro, main)
.output(f'processed/{video.stem}_final.mp4')
.run()
)
python复制import ffmpeg
from pathlib import Path
from datetime import datetime
from tqdm import tqdm
def process_video(input_path, output_dir, watermark_text):
output_path = output_dir / (input_path.stem + '_processed.mp4')
# 动态水印
video = ffmpeg.input(str(input_path))
watermark = ffmpeg.filter(
video,
'drawtext',
text=watermark_text,
fontfile='Arial.ttf',
fontsize=24,
fontcolor='white',
x='w-tw-10',
y='h-th-10',
box=1,
boxcolor='black@0.5',
enable=f'between(t,2,{duration-2})'
)
# 添加片头
intro = ffmpeg.input('assets/intro.mp4')
final = ffmpeg.concat(
intro,
watermark,
v=1,
a=1
)
# 输出配置
(
final
.output(
str(output_path),
vcodec='libx264',
preset='fast',
crf=23,
movflags='faststart'
)
.overwrite_output()
.run(quiet=True)
)
if __name__ == '__main__':
input_dir = Path('input_videos')
output_dir = Path('processed')
output_dir.mkdir(exist_ok=True)
videos = list(input_dir.glob('*.mp4'))
for video in tqdm(videos, desc='Processing videos'):
try:
process_video(video, output_dir, '©MyStudio 2023')
except Exception as e:
print(f"Error processing {video.name}: {str(e)}")
优化建议:
ThreadPoolExecutor实现并行处理| 参数 | 推荐值 | 说明 |
|---|---|---|
| crf | 18-28 | 数值越小质量越高 |
| preset | fast/slow | 编码速度与压缩率平衡 |
| movflags | faststart | 优化网络播放 |
| pix_fmt | yuv420p | 最大兼容性 |
python复制try:
ffmpeg.run(..., capture_stdout=True, capture_stderr=True)
except ffmpeg.Error as e:
print('stdout:', e.stdout.decode('utf8'))
print('stderr:', e.stderr.decode('utf8'))
python复制.output(
...,
vcodec='h264_nvenc', # NVIDIA GPU
# vcodec='h264_videotoolbox', # macOS
# vcodec='h264_amf', # AMD
preset='fast',
crf=23
)
实际测试中,使用RTX 3060处理4K视频,速度比纯CPU快5-8倍。记得先运行ffmpeg -hwaccels查看支持的硬件加速方案。