如何用FFmpeg+MoviePy实现任意方向视频的Logo正确叠加?
解决FFmpeg任意方向视频Logo叠加问题
核心思路
先通过ffprobe提取视频的旋转元数据,根据不同旋转角度调整Logo的旋转方向和叠加位置,同时避免视频输出变形。
完整Bash脚本
#!/bin/bash # 配置路径 INPUT_VIDEO="input.mp4" LOGO_FILE="logo.png" OUTPUT_VIDEO="output.mp4" # 获取视频旋转角度,无旋转标签时默认0度 ROTATION=$(ffprobe -v error -select_streams v:0 -show_entries stream_tags=rotate -of default=nw=1:nk=1 "$INPUT_VIDEO") ROTATION=${ROTATION:-0} case $ROTATION in 0|180) # 横屏/倒置横屏处理 if [ "$ROTATION" -eq 180 ]; then # 倒置横屏时Logo同步旋转180度,放在显示的右下角 FILTER="rotate=180:ow='iw':oh='ih',overlay=W-w-10:H-h-10" else # 正常横屏直接叠加在右下角 FILTER="overlay=W-w-10:H-h-10" fi ffmpeg -i "$INPUT_VIDEO" -i "$LOGO_FILE" -filter_complex "[1:v]$FILTER[outv]" -map "[outv]" -map 0:a -c:a copy "$OUTPUT_VIDEO" ;; 90) # 顺时针90度竖屏:Logo逆时针转90度,放在显示的右下角(对应原始视频右上角) FILTER="rotate=-90*PI/180:ow='ih':oh='iw',overlay=W-w-10:10" ffmpeg -i "$INPUT_VIDEO" -i "$LOGO_FILE" -filter_complex "[1:v]$FILTER[outv]" -map "[outv]" -map 0:a -c:a copy -metadata:s:v:0 rotate=90 "$OUTPUT_VIDEO" ;; 270|-90) # 逆时针90度(或270度)竖屏:Logo顺时针转90度,放在显示的右下角 FILTER="rotate=90*PI/180:ow='ih':oh='iw',overlay=W-w-10:10" ffmpeg -i "$INPUT_VIDEO" -i "$LOGO_FILE" -filter_complex "[1:v]$FILTER[outv]" -map "[outv]" -map 0:a -c:a copy -metadata:s:v:0 rotate=270 "$OUTPUT_VIDEO" ;; esac
关键细节说明
- 旋转元数据检测:用
ffprobe读取视频的rotate标签,部分视频无该标签时默认按0度横屏处理。 - Logo旋转与位置:
- 90度竖屏:视频实际存储为宽<高,播放时顺时针旋转90度显示,因此Logo需逆时针转90度,叠加在
W-w-10:10位置(对应显示的右下角)。 - 270度竖屏:Logo顺时针转90度,同样叠加在右上角位置。
- 90度竖屏:视频实际存储为宽<高,播放时顺时针旋转90度显示,因此Logo需逆时针转90度,叠加在
- 避免视频变形:保留原视频的
rotate元数据,确保播放时方向正确,不会强制拉伸成横屏。 - 音频处理:用
-c:a copy直接复制原音频编码,无需重新编码,提升处理速度。
可选方案:直接转正视频
如果不需要保留原旋转元数据,可将视频直接转正为横屏后叠加Logo,逻辑更简单:
# 处理90度竖屏,转正后叠加Logo在右下角 ffmpeg -i "$INPUT_VIDEO" -i "$LOGO_FILE" -filter_complex "[0:v]transpose=1[vid];[1:v]rotate=-90*PI/180[logo];[vid][logo]overlay=W-w-10:H-h-10" -c:a copy "$OUTPUT_VIDEO"
transpose=1:将顺时针90度的竖屏转正为横屏。- 同步旋转Logo到对应方向,再叠加在右下角。
内容的提问来源于stack exchange,提问作者reallymemorable
相关产品推荐
相关产品推荐

