从视频中提取特定帧的最快方法(PHP/ffmpeg/anything)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18534835/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 17:44:38  来源:igfitidea点击:

Fastest way to extract a specific frame from a video (PHP/ffmpeg/anything)

phpvideoffmpegmp4video-processing

提问by DanM

I have a web page, which (among other things) needs to extract a specific frame from a user-uploaded video. The user seeks to a particular part of a .mp4 in the player, then clicks a button, and an ajax call gets fired off to a php script which takes the .mp4, and the exact time from the video, and uses that to extract a "thumbnail" frame.

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

My current solution is using the php execcommand:

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

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

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

...which works just great, except it's as slow as molasses. My guess is that ffmpeg is a little too much for the job, and I might be able to do better by utilizing the underlying libraries or something... however I have zero idea how to do that.

...这很好用,除了它和糖蜜一样慢。我的猜测是 ffmpeg 对这项工作来说有点太多了,我可能可以通过利用底层库或其他东西做得更好......但是我对如何做到这一点毫无想法。

Ideally I don't want to have to install anything that requires a real "installation process"... i.e., dropping an executable into the folder with my web app is fine, but I'd rather not have to actually run an installer. Also, the solution should be able to run on mac, linux and windows (though linux is the top priority).

理想情况下,我不想安装任何需要真正“安装过程”的东西......即,将可执行文件放入带有我的网络应用程序的文件夹中很好,但我宁愿不必实际运行安装程序。此外,该解决方案应该能够在 mac、linux 和 windows 上运行(尽管 linux 是首要任务)。

What can I do to speed this process up?

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

Thanks.

谢谢。

回答by nmaier

Of course you could code up some C/C++ and link to -lav*, basically creating a simplified version of ffmpeg just for extracting frames, and maybe even do it as a php extension (also I wouldn't run it as the same user, let alone in the same process). But the result is very unlikely to be faster, because you would only avoid some forking and setup overhead, but your likely problem is actually the decoding, which would still be the same.

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

Instead, you should first look into using ffmpeg in fast seeking mode (or fast/accurate hybrid mode). Their wiki statesabout fast seeking:

相反,您应该首先考虑在快速搜索模式(或快速/准确混合模式)下使用 ffmpeg。他们的 wiki 说明了快速搜索:

The -ss parameter needs to be specified before -i:

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

This example will produce one image frame (out1.jpg) somewhere around the third minute from the beginning of the movie. The input will be parsed using keyframes, which is very fast. The drawback is that it will also finish the seeking at some keyframe, not necessarily located at specified time (00:03:00), so the seeking will not be as accurate as expected.

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

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

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

Fast seeking is less accurate, but a damn lot faster, as ffmpeg will not actually need to decode (most of) the movie during the seek, while fast/accurate hybrid mode is good compromise. Read the wiki pagefor all available options.

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

Edit 14/06/10:

10 年 6 月 14 日编辑

As of FFmpeg 2.1, when transcoding with ffmpeg (i.e. not stream copying), -ss is now accurate even when used as an input option. Previous behavior can be restored with the -noaccurate_seek option. (source)

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

So with 2.1+, "hybrid" seeking shouldn't be required anymore for accurate results when it comes to re-encodes (and saving to .jpegis a re-encode). It is enough to do the usual fast seeking (-ss ... -i ...) instead of slow seeking (-i ... -ss ...).

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