行车记录仪视频ffmpeg合并转录存档,跳过重复的漏秒 - Est's Blog

行车记录仪视频ffmpeg合并转录存档,跳过重复的漏秒

手上有几个行车记录仪

  • 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 concatselect=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