【问题标题】:Get youtube animated thumbnail获取 youtube 动画缩略图
【发布时间】:2018-04-15 11:56:24
【问题描述】:

有没有办法将来自 youtube 的动画缩略图嵌入我的网站?我说的不是静态缩略图,而是看起来像大约 3 秒的动画 .gif 的那个。

【问题讨论】:

  • AFAIK,API 尚不支持此功能。您只会获得缩略图的静态图像。还有一个reported issue 想要提取动画缩略图但标记为预期行为。希望这会有所帮助。

标签: javascript youtube youtube-api animated-gif


【解决方案1】:

不知道对你有没有帮助

但是当你去 youtube 的搜索页面时 你可以访问对象

window.ytInitialData

这里我们有一个节点叫做: window.ytInitialData.contents.twoColumnSearchResultsRenderer.primaryContents.sectionListRenderer.contents["0"].itemSectionRenderer.contents[2].videoRenderer.richThumbnail.movingThumbnailRenderer.movingThumbnailDetails.thumbnails["0"].url

也许你可以找到一种方法来检索这些数据

像这样访问搜索页面并且: https://www.youtube.com/results?search_query=USPwv1zwWV4 我在控制台中尝试过的:

let videos = window.ytInitialData.contents.twoColumnSearchResultsRenderer.primaryContents.sectionListRenderer.contents["0"].itemSectionRenderer.contents;


if (!videos.length) { // includes other renderers i.e: "did you mean ..."
    console.log('no videos in search'); 
    //return;
}

let video = videos.filter( v => v.videoRenderer && v.videoRenderer.videoId == "USPwv1zwWV4")

if (!video.length) { 
    console.log('no video by that ID in search'); 
    //return;
}

let thumbs = video[0].videoRenderer.richThumbnail.movingThumbnailRenderer.movingThumbnailDetails.thumbnails;

if (!thumbs.length) { 
    console.log('no moving thumbs for that video'); 
    //return;
}

console.log(thumbs[0].url);

【讨论】:

【解决方案2】:

截至 2019 年 6 月:

1.获取静态缩略图非常简单

  • 它们通过 YouTube API 公开,更好的是,它们遵循非常简单且统一的 URL 结构(更多详细信息 here)。

2。有限数量的浏览器支持 Youtube 的动画缩略图。

  • 显然,桌面浏览器 Chrome 和 Opera (source)
  • 顺便说一句,缩略图采用WebP 图像格式,具有更宽的browser support

3.为有限数量的视频获取动画缩略图相对容易。

例如,您可以在浏览器开发工具中检查网络活动(Chrome 的更多详细信息)。

在网络面板打开的情况下,访问包含所需视频的页面列表,清除网络活动(您也可以选择“Img”以仅显示与图像相关的活动)并将所需视频悬停。然后只需右键单击所需的资源并复制 url。

如果图片有帮助...

动画缩略图的网址如下所示:

https://i.ytimg.com/an_webp/zdOmNiXvM3w/mqdefault_6s.webp?du=3000&sqp=CPDloOgF&rs=AOn4CLD9rYflZAMK6qBIbYJDoQZLk9UARw

4.据我所知,目前无法以编程方式获取动画缩略图(无需网页抓取)

  • 换句话说,给定视频 ID,目前无法通过 API 或定义的 URL 模式获取动画缩略图 URL。

PS.:希望有人能证明我在第 4 点上是错误的,以下是这些 URL 的一些示例:

https://i.ytimg.com/an_webp/zdOmNiXvM3w/mqdefault_6s.webp?du=3000&sqp=CPDloOgF&rs=AOn4CLD9rYflZAMK6qBIbYJDoQZLk9UARw

https://i.ytimg.com/an_webp/oIIDZq4nZpo/mqdefault_6s.webp?du=3000&sqp=CLyqoegF&rs=AOn4CLD9DyqMoxBTiOPTUX8FQJmUfiu8NA

https://i.ytimg.com/an_webp/X9tU8ybzcFs/mqdefault_6s.webp?du=3000&sqp=CLHroOgF&rs=AOn4CLAX8j6uWUko_54aPJLwkbAe_cUR3w

更改视频 ID 或其他参数不会返回有效的缩略图。

【讨论】:

    【解决方案3】:

    Gifs.com 有一个免费的 API,用于从与媒体相关的 URL 生成带水印的 GIF。

    https://gifs.com/dashboard/api

    它没有明确提及它,但它确实接受 Youtube URL 并从中生成预览。

    这是一个如何与 cURL 一起使用的示例

    curl -XPOST -H "Content-type: application/json" -d '{ "source": "https://www.youtube.com/watch?v=74KxwkLjE9E" }' 'https://api.gifs.com/media/import'
    

    生成大约需要一两分钟,因此如果您使用服务器存储/缓存 gif,您可以创建自己的个人预览生成器。

    这是文档的存档链接 https://web.archive.org/web/20190408212718/http://docs.gifs.com/docs/authentication-key

    【讨论】:

      【解决方案4】:

      我输入了一个 FFmpeg 脚本。要获得许多未压缩的 YouTube 移动缩略图变体,您需要

      1. 下载 FFmpeg 并将 FFmpeg.exe 解压到一个文件夹中。
      2. 将所需视频从 YouTube 下载到同一文件夹,并将其重命名为“video”(如果视频具有 16:9 宽高比)或“sar”(如果视频具有其他/特殊宽高比)。
      3. 在文件夹中运行 cmd。
      4. 手动编辑我的脚本:

        • '00:00:00.0' 在行中与'CuttedFor1.mp4' = img 上显示的帧的时间(在下载的视频中,hh:mm:ss.(1/10 秒的部分)) .youtube.com/vi/(视频 ID)/1.jpg。
        • '00:00:00.0' 在行中与 'CuttedFor2.mp4' = img.youtube.com/vi/(video's ID)/2.jpg 上显示的帧的时间。
        • '00:00:00.0' 在行中与 'CuttedFor3.mp4' = img.youtube.com/vi/(video's ID)/3.jpg 上显示的帧的时间。
        • 其他 '00:00:00.0' = 原始 mqdefault_6s.webp 中第一帧的时间(来自网络选项卡)。
      5. 运行我的脚本。

      6. 计算每个生成的 webp 的持续时间(例如,使用秒表,手动查看 webp 100 次,然后除以 100)(也许自动方法会出现在 How to find the duration of an animated webp?)。
      7. 手动编辑我的脚本,使 setpts 等于 '1/((此处需要粘贴脚本第一次运行后获得的相应 webp 的持续时间)/3)*PTS[v]',并且 atempo 为等于'(这里需要粘贴第一次运行脚本后得到的相应webp的持续时间)/3[a]'。
      8. 删除第一次运行脚本后获得的所有文件。
      9. 再次运行我的脚本。

      易于阅读:

      ffmpeg -i sar.mp4 -vf "crop=in_w:in_w/16*9" -c:a copy video.mp4
      rem // If to obtain a 16: 9 aspect ratio, you need to crop the thumbnail from above and below.
      ffmpeg -i sar.mp4 -vf "crop=in_h/9*16:in_h" -c:a copy video.mp4
      rem // If to obtain a 16: 9 aspect ratio, you need to crop the thumbnail on the sides.
      ffmpeg -ss 00:00:00.0 -i video.mp4 -c copy -t 6 CuttedFor0.mp4
      ffmpeg -i CuttedFor0.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedFormaxresdefault.mp4
      ffmpeg -i SpeedChangedFormaxresdefault.mp4 -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 maxresdefault_6s.webp
      ffmpeg -i CuttedFor0.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedForsddefault.mp4
      ffmpeg -i SpeedChangedForsddefault.mp4 -vf "scale=640:480:force_original_aspect_ratio=decrease,pad=640:480:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 sddefault_6s.webp
      ffmpeg -i CuttedFor0.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedForhqdefault.mp4
      ffmpeg -i SpeedChangedForhqdefault.mp4 -vf "scale=480:360:force_original_aspect_ratio=decrease,pad=480:360:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 hqdefault_6s.webp
      copy hqdefault_6s.webp 0_6s.webp
      ffmpeg -i CuttedFor0.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedFormqdefault.mp4
      ffmpeg -i SpeedChangedFormqdefault.mp4 -vf "scale=320:180:force_original_aspect_ratio=decrease,pad=320:180:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 mqdefault_6s.webp
      ffmpeg -i CuttedFor0.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedFordefault.mp4
      ffmpeg -i SpeedChangedFordefault.mp4 -vf "scale=120:90:force_original_aspect_ratio=decrease,pad=120:90:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 default_6s.webp
      ffmpeg -ss 00:00:00.0 -i video.mp4 -c copy -t 6 CuttedFor1.mp4
      ffmpeg -i CuttedFor1.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedFor1.mp4
      ffmpeg -i SpeedChangedFor1.mp4 -vf "scale=120:90:force_original_aspect_ratio=decrease,pad=120:90:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 1_6s.webp
      ffmpeg -ss 00:00:00.0 -i video.mp4 -c copy -t 6 CuttedFor2.mp4
      ffmpeg -i CuttedFor2.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedFor2.mp4
      ffmpeg -i SpeedChangedFor2.mp4 -vf "scale=120:90:force_original_aspect_ratio=decrease,pad=120:90:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 2_6s.webp
      ffmpeg -ss 00:00:00.0 -i video.mp4 -c copy -t 6 CuttedFor3.mp4
      ffmpeg -i CuttedFor3.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedFor3.mp4
      ffmpeg -i SpeedChangedFor3.mp4 -vf "scale=120:90:force_original_aspect_ratio=decrease,pad=120:90:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 3_6s.webp
      

      准备执行:

      为 SAR 压缩(从上方和下方裁剪缩略图):

      ffmpeg -i sar.mp4 -vf "crop=in_w:in_w/16*9" -c:a copy video.mp4 && ffmpeg -ss 00:00:00.0 -i video.mp4 -c copy -t 6 CuttedFor0.mp4 && ffmpeg -i CuttedFor0.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedFormaxresdefault.mp4 && ffmpeg -i SpeedChangedFormaxresdefault.mp4 -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 maxresdefault_6s.webp && ffmpeg -i CuttedFor0.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedForsddefault.mp4 && ffmpeg -i SpeedChangedForsddefault.mp4 -vf "scale=640:480:force_original_aspect_ratio=decrease,pad=640:480:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 sddefault_6s.webp && ffmpeg -i CuttedFor0.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedForhqdefault.mp4 && ffmpeg -i SpeedChangedForhqdefault.mp4 -vf "scale=480:360:force_original_aspect_ratio=decrease,pad=480:360:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 hqdefault_6s.webp && copy hqdefault_6s.webp 0_6s.webp && ffmpeg -i CuttedFor0.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedFormqdefault.mp4 && ffmpeg -i SpeedChangedFormqdefault.mp4 -vf "scale=320:180:force_original_aspect_ratio=decrease,pad=320:180:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 mqdefault_6s.webp && ffmpeg -i CuttedFor0.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedFordefault.mp4 && ffmpeg -i SpeedChangedFordefault.mp4 -vf "scale=120:90:force_original_aspect_ratio=decrease,pad=120:90:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 default_6s.webp && ffmpeg -ss 00:00:00.0 -i video.mp4 -c copy -t 6 CuttedFor1.mp4 && ffmpeg -i CuttedFor1.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedFor1.mp4 && ffmpeg -i SpeedChangedFor1.mp4 -vf "scale=120:90:force_original_aspect_ratio=decrease,pad=120:90:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 1_6s.webp && ffmpeg -ss 00:00:00.0 -i video.mp4 -c copy -t 6 CuttedFor2.mp4 && ffmpeg -i CuttedFor2.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedFor2.mp4 && ffmpeg -i SpeedChangedFor2.mp4 -vf "scale=120:90:force_original_aspect_ratio=decrease,pad=120:90:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 2_6s.webp && ffmpeg -ss 00:00:00.0 -i video.mp4 -c copy -t 6 CuttedFor3.mp4 && ffmpeg -i CuttedFor3.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedFor3.mp4 && ffmpeg -i SpeedChangedFor3.mp4 -vf "scale=120:90:force_original_aspect_ratio=decrease,pad=120:90:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 3_6s.webp
      

      针对 SAR 进行压缩(侧面裁剪缩略图):

      ffmpeg -i sar.mp4 -vf "crop=in_h/9*16:in_h" -c:a copy video.mp4 && ffmpeg -ss 00:00:00.0 -i video.mp4 -c copy -t 6 CuttedFor0.mp4 && ffmpeg -i CuttedFor0.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedFormaxresdefault.mp4 && ffmpeg -i SpeedChangedFormaxresdefault.mp4 -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 maxresdefault_6s.webp && ffmpeg -i CuttedFor0.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedForsddefault.mp4 && ffmpeg -i SpeedChangedForsddefault.mp4 -vf "scale=640:480:force_original_aspect_ratio=decrease,pad=640:480:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 sddefault_6s.webp && ffmpeg -i CuttedFor0.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedForhqdefault.mp4 && ffmpeg -i SpeedChangedForhqdefault.mp4 -vf "scale=480:360:force_original_aspect_ratio=decrease,pad=480:360:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 hqdefault_6s.webp && copy hqdefault_6s.webp 0_6s.webp && ffmpeg -i CuttedFor0.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedFormqdefault.mp4 && ffmpeg -i SpeedChangedFormqdefault.mp4 -vf "scale=320:180:force_original_aspect_ratio=decrease,pad=320:180:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 mqdefault_6s.webp && ffmpeg -i CuttedFor0.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedFordefault.mp4 && ffmpeg -i SpeedChangedFordefault.mp4 -vf "scale=120:90:force_original_aspect_ratio=decrease,pad=120:90:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 default_6s.webp && ffmpeg -ss 00:00:00.0 -i video.mp4 -c copy -t 6 CuttedFor1.mp4 && ffmpeg -i CuttedFor1.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedFor1.mp4 && ffmpeg -i SpeedChangedFor1.mp4 -vf "scale=120:90:force_original_aspect_ratio=decrease,pad=120:90:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 1_6s.webp && ffmpeg -ss 00:00:00.0 -i video.mp4 -c copy -t 6 CuttedFor2.mp4 && ffmpeg -i CuttedFor2.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedFor2.mp4 && ffmpeg -i SpeedChangedFor2.mp4 -vf "scale=120:90:force_original_aspect_ratio=decrease,pad=120:90:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 2_6s.webp && ffmpeg -ss 00:00:00.0 -i video.mp4 -c copy -t 6 CuttedFor3.mp4 && ffmpeg -i CuttedFor3.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedFor3.mp4 && ffmpeg -i SpeedChangedFor3.mp4 -vf "scale=120:90:force_original_aspect_ratio=decrease,pad=120:90:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 3_6s.webp
      

      压缩为 16:9(“视频”):

      ffmpeg -ss 00:00:00.0 -i video.mp4 -c copy -t 6 CuttedFor0.mp4 && ffmpeg -i CuttedFor0.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedFormaxresdefault.mp4 && ffmpeg -i SpeedChangedFormaxresdefault.mp4 -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 maxresdefault_6s.webp && ffmpeg -i CuttedFor0.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedForsddefault.mp4 && ffmpeg -i SpeedChangedForsddefault.mp4 -vf "scale=640:480:force_original_aspect_ratio=decrease,pad=640:480:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 sddefault_6s.webp && ffmpeg -i CuttedFor0.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedForhqdefault.mp4 && ffmpeg -i SpeedChangedForhqdefault.mp4 -vf "scale=480:360:force_original_aspect_ratio=decrease,pad=480:360:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 hqdefault_6s.webp && copy hqdefault_6s.webp 0_6s.webp && ffmpeg -i CuttedFor0.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedFormqdefault.mp4 && ffmpeg -i SpeedChangedFormqdefault.mp4 -vf "scale=320:180:force_original_aspect_ratio=decrease,pad=320:180:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 mqdefault_6s.webp && ffmpeg -i CuttedFor0.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedFordefault.mp4 && ffmpeg -i SpeedChangedFordefault.mp4 -vf "scale=120:90:force_original_aspect_ratio=decrease,pad=120:90:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 default_6s.webp && ffmpeg -ss 00:00:00.0 -i video.mp4 -c copy -t 6 CuttedFor1.mp4 && ffmpeg -i CuttedFor1.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedFor1.mp4 && ffmpeg -i SpeedChangedFor1.mp4 -vf "scale=120:90:force_original_aspect_ratio=decrease,pad=120:90:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 1_6s.webp && ffmpeg -ss 00:00:00.0 -i video.mp4 -c copy -t 6 CuttedFor2.mp4 && ffmpeg -i CuttedFor2.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedFor2.mp4 && ffmpeg -i SpeedChangedFor2.mp4 -vf "scale=120:90:force_original_aspect_ratio=decrease,pad=120:90:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 2_6s.webp && ffmpeg -ss 00:00:00.0 -i video.mp4 -c copy -t 6 CuttedFor3.mp4 && ffmpeg -i CuttedFor3.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedFor3.mp4 && ffmpeg -i SpeedChangedFor3.mp4 -vf "scale=120:90:force_original_aspect_ratio=decrease,pad=120:90:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 3_6s.webp
      

      要获得 压缩 YouTube 移动缩略图的许多变体,您需要重写我的脚本,以便它创建具有指定帧数的 webp,因此 FPS(您可以在原始 mqdefault_6s.webp),持续时间正好 3000 毫秒,最后一帧通过它自己的时间戳,压缩图像(或类似的东西,这会产生锐度或颜色丢失的效果,如下图所示)。

      原始 webp 中提取的帧:https://i.stack.imgur.com/Iow4N.png

      自制 webp中提取的框架:https://i.stack.imgur.com/Q3loy.png

      【讨论】:

        【解决方案5】:

        这可能无法直接回答 OP 的问题,但可能对浏览的人有用。

        事实证明,YouTube 移动缩略图的 URL 参数不仅是半随机的,而且还会不断变化。我的猜测是这是因为 Google 不希望我们能够以编程方式获取这些缩略图。至少现在不会。

        一种解决方法是将您需要的每个缩略图保存到您的服务器,将其命名为您的视频 ID(例如 dQw4w9WgXcQ.webp),然后在加载视频的循环中使用如下函数检查它:

        function checkMovingThumbnail(imgSrc) {
          return new Promise((resolve, reject) => {
            var img = new Image();
            img.onload = function() {
              resolve();
            };
            img.onerror = function() {
              reject();
            };
            img.src = imgSrc;
          });
        }
        

        然后:

        checkMovingThumbnail('/assets/' + videoID + '.webp').then(function() {
          //Load the thumbnail on mouseover
        }
        

        通过这种方式,您可以使用相同的脚本来加载所有视频,无论您是否下载了所有移动的缩略图——此外,您还可以检查 webp 支持,以缓解 Safari 和 IE 的问题。

        【讨论】:

          【解决方案6】:

          您可以使用 FRAMES 缩略图来创建简短的动画缩略图:

          frame1: https://i.ytimg.com/vi/<YouTube_Video_ID_HERE>/1.jpg
          frame2: https://i.ytimg.com/vi/<YouTube_Video_ID_HERE>/2.jpg
          frame3: https://i.ytimg.com/vi/<YouTube_Video_ID_HERE>/3.jpg
          

          【讨论】:

          • 你能解释一下这是什么或它来自哪里吗?
          • Youtube 自动为每个上传的视频选择 3 帧并将其存储在 3 张图像中。这是获取它们的一种方式。
          • 哦,上传视频时生成的 3 个缩略图?不知道这些会可用,因为据我所知,它们并没有真正在其他任何地方使用。
          • 这些都是小尺寸,有没有办法获得更高的分辨率?
          猜你喜欢
          • 2014-08-05
          • 2011-06-03
          • 2011-10-09
          • 1970-01-01
          • 1970-01-01
          • 2017-02-11
          • 2013-09-11
          • 2013-09-19
          • 2020-08-27
          相关资源
          最近更新 更多