从视频中提取特定帧的最快方法(PHP / ffmpeg /任何内容)

2022-08-30 10:32:07

我有一个网页,它需要从用户上传的视频中提取特定的帧。用户在播放器中查找.mp4的特定部分,然后单击一个按钮,然后向php脚本发出ajax调用,该脚本从视频中获取.mp4和确切时间,并使用它来提取“缩略图”帧。

我目前的解决方案是使用php命令:exec

exec("ffmpeg -i $videoPath -ss $timeOffset -vframes 1 $jpgOutputPath");

...这很好用,除了它像糖蜜一样慢。我的猜测是ffmpeg对于这项工作来说有点太多了,我也许可以通过利用底层库或其他东西做得更好......但是我不知道该怎么做。

理想情况下,我不想安装任何需要真正“安装过程”的东西......也就是说,将可执行文件拖放到我的Web应用程序的文件夹中是可以的,但我宁愿不必实际运行安装程序。此外,该解决方案应该能够在Mac,linux和Windows上运行(尽管linux是重中之重)。

我能做些什么来加快这个过程?

谢谢。


答案 1

当然,你可以编写一些C /C++并链接到-lav*,基本上创建一个简化版本的ffmpeg只是为了提取帧,甚至可能将其作为php扩展(我也不会以同一用户的身份运行它,更不用说在同一进程中了)。但结果不太可能更快,因为您只能避免一些分叉和设置开销,但您可能的问题实际上是解码,这仍然是相同的。

相反,您应该首先考虑在快速搜索模式(或快速/准确的混合模式)中使用ffmpeg。他们的维基关于快速搜索的州话:

需要在 -i 之前指定 -ss 参数

ffmpeg -ss 00:03:00 -i Underworld.Awakening.avi -frames:v 1 out1.jpg

本示例将在影片开始后第三分钟左右的某个位置生成一个图像帧 (out1.jpg)。输入将使用关键帧进行解析,这非常快。缺点是它还会在某个关键帧处完成搜索,而不一定位于指定时间 (00:03:00),因此搜索不会像预期的那样准确。

快速搜索不太准确,但速度快得多,因为ffmpeg实际上不需要在搜索期间解码(大部分)电影,而快速/准确的混合模式是很好的折衷方案。阅读维基页面,了解所有可用选项。

编辑14/06/10

从 FFmpeg 2.1 开始,当使用 ffmpeg 转码(即不是流复制)时,即使用作输入选项,-ss 现在也是准确的。可以使用 -noaccurate_seek 选项恢复以前的行为。(来源)

因此,对于2.1 +,在重新编码时,应该不再需要“混合”搜索来获得准确的结果(并且保存到是重新编码)。做通常的快速搜索()而不是缓慢的搜索()就足够了。.jpeg-ss ... -i ...-i ... -ss ...


答案 2

在C / C++直接使用ffmpeg库(正如nmaier所提到的,但没有提供资源):我遇到了同样的问题,这花了我很多工作,但我现在已经C++中实现了帧提取函数,直接使用ffmpeg库(在QT框架中,但它仍然应该有助于普通的C++)。

请参阅我的项目中的函数 QImage Video::ffmpegLib_captureAt(const int percent, const int ofDuration) Video simili duplicate cleaner Video.cpp 文件,它应该是一个不言自明的例子:https://github.com/theophanemayaud/video-simili-duplicate-cleaner/blob/master/QtProject/app/video.cpp


推荐