HTML5:在 IOS Safari 中手动“播放”画布内的视频
Posted
技术标签:
【中文标题】HTML5:在 IOS Safari 中手动“播放”画布内的视频【英文标题】:HTML5: Manually "playing" a video inside a canvas, in IOS Safari 【发布时间】:2012-06-04 11:26:13 【问题描述】:所以,这就是我想要做的: 我想将视频加载到视频元素中,但没有以“正常”方式播放。 使用根据电影的帧速率计算的定时间隔,我希望在每次迭代中
A.手动将视频推进一“帧”(或尽可能接近该帧)。 B. 将该框架绘制到画布中。
从而在画布内“播放”视频。
这里有一些代码:
<video id="mainVideo" src="urltovideo.mp4" type="video/mp4"></video>
<canvas id="videoCanvas"></canvas>
<script type="text/javascript">
var videoDom = document.querySelector("#mainVideo");
var videoCanvas = document.querySelector("#videoCanvas");
var videoCtx = null;
var interval = null;
videoDom.addEventListener('canplay',function()
// The video's framerate is 24fps, so we should move one frame each 1000/24=41.66 ms
interval = setInterval(function() doVideoCanvas(); , 41.66);
);
videoDom.addEventListener('loadeddata',function()
videoCtx = videoCanvas.getContext('2d');
);
function doVideoCanvas()
videoCtx.drawImage(videoDom,0,0);
//AFAIK and seen, currentTime is in seconds
videoDom.currentTime += 0.0416;
</script>
这在 Google Chrome 中完美运行,但在 Iphone 的 Safari 中无法运行; 视频帧根本不会被绘制到画布上。
我确定:
我挂钩的视频事件确实被触发(有“警报”并显示出来)。 我可以控制画布(执行了“fillRect
”并填满)。
[我也尝试在 drawImage 中指定尺寸 - 它没有帮助]drawImage
的视频对象是否在 Iphone Safari 中完全不适用...?
即使我设法找到捕获视频帧的方法,Iphone 的浏览器中也存在一些其他问题:
只有在视频开始播放后(以标准方式),才能访问视频的 currentTime
属性。我想也许以某种方式“隐藏它”然后捕获,但没有设法做到这一点。还想到了可能以某种方式开始播放视频然后立即停止播放;
似乎没有任何方法可以强制开始在 ios Safari 中播放视频。 video.play()
或 autoplay
似乎什么也没做。只有当用户点击视频上的“播放圈”时,视频才会开始播放(占据整个屏幕,与 iPhone 浏览器上的视频通常一样)。
视频播放后 - currentTime
属性确实会被转发。关于视频本身。当您暂停视频并返回正常的 html 页面时 - 您可以看到视频元素上的帧发生变化。虽然,在一个缓慢的阶段(不像谷歌浏览器,它的速度似乎足够平滑,让它看起来像是在播放)——在 iphone 中它看起来可能是每秒 2-3 帧的速度。即使我尝试更改间隔时间也保持不变,我猜iPhone上的浏览器可以处理的最小时间限制。
“额外问题” :) - 当视频元素上的帧从事件开始时 - 圆形“播放按钮”在视频元素上可见(因为它实际上不是“播放”)。有没有办法把它隐藏起来,让它不可见?
这已经在运行 IOS 5 的 Iphone 3GS(同时支持 3G 和 Wifi)和 Iphone 4 上进行了测试,结果与描述的相同。
【问题讨论】:
【参考方案1】:不幸的是,我没有 iOS 设备来测试这一点,但我认为您不需要以您尝试使用 currentTime
属性的方式实际捕获视频帧。通常的过程是这样的:
-
创建不带控件的视频元素(省略
controls
属性)
隐藏元素
在播放视频时,每隔一段时间将其绘制到画布上
正如您所发现的,iOS 设备不支持 HTML5 视频(甚至音频)的自动播放,但您可以创建一个单独的控件来使用 play()
方法开始播放视频。
这种方法应该可以解决播放按钮可见的问题,因为在这种情况下,您实际上是在播放视频。
【讨论】:
感谢您的回复和提示!我遇到过这个文档:developer.apple.com/library/safari/#documentation/AudioVideo/… 其中有一行说明:“注意:iOS 目前不支持将视频作为画布 drawImage() 方法的源。” :\ 但另一种选择是将视频转换为图像序列 - 并在画布上使用它们! 很好地找到了 Yuval,知道这真的很有用。您应该添加这是您问题的答案并接受它。 目前android Chrome和Android Browser似乎也缺乏类似的功能。【参考方案2】:我不相信在 iOS 上会调用 loadeddata
事件,请尝试使用 loadedmetadata
事件。我还发现在 iOS 上设置videoDom.src
后需要调用videoDom.load()
方法。
对于我的用例,我需要在 seeked
事件之后执行“dRAF”(双重 requestAnimationFrame),以确保实际绘制到画布而不是透明矩形。
尝试类似:
videoDom.onloadedmetadata = () =>
videoCanvas.height = videoDom.videoHeight
videoCanvas.width = videoDom.videoWidth
videoDom.currentTime = 0
videoDom.onseeked = () =>
// delay the drawImage call, otherwise we get an empty videoCanvas on iOS
// see https://***.com/questions/44145740/how-does-double-requestanimationframe-work
window.requestAnimationFrame(() =>
window.requestAnimationFrame(() =>
videoCanvas.getContext('2d').drawImage(videoDom, 0, 0, videoCanvas.width, videoCanvas.height)
videoDom.currentTime += 0.0416
)
)
videoDom.load()
来自this gist
【讨论】:
这是否适用于使用 VideoJS 或类似工具的实时网络摄像头流? 我不知道,试试看。以上是关于HTML5:在 IOS Safari 中手动“播放”画布内的视频的主要内容,如果未能解决你的问题,请参考以下文章