俩木成林 发表于 2023-9-7 21:56:47

notes-for-ffmpeg

一些ffmpeg处理视频笔记。

裁剪黑边
主要使用 ffmpeg 的 crop 以及 cropdetect 参数。

视频左上角为坐标(0,0),单位为像素。

ffmpeg -i input.mp4 -vf "cropdetect=24:16:0" dummy.mp4

# 可以得到如下所示信息
# x1:36 x2:1883 y1:0 y2:1079 w:1840 h:1072 x:40 y:4 pts:3584 t:0.233333 crop=1840:1072:40:4

# Ctrl + C 停止,复制 crop=1840:1072:40:4 用于后面步骤
# 注意视频黑边 是否会变化,否则需取舍使用哪些参数。

# 也可以使用 ffplay 预览,不用'压制'即可得到 crop 信息。
ffplay input.mp4 -vf cropdetect=24:16:0

# 后面的参数 24 16 0 为默认值,更多请移步 [官方文档](https://www.ffmpeg.org/ffmpeg-filters.html#cropdetect)


关于 crop,第一个 1840 表示裁剪出来的矩形长1840像素,宽1072像素,从(40,0)坐标处开始裁剪。crop官方文档。

除了使用 ffmpeg 的 cropdetect 参数外,可以截取一张视频图片,使用 GIMP 等图像工具,手动测量得到需要的参数。 以 GIMP 为例: 1. 拉出参考线,Ctrl+鼠标滚轮放大,M 移动工具; 2. Shift + M 换到测量工具,Ctrl 拉出水平垂直测量线。

notes-for-ffmpeg-2019-6-2-18-7-13.png

notes-for-ffmpeg-2019-6-2-18-7-28.png

去水印
和裁剪黑边类似,使用 delogo 命令,官方文档。

同样需要定位位置,使用上面提到的 GIMP 测量坐标。 delogo=x=1742:y=992:w=132:h=40,如其意,x y坐标起点(左上角0、0),w h宽和高。 一次可以定义多个去水印位置,使用 , 分隔,放置在滤镜参数里面。例子如下:

ffmpeg -y -i in.mp4 -vf "delogo=x=1472:y=35:w=408:h=42,delogo=x=1742:y=992:w=132:h=40,crop=1840:1040:40:0" \
-metadata comment='made by rachpt' -max_muxing_queue_size 1024 out.mp4


两个水印,加上裁剪黑边。

效果对比如下:

倍速
详见: https://github.com/rachpt/shell-scripts/blob/master/speed_up_video.sh

视频
1.7 倍速:

ffmpeg -i "$i" -r 30 -c:v libx264 -preset fast \
-filter_complex "setpts=10/17 *PTS;atempo=1.7" \
-map "" -map "" "../encode/$i" -y


音频
如上,atempo=1.7。

字幕
使用shell来完成,

for i in `grep -Eo '({2}:){2}{2},{3}' "$file"` ;do
a=${i:0:2};
b=${i:3:2};
c=${i:6:2};
d=${i:9:3};
# 匹配视频 1.7 倍速
total=`echo "scale=0;((($a*60+$b)*60+$c)*1000+$d)/1.7"|bc`;
e=$((total % 1000));f=$((total / 1000));
g=$((f % 60));
h=$((f / 60));x=$((h % 60));
y=$((h / 60)) ;
j=`printf "%02d:%02d:%02d,%03d\n" $y $x $g $e`;
sed -i "s/$i/$j/" "$file";
done

# 最后封装在一起参数
ffmpeg -i in.mp4 -i sub.srt -c:s mov_text -c:v copy -c:a copy out.mp4

音视频提取与合并
提取

# 提取视频
ffmpeg -i input.mp4 -c:v copy -an video.mp4
# 提取音频
ffmpeg -i input.mp4 -c:a copy -vn audio.m4a

其中 v 视频,a 音频。

合并

# 视频 音频 (字幕)分别单文件
ffmpeg -i input.mp4 -i audio.m4a -i sub.srt -c:v copy -c:a copy -c:s mov_text output.mp4
# 视频里面有音轨,需要替换音轨
ffmpeg -i input.mp4 -i audio.m4a -c:v copy -c:a copy -map 0✌️0 -map 1🅰️0 output.mp4
# 追加音轨,再加一个-map 0🅰️0

# 封装多字幕
ffmpeg -i input.mp4 -i chs.srt -i eng.srt -c copy -map 0:0 -map 0:1 -map 1:0 -map 2:0 \
-c:s mov_text -c:s mov_text output.mp4

map 参数第一个表示 输出文件,0 第一个,1 第二个,v/a 和上面提到的一样,表示视频 / 音频,最后面的数字表示输入文件里面的第几个视频 / 音频 轨道。通常一个视频 一个视频轨道一个音频轨道,这个需要自己看 mediainfo。

删除压制信息
删除视频文件 mediainfo 里面的 Writing library 和 Encoding settings, 添加如下参数

# x265
-x265-params no-info=1

# x264 (ffmpeg 4.0+)
-bsf:v 'filter_units=remove_types=6'

# 删除 General 里面的附加信息
-map_metadata -1

参考文档一,文档二。

停止播放
ffplay 使用 -t 时间 可以只播放一小段,但是并不会到时间后退出播放,而是会处于等待状态。 添加 -autoexit 参数即可解决该问题。

其他
使用 -ss 0:0:0 -t 1:0:0 后可能会遇到下面的报错,

Too many packets buffered for output stream 0:1.

只需要多加一个 -max_muxing_queue_size 1024 参数在其中即可解决,详见这里。

隐藏 版本信息编译参数
添加参数 -hide_banner 即可。

libx265 2pass 遇到如下错误,卡住不动

cur_dts is invalid (this is harmless if it occurs once at the start per stream)
在不同机器上,不同版本 ffmpeg 使用相同的压制命令却不会遇到这个问题。
另外,换用 libx264 不会遇到此问题。


多番查证,可能是原视频某些信息不全所致。 最终发现是 使用的 缩放 (-s 1280x720 或者 滤镜 - vf scale=-2:720) 参数导致的,去掉缩放,2pass 不会遇到此问题。

最后曲线救国,先将原文件使用 ffmpeg -c copy 相同容器复制一份,使用新生成的文件成功缩放压制。

缩放警告

Warning: data is not aligned! This can lead to a speed loss

修改 宽度 为 16 的倍数。参考文档。
页: [1]
查看完整版本: notes-for-ffmpeg