在画布上基本加载和播放视频
画布可用于显示来自各种来源的视频。此示例显示如何将视频作为文件资源加载,显示它并在屏幕播放/暂停切换上添加简单的单击。
此 stackoverflow 自回答问题如何使用 HTML5 canvas 标签显示视频显示以下示例代码。
只是一个图像
就画布而言,视频只是一个图像。你可以像任何图像一样绘制它。不同的是视频可以播放和有声音。
获取画布和基本设置
// It is assumed you know how to add a canvas and correctly size it.
var canvas = document.getElementById("myCanvas"); // get the canvas from the page
var ctx = canvas.getContext("2d");
var videoContainer; // object to hold video and associated info
创建和加载视频
var video = document.createElement("video"); // create a video element
video.src = "urlOffVideo.webm";
// the video will now begin to load.
// As some additional info is needed we will place the video in a
// containing object for convenience
video.autoPlay = false; // ensure that the video does not auto play
video.loop = true; // set the video to loop.
videoContainer = { // we will add properties as needed
video : video,
ready : false,
};
与图像元素不同,视频不必完全加载以在画布上显示。视频还提供了许多可用于监控视频状态的额外事件。
在这种情况下,我们希望知道视频何时可以播放。oncanplay
意味着足够的视频已加载播放其中一些,但可能还不足以播放到最后。
video.oncanplay = readyToPlayVideo; // set the event to the play function that
// can be found below
或者你也可以使用 oncanplaythrough
,它会在足够的视频加载时触发,以便可以播放到最后。
video.oncanplaythrough = readyToPlayVideo; // set the event to the play function that
// can be found below
仅使用其中一个 canPlay 事件而不是两者。
can play 事件(相当于图像 onload)
function readyToPlayVideo(event){ // this is a referance to the video
// the video may not match the canvas size so find a scale to fit
videoContainer.scale = Math.min(
canvas.width / this.videoWidth,
canvas.height / this.videoHeight);
videoContainer.ready = true;
// the video can be played so hand it off to the display function
requestAnimationFrame(undateCanvas);
}
显示
视频不会在画布上播放。你需要为每个新帧绘制它。由于很难知道确切的帧速率以及它们何时出现,因此最好的方法是将视频显示为以 60fps 运行。如果帧速率较低,那么 w 只渲染相同的帧两次。如果帧速率更高,那么没有什么可以看到额外的帧,所以我们只是忽略它们。
视频元素只是一个图像元素,可以像任何图像一样绘制,你可以缩放,旋转,平移视频,镜像,淡化,剪辑和仅显示部分,使用全局复合模式第二次绘制它添加像闪电,屏幕等 FX。
function updateCanvas(){
ctx.clearRect(0,0,canvas.width,canvas.height); // Though not always needed
// you may get bad pixels from
// previous videos so clear to be
// safe
// only draw if loaded and ready
if(videoContainer !== undefined && videoContainer.ready){
// find the top left of the video on the canvas
var scale = videoContainer.scale;
var vidH = videoContainer.video.videoHeight;
var vidW = videoContainer.video.videoWidth;
var top = canvas.height / 2 - (vidH /2 ) * scale;
var left = canvas.width / 2 - (vidW /2 ) * scale;
// now just draw the video the correct size
ctx.drawImage(videoContainer.video, left, top, vidW * scale, vidH * scale);
if(videoContainer.video.paused){ // if not playing show the paused screen
drawPayIcon();
}
}
// all done for display
// request the next frame in 1/60th of a second
requestAnimationFrame(updateCanvas);
}
基本播放暂停控制
现在我们已经加载并显示了视频我们需要的是播放控件。我们将其作为屏幕上的单击切换播放。播放视频并且用户点击视频时,视频会暂停。暂停时,点击恢复播放。我们将添加一个功能来使视频变暗并绘制一个播放图标(三角形)
function drawPayIcon(){
ctx.fillStyle = "black"; // darken display
ctx.globalAlpha = 0.5;
ctx.fillRect(0,0,canvas.width,canvas.height);
ctx.fillStyle = "#DDD"; // colour of play icon
ctx.globalAlpha = 0.75; // partly transparent
ctx.beginPath(); // create the path for the icon
var size = (canvas.height / 2) * 0.5; // the size of the icon
ctx.moveTo(canvas.width/2 + size/2, canvas.height / 2); // start at the pointy end
ctx.lineTo(canvas.width/2 - size/2, canvas.height / 2 + size);
ctx.lineTo(canvas.width/2 - size/2, canvas.height / 2 - size);
ctx.closePath();
ctx.fill();
ctx.globalAlpha = 1; // restore alpha
}
现在播放暂停事件
function playPauseClick(){
if(videoContainer !== undefined && videoContainer.ready){
if(videoContainer.video.paused){
videoContainer.video.play();
}else{
videoContainer.video.pause();
}
}
}
// register the event
canvas.addEventListener("click",playPauseClick);
摘要
使用画布播放视频非常容易,实时添加效果也很容易。然而,格式有一些限制,你可以如何玩和寻找。MDN HTMLMediaElement 是获取视频对象的完整依据的地方。
在画布上绘制图像后,你可以使用 ctx.getImageData
访问其包含的像素。或者你可以使用 canvas.toDataURL
拍摄静止图像并下载它。 (仅当视频来自受信任的来源且不会污染画布时)。
请注意,如果视频有声音,那么播放它也会播放声音。
快乐的视频。