![](/img/trans.png)
[英]How do I play back CENC-encrypted MP4 video using the HTML5 <video> tag?
[英]How do I display a video using HTML5 canvas tag
我想使用包含播放暫停功能的畫布顯示視頻,該功能允許用戶通過單擊畫布來切換播放,我還想在視頻暫停時在視頻上方繪制一個疊加層。 如何在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
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事件之一,不能同時使用兩者。
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將同一幀渲染兩次。 如果幀速率較高,則看不到多余的幀,因此我們將其忽略。
video元素只是一個圖像元素,可以像繪制任何圖像一樣進行繪制,您可以縮放,旋轉,平移視頻,對其進行鏡像,淡入淡出,對其進行裁剪和僅顯示部分,並使用全局合成模式第二次繪制兩次添加效果,如變亮,屏幕等。
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
捕捉靜止圖像並下載。 (僅當視頻來自受信任的來源並且沒有污染畫布時)。
請注意,如果視頻有聲音,則播放時也會播放聲音。
祝您拍攝愉快。
顯示視頻與顯示圖像幾乎相同。 較小的差異與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)
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; }
<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>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.