Bli*_*n67 0 javascript canvas html5-video html5-canvas
我想使用画布显示视频,包括播放暂停功能,允许用户通过单击画布来切换播放,我还希望在视频暂停时在视频顶部绘制叠加层。这是如何在 javascript 中完成的?
画布可用于显示来自各种来源的视频。此示例展示了如何将视频加载为文件资源、显示它并在屏幕播放/暂停切换上添加一个简单的点击。
就画布而言,视频只是一个图像。您可以像绘制任何图像一样绘制它。不同之处在于视频可以播放并且有声音。
// 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
Run Code Online (Sandbox Code Playgroud)
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,
};
Run Code Online (Sandbox Code Playgroud)
与图像元素不同,视频不必完全加载即可显示在画布上。视频还提供了许多可用于监控视频状态的额外事件。
在这种情况下,我们希望知道视频何时可以播放。oncanplay意味着已经加载了足够的视频来播放其中的一些,但可能没有足够的播放到最后。
video.oncanplay = readyToPlayVideo; // set the event to the play function that
// can be found below
Run Code Online (Sandbox Code Playgroud)
或者,您可以使用oncanplaythroughwhich 将在加载足够的视频时触发,以便可以播放到最后。
video.oncanplaythrough = readyToPlayVideo; // set the event to the play function that
// can be found below
Run Code Online (Sandbox Code Playgroud)
仅使用 canPlay 事件之一,而不是同时使用两者。
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);
}
Run Code Online (Sandbox Code Playgroud)
视频不会在画布上自行播放。您需要为每个新帧绘制它。由于很难知道确切的帧速率以及它们何时发生,因此最好的方法是像以 60fps 运行一样显示视频。如果帧速率较低,那么 w 只需渲染同一帧两次。如果帧速率较高,则无法查看额外的帧,因此我们只需忽略它们。
视频元素只是一个图像元素,可以像任何图像一样绘制,您可以缩放、旋转、平移视频、镜像、淡化、剪辑并仅显示部分,使用全局复合模式第二次绘制两次添加诸如变亮、屏幕等效果。
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);
Run Code Online (Sandbox Code Playgroud)
现在我们已经加载并显示了视频,我们需要的只是播放控件。我们将其作为屏幕上的点击切换播放。当视频正在播放并且用户点击视频时,视频会暂停。暂停时,单击恢复播放。我们将添加一个使视频变暗的功能并绘制一个播放图标(三角形)
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
}
Run Code Online (Sandbox Code Playgroud)
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);
Run Code Online (Sandbox Code Playgroud)
使用画布播放视频非常容易,实时添加效果也很容易。但是,在格式、播放和搜索方式方面存在一些限制。MDN HTMLMediaElement 是获取视频对象完整引用的地方。
在画布上绘制图像后,您可以使用它ctx.getImageData来访问它包含的像素。或者您可以使用canvas.toDataURL捕捉静止图像并下载它。(仅当视频来自可信来源且不会污染画布时)。
请注意,如果视频有声音,则播放它也会播放声音。
快乐的视频。
显示视频与显示图像非常相似。细微的差异与 onload 事件以及您需要每帧渲染视频或者您只会看到一帧而不是动画帧的事实有关。
下面的演示与示例有一些细微差别。静音功能(在视频下单击静音/声音以切换声音)和一些错误检查以捕获 IE9+ 和 Edge(如果它们没有正确的驱动程序)。我会使用 IE 支持的另一种格式,但找不到公共领域的格式。
请注意 IE9+ 和 Edge 用户。您可能无法播放视频格式 WebM,因为它需要额外的驱动程序来播放视频。它们可以在tools.google.com 上找到下载 IE9+ WebM 支持
// This code is from the example document on stackoverflow documentation. See HTML for link to the example.
// This code is almost identical to the example. Mute has been added and a media source. Also added some error handling incase the media load fails and a link to fix IE9+ and Edge suport.
// Code by Blindman67.
var mediaSource = "http://video.webmfiles.org/big-buck-bunny_trailer.webm";
var muted = true;
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 = mediaSource;
// 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.
video.muted = muted;
videoContainer = { // we will add properties as needed
video : video,
ready : false,
};
// To handle errors. This is not part of the example at the moment. Just fixing for Edge that did not like the ogv format video
video.onerror = function(e){
document.body.removeChild(canvas);
document.body.innerHTML += "<h2>There is a problem loading the video</h2><br>";
document.body.innerHTML += "Users of IE9+ , the browser does not support WebM videos used by this demo";
document.body.innerHTML += "<br><a href='https://tools.google.com/dlpage/webmmf/'> Download IE9+ WebM support</a> from tools.google.com<br> this includes Edge and Windows 10";
}
video.oncanplay = readyToPlayVideo; // set the event to the play function that
// can be found below
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(updateCanvas);
// add instruction
document.getElementById("playPause").textContent = "Click video to play/pause.";
document.querySelector(".mute").textContent = "Mute";
}
function updateCanvas(){
ctx.clearRect(0,0,canvas.width,canvas.height);
// only draw if loaded and ready
if(videoContainer !== undefined && videoContainer.ready){
// find the top left of the video on the canvas
video.muted = muted;
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();
}
}
}
function videoMute(){
muted = !muted;
if(muted){
document.querySelector(".mute").textContent = "Mute";
}else{
document.querySelector(".mute").textContent= "Sound on";
}
}
// register the event
canvas.addEventListener("click",playPauseClick);
document.querySelector(".mute").addEventListener("click",videoMute)Run Code Online (Sandbox Code Playgroud)
body {
font :14px arial;
text-align : center;
background : #36A;
}
h2 {
color : white;
}
canvas {
border : 10px white solid;
cursor : pointer;
}
a {
color : #F93;
}
.mute {
cursor : pointer;
display: initial;
}Run Code Online (Sandbox Code Playgroud)
<h2>Basic Video & canvas example</h2>
<p>Code example from Stackoverflow Documentation HTML5-Canvas<br>
<a href="https://stackoverflow.com/documentation/html5-canvas/3689/media-types-and-the-canvas/14974/basic-loading-and-playing-a-video-on-the-canvas#t=201607271638099201116">Basic loading and playing a video on the canvas</a></p>
<canvas id="myCanvas" width = "532" height ="300" ></canvas><br>
<h3><div id = "playPause">Loading content.</div></h3>
<div class="mute"></div><br>Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4914 次 |
| 最近记录: |