每秒获取视频帧的图片

get a picture of the frame of a video at every second

Youtube 有这个很酷的功能,您可以 'scrub' 浏览视频,他们会每秒为您提供视频的缩略图视图:

有人知道这是怎么实现的吗?服务器是否必须单独发送每个图像,或者可以使用 javascript 从客户端计算机上的视频中提取它们?

关于 "extraction" 的实现,我有点迷茫,但我想 canvas 元素一旦被提取就可以用来绘制框架。

如果必须使用服务器:由于图像很小,我想我可以使用精灵,但如果我们谈论的是视频的每一秒,那么该文件可能会变得很大。 (与我认为的视频数据相比仍然很小,但不是最佳的)

在 HLS 中,这是通过 #EXT-X-I-FRAMES-ONLY 播放列表 (HLS v4) 完成的,称为 Trick Play。希望这对您的研究有所帮助。

https://developer.apple.com/library/ios/technotes/tn2288/_index.html#//apple_ref/doc/uid/DTS40012238-CH1-I_FRAME_PLAYLIST

tl;dr 服务器生成精灵 sheets,根据需要下载。

我们可以猜测图像是在服务器端生成的。 YouTube 对每个视频进行的处理比提取一些缩略图要密集得多。此外,快速 Google 表明此功能已经存在了几年 - 可能比 HTML5/JS/browser-horsepower 执行此操作所需的时间更长 client-side.

我在浏览器中点击 Download Tools > Resources 并从我的 Feed 中签出 newly-posted video。有趣的是,还没有预览(我检查时视频只播放了大约 20 分钟)。这表示图像可能已生成 server-side,只是尚未完成处理。

检查 an older video 并查看 Resources > Images 没有发现任何有趣的东西。所以我切换到 Timelines 并点击记录,然后开始将鼠标悬停在时间线上并观察网络流量。当我移动鼠标时,*.jpg 个文件开始加载,它们包含给定视频部分的 25 个缩略图:

我还注意到初始文件 M0.jpg 是相同大小的图像,但包含整个视频的大约 100 个缩略图,而不是一个片段的 25 个缩略图。示例:

再次测试新视频,看起来 100 张图像 M0.jpg 首先下载并提供基本的 lower-res less-granular 缩略图预览。然后,当您将鼠标悬停在视频的不同部分时,higher-res M0.jpgM1.jpg 等会根据需要下载。

有趣的是,longer videos 并没有改变,这就解释了为什么缩略图有时会很糟糕。如果您的网络连接或 YouTube 获取 higher-res 缩略图的速度太慢,那么您将只能看到一个非常长的视频的 100 low-res 个缩略图。不确定这对较短的视频有何影响。此外,看看他们从什么分布中提取缩略图可能会很有趣(它只是视频的每 1/100 线性吗?还是其他)。

最后一点,我注意到如果你使用带有时间码的 url,你不会得到完整的 100 张图像 M0.jpg sheet 而是一个完整的不同大小 M#.jpg,包含从时间码到视频结尾的大约 25 low-res 个缩略图。

我猜他们假设当人们 link 到特定时间码时,用户不太可能跳到视频中较早的点。此外,这比发送普通的 100 张图像 M0.jpg 得到的大约 75 张图像要小得多。另一方面,它也只有大小的 30% 左右,所以也许速度很重要。

至于生成缩略图,ffmpeg 是一个不错的方法:

To make multiple screenshots and place them into a single image file (creating tiles), you can use FFmpeg's tile video filter, like this:

ffmpeg -ss 00:00:10 -i movie.avi -frames 1 -vf "select=not(mod(n\,1000)),scale=320:240,tile=2x3" out.png

That will seek 10 seconds into the movie, select every 1000th frame, scale it to 320x240 pixels and create 2x3 tiles in the output image out.png, which will look like this: