html5:在画布内显示视频
是否可以将 html5 视频显示为画布的一部分?
基本上与在画布上绘制图像的方式相同。
context.drawVideo(vid, 0, 0);
谢谢!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
是否可以将 html5 视频显示为画布的一部分?
基本上与在画布上绘制图像的方式相同。
context.drawVideo(vid, 0, 0);
谢谢!
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(5)
我想上面的代码是不言自明的,如果不在下面发表评论,我会尝试解释上面几行代码
编辑:
这是一个专门为您准备的在线示例:)
演示
I guess the above code is self Explanatory, If not drop a comment below, I will try to explain the above few lines of code
Edit :
here's an online example, just for you :)
Demo
这是一个使用更现代语法的解决方案,并且比已经提供的解决方案更简洁:
一些有用的链接:
Here's a solution that uses more modern syntax and is less verbose than the ones already provided:
Some useful links:
使用画布显示视频
显示视频与显示图像非常相似。细微的差别与 onload 事件有关,并且您需要渲染每一帧视频,否则您只会看到一帧而不是动画帧。
下面的演示与示例有一些细微的差别。静音功能(在视频下单击静音/声音打开以切换声音)和一些错误检查,以捕获 IE9+ 和 Edge(如果它们没有正确的驱动程序)。
Keeping answers current.
user372551 之前的答案已经过时(2010 年 12 月),并且所使用的渲染技术存在缺陷。它使用
setTimeout
和 33.333..ms 的速率,setTimeout 将向下舍入到 33ms,这将导致每两秒丢帧一次,如果视频帧速率更高,可能会丢更多帧超过 30。使用setTimeout
还会引入由于 setTimeout 无法同步到显示硬件而创建的视频剪切。目前没有可靠的方法可以确定视频帧速率,除非您提前知道视频帧速率,否则您应该以浏览器上可能的最大显示刷新率显示它。 60fps
给出的最佳答案是当时(6年前)最好的解决方案,因为
requestAnimationFrame
没有得到广泛支持(如果有的话),但requestAnimationFrame
现在是跨主要的标准浏览器中,应该使用 setTimeout 来减少或删除丢帧,并防止剪切。示例演示。
加载视频并将其设置为循环播放。在您点击视频之前,该视频不会播放。再次点击将暂停。视频下方有一个静音/声音按钮。视频默认静音。
画布附加功能
使用画布渲染视频为您提供了有关显示和混合效果的附加选项。下图显示了您可以使用画布获得的一些效果。使用 2D API 提供了广泛的创意可能性。
与答案相关的图片将画布视频从灰度淡化为彩色
请参阅上面演示中的视频标题,了解上面图像中内容的归属。
Using canvas to display Videos
Displaying a video is much the same as displaying an image. The minor differences are to do with onload events and the fact that you need to render the video every frame or you will only see one frame not the animated frames.
The demo below has some minor differences to the example. A mute function (under the video click mute/sound on to toggle sound) and some error checking to catch IE9+ and Edge if they don't have the correct drivers.
Keeping answers current.
The previous answers by user372551 is out of date (December 2010) and has a flaw in the rendering technique used. It uses the
setTimeout
and a rate of 33.333..ms which setTimeout will round down to 33ms this will cause the frames to be dropped every two seconds and may drop many more if the video frame rate is any higher than 30. UsingsetTimeout
will also introduce video shearing created because setTimeout can not be synced to the display hardware.There is currently no reliable method that can determine a videos frame rate unless you know the video frame rate in advance you should display it at the maximum display refresh rate possible on browsers. 60fps
The given top answer was for the time (6 years ago) the best solution as
requestAnimationFrame
was not widely supported (if at all) butrequestAnimationFrame
is now standard across the Major browsers and should be used instead of setTimeout to reduce or remove dropped frames, and to prevent shearing.The example demo.
Loads a video and set it to loop. The video will not play until the you click on it. Clicking again will pause. There is a mute/sound on button under the video. The video is muted by default.
Canvas extras
Using the canvas to render video gives you additional options in regard to displaying and mixing in fx. The following image shows some of the FX you can get using the canvas. Using the 2D API gives a huge range of creative possibilities.
Image relating to answer Fade canvas video from greyscale to color
See video title in above demo for attribution of content in above inmage.
我从 2018 年关于
requestAnimationFrame
的答案开始。然而,它存在三个问题。play
事件会引发性能问题首先,事件侦听器可以简单地连接到执行您所需的函数处理并安排下一次对其自身的调用。无需将其包装在匿名函数中并再次调用
requestAnimationFrame
。其次,不要使用
requestAnimationFrame
。该函数会以浏览器可以处理的速度(通常为 60Hz)安排下一次对回调的调用,这会导致大量的处理工作负载。video.requestVideoFrameCallback
仅在视频进入下一帧时调用您的回调。当视频以低于 60 FPS 的速度运行时,这可以减少工作负载,并且在视频不播放时完全不需要进行任何处理,从而显着提高性能。第三,每当您将视频告诉
video.play()
时,附加到play
事件的事件侦听器就会触发,每次加载新视频时都会执行此操作进入视频元素并告诉它开始播放,以及在使用video.pause()
后恢复播放时。因此,每次视频被告知play()
时,视频都会在画布上绘制一次(加上您正在执行的任何其他处理),这会快速累积。如果您确定只播放一个要暂停和恢复的视频,您可以通过更改播放速率来切换播放/暂停,例如
video.playbackRate = !video.playbackRate
。如果您要将多个视频加载到此元素中,最好完全放弃play
事件侦听器,并在加载第一个视频时插入对step()
的手动调用开始吧。请注意,这在视频元素上有效,而不是在特定加载的视频上有效,因此您需要设置并检查标志以确保仅在加载第一个视频时调用step()
,或者在发出新请求之前取消任何活动视频帧请求(如下所示)。I started with the answer from 2018 about
requestAnimationFrame
. However, it has three problems.play
event invites performance issuesFirst, the event listener can simply be connected to the function that does your desired processing and schedules the next call to itself. There's no need to wrap it in an anonymous function with another call to
requestAnimationFrame
.Second, don't use
requestAnimationFrame
. That function schedules the next call to your callback as quickly as the browser can handle (generally 60Hz), which results in a significant processing workload.video.requestVideoFrameCallback
only calls your callback when the video proceeds to its next frame. This reduces the workload when a video runs at less than 60 FPS and obviates the need for any processing at all while the video isn't playing, significantly improving performance.Third, an event listener attached to the
play
event will fire whenever you tell the video tovideo.play()
, which you'll do every time you load a new video into the video element and tell it to start playing, and also when you resume playback after usingvideo.pause()
. Thus, the video is drawn on the canvas (plus whatever other processing you're doing) once for each time the video has been told toplay()
, which quickly accumulates.If you're sure you'll only be playing one video which you'd like to pause and resume, you can toggle play/pause by changing the playback rate, e.g.
video.playbackRate = !video.playbackRate
. If you'll be loading multiple videos into this element, it's better to forego theplay
event listener entirely and insert a manual call tostep()
when you load your first video to get that started. Note that this is active on the video element, not on specific loaded videos, so you'll need to either set and check a flag to ensure that you only callstep()
when loading the first video, or cancel any active video frame request before making a new one (shown below).您需要更新 currentTime 视频元素,然后在画布中绘制帧。不要在视频上初始化 play() 事件。
您也可以使用 for ex。这个插件 https://github.com/tstabla/stVideo
You need to update currentTime video element and then draw the frame in canvas. Don't init play() event on the video.
You can also use for ex. this plugin https://github.com/tstabla/stVideo