从视频中提取海报图像

Posted

技术标签:

【中文标题】从视频中提取海报图像【英文标题】:Extract poster image from video 【发布时间】:2015-11-22 14:44:34 【问题描述】:

我想从视频文件中提取我的海报图像,并希望在网页上使用该图像。

我的技术栈由spring mvc、hibernate、jpa、jQuery、jsp、html5、css3组成。

谁能指导我如何做到这一点?

【问题讨论】:

【参考方案1】:

取决于你想在哪里进行处理,这里有几个选项

预处理选项 如果您对视频进行预处理,您可以使用 Grunt 生成不同的视频格式/大小/图像,https://github.com/sjwilliams/grunt-responsive-videos

客户端选项 如果您想在客户端生成它,只要您托管自己的视频文件,就可以使用 Popcorn.capture 之类的东西,否则您将遇到同源策略问题。见https://github.com/rwaldron/popcorn.capture

服务器端选项 如果你想在服务器端生成它,Humble-Video https://github.com/artclarke/humble-video 是一个处理视频文件的 Java 框架

【讨论】:

我正在尝试使用 Popcorn.capture 处理一些示例视频。但很难使用它。【参考方案2】:

按照@sjm 的建议,我使用了 Popcorn.capture 并尝试了以下代码来解决问题

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8" />
    <title>Popcorn.capture.js Functional Examples</title>
    <script src="http://cdn.popcornjs.org/code/dist/popcorn.min.js"></script>
    <script src="../src/popcorn.capture.js"></script>
</head>
<body  onload="myFunction()">

  <div id="unmoved-fixture">
        <video   id="video-target" controls>
        <source src="assets/popcorntest.mp4"></source>
        <source src="assets/popcorntest.ogv"></source>
        <source src="assets/popcorntest.webm"></source>
        </video>
  </div>
<pre>



</pre>

<script>
function myFunction() 
   var $pop = Popcorn( "#video-target" ),
    poster;

    $pop.capture(
    at: 10
    );


</script>

</body>
</html>

以上代码从视频的第 10 秒捕获图像并为视频创建海报图像。

你可以从https://github.com/rwaldron/popcorn.capture/tree/master/src获取popcorn.capture.js

【讨论】:

【参考方案3】:

可以使用 html5 和 canvas

Github here

查看实际操作here

更多细节在这里 - CREATING SCREENGRABS FROM HTML5 VIDEO WITH CANVAS

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Taking screengrabs from video in Canvas</title>
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<style>
  *margin:0;padding:0;font-size:15px;font-family:calibri,arial,sans-serif
  footer,section,headerdisplay:block;
  bodypadding:2em;background:#666;color:#fff;
  h1font-size:24px;margin:10px 0;
  h2font-size:18px;margin:10px 0;color:lime;
  canvasdisplay:block;border:2px solid #000;
  #video,#canvasfloat:left;padding-right:10px;
  #videowidth:640px;
  #save lilist-style:none;margin:0;padding:0
  #saveclear:both;padding:10px 0;overflow:auto;
  #save imgfloat:left;padding-right:5px;padding-bottom:5px;
  footer acolor:lime;
  footer pmargin:5em 0 1em 0;padding:1em 0;border-top:1px solid #999
</style>
</head>
<body>
  <header><h1>Taking screengrabs from video in Canvas (Chrome, Mozilla, Opera, Safari - maybe IE (got no windows))</h1></header>
  <section>
    <p>Simply play the video. Every time you pause, you can see the screenshot on the right. Click the screenshot to store it in your collection below.</p>
<div id="video">
  <h2>The Video:</h2>
  <video controls>
    <source src="meetthecubs.mp4" type="video/mp4"></source>
    <source src="meetthecubs.webm" type="video/webm"></source>
  </video>
</div>
<div id="canvas">
  <h2>Preview (click to store images below):</h2>
  <canvas></canvas>
</div>
<div id="save">
  <h2>Your saved images:</h2>
  <ul></ul>
</div>
</section>
<footer>
  <p>Written by 
    <a href="http://wait-till-i.com/">Chris Heilmann</a> - 
    <a href="http://twitter.com/codepo8">@codepo8</a>
  </p>
</footer>
<script>

(function()

  var v = document.querySelector('video'),
      n = document.querySelector('source').src.replace(/.*\/|\..*$/g,''),
      c = document.querySelector('canvas'),
      save = document.querySelector('#save ul'),
      ctx = c.getContext('2d');

  v.addEventListener('loadedmetadata',function(ev)

    var ratio = v.videoWidth/v.videoHeight,
        w = 400,
        h = parseInt(w / ratio, 10),
        time = 0,
        img = null,
        li = null;

    c.width = w;
    c.height = h + 40;

    v.addEventListener('timeupdate',function(ev)
      if(v.paused)
        ctx.fillStyle = 'rgb(0, 0, 0)';
        ctx.fillRect(0, 0, w, h);
        ctx.drawImage(v, 0, 40, w, h);
        ctx.font = '20px Calibri';
        ctx.fillStyle = 'lime';
        ctx.fillText(n, 5, 20);
        time = format(v.currentTime);
        ctx.fillStyle = 'white';
        ctx.fillText(time, 395 - ctx.measureText(time).width, 20);
      
    ,false);

    c.addEventListener('click',function(ev)
      li = document.createElement('li');
      img = document.createElement('img');
      li.appendChild(img);
      save.appendChild(li);
      img.src = ctx.canvas.toDataURL('image/png');
    ,false);

  ,false);

  function format(time)
    var hours = parseInt((time / 60 / 60) % 60, 10),
        mins = parseInt((time / 60) % 60, 10),
        secs = parseInt(time, 10) % 60,
        hourss = (hours < 10 ? '0' : '') + parseInt(hours, 10) + ':',
        minss = (mins < 10 ? '0' : '') + parseInt(mins, 10) + ':',
        secss  = (secs < 10 ? '0' : '') +(secs % 60),
        timestring = ( hourss !== '00:' ? hourss : '' ) + minss + secss;
    return timestring;
  ;
)();
</script>
</body>
</html>

确保您的视频源正确。

【讨论】:

如何删除上下文从视频中生成图像的 SecurityError 。我尝试将此添加到代码v.setAttribute('crossOrigin','anonymous');

以上是关于从视频中提取海报图像的主要内容,如果未能解决你的问题,请参考以下文章

即使海报图像的宽高比与其视频元素不同,如何用海报图像填充视频元素? [复制]

video.js 在视频末尾显示海报图像

在android上的html5视频标签中禁用默认的丑陋海报图像

不同分辨率的视频和视频预览图(海报)

暂停 HTML5 视频时显示海报图像或暂停按钮?

如何从视频中提取某一帧的图像