如何从网络直接从视频部分有效地创建最佳调色板gif


1

我已经使用了一段时间这两个命令将视频片段转换为动画gif,具有 ffmpeg 为它计算最佳调色板:

ffmpeg -ss $START -i $IN_FILE -t $LENGTH -vf "fps=$FPS,scale=$WIDTH:-1:flags=lanczos,palettegen" palette.png
ffmpeg -ss $START -i $IN_FILE -i palette.png -t $LENGTH -filter_complex "fps=$FPS,scale=$WIDTH:-1:flags=lanczos [x]; [x] [1:v] paletteuse" output.gif

这适用于本地文件,但如果我开始使用远程URL $IN_FILE,它会下载所需的部分两次 - 一次用于调色板生成,一次用于实际转换。

提前下载完整文件通常是不可能的 - 通常我对较长视频中间的一个非常小的序列感兴趣。

我试着用下载一小部分 -ss-t 并将其保存 - 无需重新编码 - 到临时文件:

ffmpeg -ss $START -i $IN_URL -t $LENGTH -vc copy -ac none temp.mkv

在这种情况下,我确实避免了带宽浪费(只下载文件的相关部分,只有一次),但搜索不再精确, -ss on input只有关键帧的粒度,用于在进行流复制时进行搜索

在理论上转换为gif时,可以进行额外的精确搜索并修复它,但似乎没有办法获得上面生成的临时文件的开始的原始时间戳,因此不可能计算我应该在哪里 -ss 当转码为gif时。我试过玩 -copy_ts,但它没有产生任何好处。

简单的解决方案是在第一步中重新编码(可能在过程中应用缩放/重采样,以避免以后再进行两次),但我想避免一个额外无用编码的成本/质量损失。

那么:我如何执行最佳调色板视频转换为可能大型网络文件的一小部分的gif转换,有效地获取它(=下载一次,只有相关部分),精确搜索并且无需额外的重新编码?

Answers:


1

使用a可以很容易地解决问题 带有多个链的filtergraph ,这使我们只需执行一次搜索/下载/过滤,并以多种方式处理它。搜索/过滤的流被馈送到调色板生成器 到调色板应用程序过滤器,它与生成的调色板一起使用。图形:

                                       .--> palettegen [pal]---.
 input                                /                        |
 [0:v] -> fps -> scale -> split=2 [a][b]                       V
 with                                 `-> [b] fifo [b] -> [b] [pal] paletteuse -> out.gif
precise
 seek

这意味着:

ffmpeg -ss $START -I $IN_URL -t $LENGTH -filter_complex "fps=$FPS,scale=$WIDTH:-1:flags=lanczos,split=2 [a][b]; [a] palettegen [pal]; [b] fifo [b]; [b] [pal] paletteuse" out.gif

请注意,要使用相同的流作为两个独立管道分支的输入,必须使用 split 过滤。

编辑 fifo 得到了感谢 @Gyan 的评论;这是必要的,因为 palettegen 需要在生成调色板之前等到流的末尾,并且 paletteuse 无法开始消费 [b] 在拥有调色板之前,因此如果视频足够大,则默认缓冲区为 [b] 是不够的 ffmpeg 将开始丢帧。解决方案是添加一个 fifo 在中间处理任意大小的缓冲(必须注意不要超过视频长度,因为在内存中缓冲整个流可能会对可用的RAM造成负担)。

(无耻的插头:这是命令 我现在正在使用 在我的 tube2gif_bot 电报机器人)


最重要的是,这是一个故事 了解您正在使用的命令 ;问题中引用的第二个命令已经使用了一个复杂的过滤器图,但是当我从网上盲目地复制粘贴时,我并没有真正尝试理解不透明的filtergraph语法,所以我没有想到只是稍微调整一下本来是最好的解决方案。


用户可能需要缓冲第二个分割副本,因为palettegen默认情况下仅在分析整个流后返回调色板。 paletteuse,otoh正在等待该调色板开始处理。因此,对于较长的流,以避免帧丢失 [b],缓冲它像这样: [b]fifo[b];[b][pal]...
Gyan

@Gyan:呃,这是我不知道的另一件事,我认为过滤器自己做了所有需要的缓冲!我马上解决这个问题。
Matteo Italia

1
在较新的版本中,他们做到了这一点。但是ffmpeg也是一个流媒体应用程序。因此,实际上有一个下降阈值。
Gyan
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.