我一直在谷歌搜索一些答案,并且没有找到确定的答案:是否可以使用HTML5画布播放视频,并允许用户绘制此视频?在某些情况下,用例是在无限循环上播放视频,以便用户可以在特定区域绘制多个框以指示感兴趣的区域。
作为奖励(:P),如果我可以自己弄清楚如何做到这一点,那么在Drupal中如何做到这一点的任何暗示?我已经在看Canvas Field模块了,但如果你对这一点有任何提示(虽然第一个是优先级),那就太棒了!
答案 0 :(得分:3)
您可以将html5视频元素绘制到画布上。 drawImage方法接受第一个参数中的视频元素,就像图像元素一样。这将获取视频元素的当前“帧”并将其渲染到画布上。要获得流畅的视频播放,您需要反复将视频绘制到画布上。
然后您可以在画布上正常绘制,确保在每次更新视频帧后重绘所有内容。
答案 1 :(得分:1)
我最近收到了客户提出此功能的请求,但它必须是CMS友好的。该技术涉及三个重要的想法
requestAnimationFrame
绘制下一帧假设您已有视频元素,请执行以下步骤
canvas.drawImage(src, x, y)
,其中src
是视频当前帧的编辑版本; 我可以举两个这样的例子(可用于内容管理系统)
第一个是:https://jsfiddle.net/yywL381w/19/
一家名为SDL的公司制作了一个名为Media Manager的工具来托管视频。你看到的是一个jQuery插件,它从data-*
获取参数,从Media Manager Rest API发出请求,创建视频,并完全基于data*
属性添加效果。该插件可以轻松调整,以处理从其他来源调用的视频。您可以查看repo以获取有关使用情况的更多详细信息。
另一个例子是:http://codepen.io/paceaux/pen/egLOeR
这不是一个jQuery插件;它取而代之的是ES6课程。您可以创建图像/视频并应用裁剪效果:
let imageModule = new ImageCanvasModule(module);
imageModule.createCanvas();
imageModule.drawOnCanvas();
imageModule.hideOriginal();
您将在ImageCanvasModule
课程中观察此方法:
drawFrame () {
if (this.isVideo && this.media.paused) return false;
let x = 0;
let width = this.media.offsetWidth;
let y = 0;
this.imageFrames[this.module.dataset.imageFrame](this.backContext);
this.backContext.drawImage(this.media, x, y, width, this.canvas.height);
this.context.drawImage(this.backCanvas, 0, 0);
if (this.isVideo) {
window.requestAnimationFrame(()=>{
this.drawFrame();
});
}
}
该类创建了第二个画布,用于绘图。画布不可见,它只是为了保存浏览器的一些心痛。
"操纵"内容可管理的是this.imageFrames[this.module.dataset.imageFrame](this.backContext);
"框架"是存储在图像/视频上的属性(可以通过CMS中的模板输出)。这将获取imageFrame的名称,并将其作为匹配函数运行。它还在上下文中发送(因此我可以在后画布或主画布上绘图之间切换)
然后this.backContext.drawImage(this.media, x, y, width, this.canvas.height);
在后台上下文中绘制图像。
最后,它出现在主画布上this.context.drawImage(this.backCanvas, 0, 0);
,我在其中拍摄背景,并将其绘制到主画布上。因此,可见的画布具有最少量的操作。
最后,因为这是一个视频,我们想要绘制一个新的框架。所以我们有函数调用本身:
if (this.isVideo) {
window.requestAnimationFrame(()=>{
this.drawFrame();
});
这整个设置允许我们使用CMS输出data-*
属性,其中包含用户想要在图像周围绘制的帧类型。然后JavaScript生成该图像或视频的画布版本。示例标记可能如下所示:
<video muted loop autoplay data-image-frame="wedgeTop">