一开始用的opencv,但怎么尝试都有质量损失,因此改用ffmpeg,目标是每个环节都无损或尽可能高质量

1. 从视频中截取视频

  1. ffmpeg -ss {start_time} -i {videoname} -t {time} -c:v copy -c:a copy {outputname}

2. 从视频中截取图片

  1. ffmpeg -i {inputname} -r 30 -f image2 {extract_dir}/%05d.png

-r 控制帧率,1s截取多少张
格式建议用png
如果必须要得到jpg格式的话,需要指定参数: -q:v 2, 这个参数数值范围是2-31,值越大质量越差

3. 用图片合成视频

首先图片需要按序号命名,比如我这里的命名是%5d.png

3.1 简单的无损

  • 优势:真无损
  • 缺点:体积大,兼容性差 ```bash

    1 要求输入是png

    ffmpeg -f image2 -r 30 -i {extract_dir}/%05d.png -c:v copy output.mkv

2 libx265和libx264都能实现无损

ffmpeg -f image2 -r 30 -i ffmpeg1/%05d.png -c:v libx265 -crf 0 output_2.mp4 ffmpeg -f image2 -r 30 -i ffmpeg1/%05d.png -c:v libx264 -crf 0 output_2.mp4

  1. -r:多少张图片组成1S<br />-c:v 编码格式,libx264libx265均可,更推荐libx265
  2. <a name="T15LF"></a>
  3. ### 3.2 兼容quicktime的无损/高质量
  4. 上面方法生成的视频无法在quicktime播放,为了提高兼容性,可以采用这样的生成方式
  5. ```bash
  6. # 1
  7. ffmpeg -f image2 -r 30 -i cat_new/%05d.png -c:v libx265 -pix_fmt yuv420p -crf 0 -tag:v hvc1 compare.mp4
  8. # 2
  9. ffmpeg -f image2 -r 30 -i cat_new/%05d.png -c:v libx264 -pix_fmt yuv420p -crf 1 compare2.mp4

想要在quicktime上播放,应指定pix_fmt和tag:v。在google的时候很多答案让只指定其中一个,我测试的情况是需要同时指定两个参数才能兼容。
编码方式为libx265时,crf可以指定为0,但需要额外指定tag:v
编码方式为libx264时,无法做到无损,crf必须取正数

参考

https://superuser.com/questions/1429256/producing-lossless-video-from-set-of-png-images-using-ffmpeg
https://superuser.com/questions/874583/lossless-h-264-mp4-file-created-from-images-cannot-be-played-in-quicktime
https://superuser.com/questions/1293639/re-encode-4k-video-to-h-265-hevc-with-ffmpeg-for-playback-in-quicktime