我想创建一个类似于白板动画风格的YouTube视频。
Tldr问题:如何使用ffmpeg编码为无损rgb视频格式,包括alpha通道?
更详细: 我目前的工作流程如下:
我在Inkscape中绘制幻灯片,我将所有要绘制的路径分组(一个场景可以这么说)并将幻灯片存储为svg。然后我运行一个自定义的python脚本。它按照此处所述https://codepen.io/MyXoToD/post/howto-self-drawing-svg-animation为幻灯片设置动画。每个帧都被导出为svg,转换为png并馈送到ffmpeg以从中制作视频。
对于每个场景(绘制几条路径,每张幻灯片有几个场景)我创建一个自己的视频文件,然后我还存储一个包含该视频最后一帧的png文件。
然后我使用kdenlive将它们连接在一起:一个视频包含第一个场景的绘图,然后是一个png,它在我谈论绘图时保存视频的最后一个图像,然后是下一个动画绘图,然后是下一个静止图像我继续说话等等。我使用这些中间图像,因为冻结最后一帧在kdenlive中是乏味的,我有大约600个场景。在这里,我进行编辑,调整静止图像的持续时间并渲染最终视频。
视频的背景是黑板上永远不会改变的照片,笔画是带有滤镜的路径,使其看起来像粉笔。
到目前为止一切都很好,一切都很有效。
我的问题是:每当动画和静止图像之间出现过渡时,最终结果都会显示。我已经尝试了几种方法来完成这项工作但没有任何缺陷。
我的第一个方法是将动画编码为mp4,如下所示:
p = Popen(['ffmpeg', '-y', '-f', 'image2pipe', '-vcodec', 'png', '-r', str(fps), '-i', '-', '-vcodec', 'libx264', '-crf', '21', '-bf', '2', '-flags', '+cgop', '-pix_fmt', 'yuv420p', '-movflags', 'faststart', '-r', str(fps), videofile], stdin=PIPE)
推荐用于YouTube。但是视频和静止图像之间存在一点亮度差异。
然后我用png编解码器尝试了mov:
p = Popen(['ffmpeg', '-y', '-f', 'image2pipe', '-vcodec', 'png', '-r', str(fps), '-i', '-', '-vcodec', 'png', '-r', str(fps), videofile], stdin=PIPE)
我认为这会将每个帧编码为视频中的png。它创建了更大的文件,因为每个帧都是单独编码的。但它没关系,因为我可以使用透明度作为背景并只存储粉笔笔画。但是,有时我想在幻灯片上滑动部分粉笔,我通过在其上绘制背景来做。如果存储在视频中的那些重叠的动画背景块看起来与背景中的底层png完全相同,那么这将起作用。但它并没有。它稍微模糊一点,我相信颜色也会变化一点点。我不明白,因为我认为视频只存储了一系列pngs ......我在这里想到了一些高质量的设置吗?
然后我读到了关于ProRes4444并尝试过:
p = Popen(['ffmpeg', '-y', '-f', 'image2pipe', '-vcodec', 'png', '-r', str(fps), '-i', '-', '-c:v', 'prores_ks', '-pix_fmt', 'yuva444p10le', '-alpha_bits', '8', '-profile:v', '4444', '-r', str(fps), videofile], stdin=PIPE)
这实际上似乎有效。但是,动画文件变得比它们包含的一堆png文件大,可能是因为这种格式每个通道存储12位。这并不可怕,因为只有中间视频变大,最终结果仍然可以。
但理想情况下会有一个无损编解码器存储在rgb色彩空间中,每个通道8位,alpha位8位,并且仅考虑与前一帧的差异(因为所有在帧与帧之间的变化都是一点点粉笔画画)。有这样的事吗?或者,我也没有透明度,但我必须在每个场景中存储背景。但是,如果只在一个场景中从一帧到另一帧存储更改,则应该是可管理的。
或者我应该完全改变我的工作流程?
对不起,这是相当冗长的,我感谢任何帮助。
干杯!