如何在不使用 safari 或 iOS 上的海报的情况下获取 HTML5 视频缩略图?

Posted

技术标签:

【中文标题】如何在不使用 safari 或 iOS 上的海报的情况下获取 HTML5 视频缩略图?【英文标题】:How to get HTML5 video thumbnail without using poster on safari or iOS? 【发布时间】:2017-05-06 11:13:17 【问题描述】:

我嵌入了 mp4 格式的 html5 视频。如何在不使用“海报”属性的情况下获得像海报这样的缩略图。这个问题出现在 Safari 和 ios 上。我添加了类似下面提到的代码的视频。

<video height=350 id='TestVideo' webkit-playsinline><source src='test.mp4' type=video/mp4></video>

在 Chrome、IE、Firefox 上,视频的第一帧以缩略图形式出现,但在 Safari 和 iOS 上不出现。

【问题讨论】:

你能添加你的代码吗? 有一个自动播放的解决方案,但它只适用于IOS 10+ 【参考方案1】:

只需在video标签中添加preload="metadata"并在url src处设置#t=0.1,它就会得到你视频0.1s的帧作为缩略图

但是,这种方案的缺点是当你点击播放视频时,它总是从 0.1s 开始

<video preload="metadata" controls>
    <source src="video.mp4#t=0.1" type="video/mp4">
</video>

【讨论】:

这种方法效果很好。我在 iOS 上使用它没有问题。在 Chrome Androïd 和桌面上测试,到目前为止没有问题。谢谢你的想法。 如果您使用 blob.url 作为视频 src,此方法不起作用 这个聪明的方法完美无缺,解决了我长期存在的问题,即在剪辑完成加载后显示原生缩略图!太感谢了!它还根据需要替换了海报属性,并且 0.1s 偏移量在我的用例中并不重要,因此这对于我的用例来说是一个完美的解决方案。 很棒的推荐! 请注意,您也可以使用较小的偏移量,例如0.001 (1ms),它仍然会显示缩略图。【参考方案2】:

如果您想在不存储服务器端图像的情况下执行此操作,虽然有点笨拙......使用画布记录视频的第一帧,然后将其覆盖在视频元素上。可以使用画布的 URL 作为海报的来源(例如 video.poster = c.toDataURL();),但这需要正确的 CORS 设置(不确定视频是否在您自己的服务器上,以及您是否可以控制它,所以采取了最安全的选择)。如果视频被正确编码以进行流式传输,这将最有效(因此 MOOV atom 位于视频的前面,否则绘制覆盖层会很慢 - 有关更多详细信息,请参阅 this answer)

HEAD 包含视频和叠加层的样式(您需要调整大小和位置以适合您的应用程序)

<head>
  <style>
    video_box
      float:left;
    
    #video_overlays 
      position:absolute;
      float:left;
      width:640px;
      min-height:264px;
      background-color: #000000;
      z-index:300000;
    
  </style>
</head>

BODY 中,您将需要div 用于覆盖和视频。覆盖 div 有一个 onclick 处理程序来隐藏覆盖并开始播放视频

<div id="video_box">
  <div id="video_overlays" onclick="this.style.display='none';document.getElementById('video').play()"></div>

    <video id="video" controls  >
      <source src="BigBuck.mp4" type='video/mp4'>
    </video>

  </div>
</div>

最后,您将需要代码来加载视频、查找第一帧并将视觉对象加载到画布中,然后将其插入叠加层

<script>

function generateOverlay() 
    video.removeEventListener('seeked',generateOverlay);  / tidy up the event handler so it doesn't redraw the overlay every time the user manually seeks the video
    var c = document.createElement("canvas");
    var ctx = c.getContext("2d");
    c.width = 640;
    c.height = 264;
    ctx.drawImage(video, 0, 0, 640, 264); // take the content of the video frame and place in canvas
    overlay.appendChild(c); // insert canvas into the overlay div


    // identify the video and the overlay
    var video = document.getElementById("video");
    var overlay = document.getElementById("video_overlays");

    // add a handler that when the metadata for the video is loaded it then seeks to the first frame
    video.addEventListener('loadeddata', function() 
        this.currentTime = 0;
    , false);

    // add a handler that when correctly seeked, it generated the overlay
    video.addEventListener('seeked', function() 
    // now video has seeked and current frames will show
    // at the time as we expect
        generateOverlay();
    , false);

    // load the video, which will trigger the event handlers in turn
    video.load();

</script>

【讨论】:

【参考方案3】:

这有点晚了,但我们遇到了同样的情况。我不能使用“静音”属性,因为我的视频是播客。这是我想出的,我希望与未来的访客分享。我所做的是将视频加载到 body 标签中,绘制一个画布,检索为 base64 并作为背景图像应用于视频。

由于我的视频的高度应固定为 150 像素,因此我计算了纵横比,以便实际视频的任何高度和宽度都将调整为 150 像素的高度和动态宽度。

$('body').append('<video class="checkmeload" style="position:absolute;top:-10000px" controls preload="auto" playsinline src="//src-here"><source src="//src-here" type="//videotype-here"></video>');

$('body').find('.checkmeload').on('loadeddata', function()
    var video = $('.checkmeload');

    var canvas = document.createElement('canvas');
    aspectratio = (video[0].videoWidth / video[0].videoHeight);
    newwidth = (150 * aspectratio);
    canvas.width = newwidth;
    canvas.height = 150;

    var context = canvas.getContext('2d');
    context.drawImage(video[0], 0, 0, canvas.width, canvas.height);
    var dataURI = canvas.toDataURL('image/jpeg');

    $('body').find('.checkmeload').remove(); 

    $('#myvideo').css('background-image','url("'+dataURI +'")');
);

【讨论】:

【参考方案4】:

来源:How to set the thumbnail image on HTML5 video?

这对我有用:

<img src="thumbnail.png"  />
/* code for the video goes here */

现在使用 jQuery 播放视频并将图像隐藏为

$("img").on("click", function() 
  $(this).hide();
  // play the video now..
)

【讨论】:

谢谢,但我不想为视频使用单独的图像或海报,因为视频是动态的,我不想通过添加单独的图像来返工。你有什么想法将视频的第一帧设置为海报。 不可以用哪个插件? 它叫 popcorn.js 看看这两个链接:***.com/questions/7323053/…***.com/questions/22607572/… 你找到解决办法了吗? 谢谢你,我会试试 popcorn.js。【参考方案5】:

在视频网址末尾添加#t=0.001

https://muffinman.io/blog/hack-for-ios-safari-to-display-html-video-thumbnail/

【讨论】:

虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review

以上是关于如何在不使用 safari 或 iOS 上的海报的情况下获取 HTML5 视频缩略图?的主要内容,如果未能解决你的问题,请参考以下文章

海报属性在 iPhone 5 上的视频标签中不起作用

在不打开新标签的情况下从本机应用返回 Safari - iOS - Safari

图像无法在 iOS 上的 Safari 上加载

如何在 iOS 上的 Safari 中滚动时监控滚动位置?

检查 IOS 上的 Facebook Connect 会话

在 iOS 上的 Safari 中全屏打开网页