行车记录仪视频ffmpeg合并转录存档,跳过重复的漏秒
Posted | stdout
手上有几个行车记录仪
- VOSONIC 勤宇V10,也叫群华 路不平,用的 联咏 Novatek NT96550BG 的芯片,1080p
- BLACKVIEW 凌度A12,采用 安霸(Ambarella) A12 方案,2k
- PAPAGO 趴趴狗,GoSafe 560WiFi,采用 NT96670 芯片+IMX415的 sony CMOS,4k
特点是每5分钟切割成一个单独的文件,为了防止每两个视频之间漏秒,所以会额外重复写入1秒的内容
现在想把一段时间的视频合并成一个存档,并且要跳过那些额外的1秒,上 ffmpeg。
首先前摇,生成需要合并的视频文件路径列表
ls -fd1 /Volumes/SD_CARD/DCIM/xxxxx/*
的结果写成如下格式:
file 'input1.mov'
inpoint 10
outpoint 300
file 'input2.mov'
# comment
outpoint 300
file 'input3.mov'
outpoint 300
...
file 'inputN.mov'
outpoint 300
inpoint 10
就是从10秒开始算,outpoint 300
就是到300秒结束。保存上面的为 1.txt
然后念 ffmpeg 咒语
ffmpeg -hwaccel cuda -hwaccel_output_format cuda -safe 0 -r 48 -f concat -i 1.txt -an -vf "select=concatdec_select,scale_cuda=w=1280:h=720:interp_algo=lanczos,setpts=0.125*PTS" -c:v h264_nvenc -preset:v p7 -profile:v high -tune:v hq -cq:v 19 -qmax 22 -b:v 0 -maxrate 8M -rc vbr out.mp4
逐个解释下:
-hwaccel cuda
用nVIDIA的 H.264 解码器硬件加速解码行车记录仪的原始 .MOV 文件。如果没显卡有 Intel 处理器可以 把 cuda 换成 qsv 也有加速效果。也可以换成 cuvid 但是速度更慢-hwaccel_output_format cuda
生成 out.mp4 的时候也采用 nVIDIA 显卡H.264编码器加速。这里如果和上面都是cuda
那么直接显存对拷,避免了内存和 PCI 拷贝速率瓶颈。-safe 0
允许读写外部文件-r 48
和后面的setpts=0.125*PTS
一起,把帧率提高到 48fps ,把回放速度提高 8倍。方便存档。不需要的可以去掉-f concat
和select=concatdec_select
就是通过前摇的1.txt
指定合并哪些文件(并且去掉时间起止点之外的)-an
丢掉音轨。如果保留的话应该是-v:a copy
-vf
后面指定一系列巨复杂的ffmpeg滤镜操作。scale_cuda=w=1280:h=720:interp_algo=lanczos
,用显卡 CUDA 操作缩放操作。lanczos是一种 downsampling 算法让画面更加平滑。如果你自己编译的还可以把 scale_cuda 换成 scale_npp 进一步提速。- 如果没有独显换成软缩放
-vf "select=concatdec_select,scale=1280x720,setsar=1,setpts=0.125*PTS" -sws_flags lanczos
-c:v h264_nvenc
视频压缩引擎:nVIDIA 的 H.264 编码器。如果没有独显可以改成 libx264-preset:v p7
这里代替之前的 slow fast 等选项。参考 HEVC Preset Migration-profile:v high
如果你要兼容初代 iPad 等古董设备就只能用main
-tune:v hq
面向画质优化(而不是码率或者延时)-cq:v 19
画质非常接近无损的。但是体积也变大。一般22中等配置不能再大了。H.265 可以设置成 26。如果是libx264
改成-crf 19
指定-qmax 22
上面的值最大为 22-b:v 0
取消码率指定-maxrate 8M
最高码率 8Mbps-rc vbr
可变码率。注意 vbr_hq 之类的已经不在支持了。
还有一些坑点:
- 2k@60fps的分辨率需要指定
-level 51
。因为默认的 H.264 级别太低frame size支持不了。。。 - 如果不缩放原始尺寸压制,很有可能会出错 No decoder surfaces left. Error while decoding stream #0:0: Invalid data found when processing input。这是 ffmpeg 4.1 以后的 bug 解决方案是
-extra_hw_frames 2
或者更大。但是 CUDA 最多支持32所以估计会报错,就只能 CPU 负责解码 GPU 负责编码。 - 压制的时候发现 TF 卡或者是读卡器20M/s是瓶颈。拷到本地发现 GPU decoder 是100%,encoder只有30%左右。
- 2k分辨率20Mbps码率30fps的原始视频占用体积太大,1080p 16Mbps码率效果比 720p 8Mbps好不了多少。最后选择的是8M码率。在超快移动的时候有色块,其他堵车的时候画质很高。识别车牌几乎不受影响
总的来说,ffmpeg 真是操作糟糕而功能强大的工具的典型。以上参数为东拼西凑撞大运偶得,如有不对敬请指正。
Comments