HTML-popCanvasVideo
弹出窗中利用canvas取视频帧,在特定视频偏移量处在视频帧上特定位置画矩形框。
- 矩形框的大小是相对于原视频大小,而视频要适应弹出窗尺寸,故对矩形框的位置及尺寸参数要进行相应的调整,即根据视频原始大小和最后显示大小进行等比变换。
- 利用canvas取视频帧首先要将视频嵌入界面但不能显示,利用display属性设置即可。
- 利用createElement及appendChild可创建新的界面,利用removeChild可以销毁创建的窗口,这样关闭弹窗以后video标签会被销毁,不会一直播放视频。
- 视频播放时间是浮点数,采用math函数的round或floor等操作可以延长矩形框展示的时间。
- 据说视频播放时间不准确,按帧数来画框比较准确,但是对于一个长视频来说每一帧画框数据量巨大,产生存储问题。目前代码还未加入读取记录目标框位置及时间的JSON文件或者TXT文件。代码是在前三篇基础上整合并修改的,故在此仅贴出javascript代码。
代码
//设置视频播放大小
var v_H=445;
var v_W=795;
//背景层
var sWidth,sHeight;
sWidth=document.body.offsetWidth;
sHeight=screen.height;
var bgObj=document.createElement("div");
//<div id="bgDiv" style=""></div>
bgObj.setAttribute('id','bgDiv');
bgObj.style.position="absolute";
bgObj.style.top="0";
bgObj.style.background="#777";
bgObj.style.filter="progid:DXImageTransform.Microsoft.Alpha(style=3,opacity=25,finishOpacity=75)";
bgObj.style.opacity="0.6";
bgObj.style.left="0";
bgObj.style.width=sWidth + "px";
bgObj.style.height=sHeight + "px";
bgObj.style.zIndex = "10000";
document.body.appendChild(bgObj);
//提示框层
var msgW,msgH,bordercolor;
msgW=800;
msgH=500;
bordercolor="white";
var msgObj=document.createElement("div")
//<div id="msgDiv" align="center" style=""></div>
msgObj.setAttribute("id","msgDiv");
msgObj.setAttribute("align","center");
msgObj.style.background="white";
msgObj.style.border="1px solid " + bordercolor;
msgObj.style.position = "fixed";
msgObj.style.left = 0;
msgObj.style.top = 0;
msgObj.style.right = 0;
msgObj.style.bottom = 0;
msgObj.style.margin="auto"
msgObj.style.width = msgW + "px";
msgObj.style.height =msgH + "px";
msgObj.style.textAlign = "center";
msgObj.style.font = "25px serif";
msgObj.style.lineHeight ="25px";
msgObj.style.zIndex = "10001";
msgObj.innerHTML="video ";
//提示框标题
var title=document.createElement("h4");
//<h4 id="msgTitle" align="right" style="" onclick=""></h4>
title.setAttribute("id","msgTitle");
title.setAttribute("align","right");
title.style.margin="0";
title.style.padding="3px";
title.style.background=bordercolor;
title.style.filter="progid:DXImageTransform.Microsoft.Alpha(startX=20, startY=20, finishX=100, finishY=100,style=1,opacity=75,finishOpacity=100);";
title.style.opacity="0.75";
title.style.border="1px solid " + bordercolor;
title.style.height="18px";
title.style.font="12px Verdana, Geneva, Arial, Helvetica, sans-serif";
title.style.color="black";
title.style.cursor="pointer";
title.innerHTML="close";
title.onclick=removeObj;
//去除元素
function removeObj(){
document.body.removeChild(bgObj);
document.getElementById("msgDiv").removeChild(title);
document.getElementById("vFrame").removeChild(videoFrame);
document.getElementById("cFrame").removeChild(canvasFrame);
document.getElementById("msgDiv").removeChild(frameConn);
document.getElementById("msgDiv").removeChild(canvasConn);
document.body.removeChild(msgObj);
}
//视频播放框和canvas
var frameConn = document.createElement("div");
frameConn.setAttribute("id","vFrame");
frameConn.style.display="none";
var videoFrame=document.createElement('video');
videoFrame.setAttribute("id","video");
videoFrame.src="movie.mp4";
//videoFrame.width=795;
//videoFrame.height=445;
videoFrame.controls="true";
var canvasConn=document.createElement("div");
canvasConn.setAttribute("id","cFrame");
var canvasFrame=document.createElement('canvas');
canvasFrame.setAttribute("id","c1");
canvasFrame.width=v_W;
canvasFrame.height=v_H;
//添加元素
document.body.appendChild(msgObj);
document.getElementById("msgDiv").appendChild(title);
document.getElementById("msgDiv").appendChild(frameConn);
document.getElementById("msgDiv").appendChild(canvasConn);
document.getElementById("vFrame").appendChild(videoFrame);
document.getElementById("cFrame").appendChild(canvasFrame);
{
var fircanvas=document.getElementById("c1");
var fircantxt=fircanvas.getContext("2d");
var str="click to play the video!";
fircantxt.beginPath();
fircantxt.fillStyle="black";
fircantxt.font="28px serif";
fircantxt.fillText(str,300,200);
fircantxt.closePath();
}
//功能函数
var btn = document.getElementById('c1');
var video = document.getElementById('video');
btn.addEventListener('click',function(){
if(video.paused){
video.play();
}
else{
video.pause();
}
});
var processor = {
timerCallback: function() {
if (this.video.paused || this.video.ended) {
return;
}
this.computeFrame(2,200,200,255,255);
var self = this;
setTimeout(function () {
self.timerCallback();
}, 0);
},
doLoad: function() {
this.video = document.getElementById("video");
this.c1 = document.getElementById("c1");
this.ctx1 = this.c1.getContext("2d");
var self = this;
this.video.addEventListener("play", function() {
self.width = v_W;
self.height = v_H;
//console.log( self.width,self.height);
self.timerCallback();
}, false);
},
computeFrame: function(offset,x,y,w,h) {
var dotx=x*v_W/this.video.videoWidth;
var doty=y*v_H/this.video.videoHeight;
var dotw=w*v_W/this.video.videoWidth;
var doth=h*v_H/this.video.videoHeight;
console.log("video currentTime:",Math.round(this.video.currentTime));
//console.log("video Width:",Math.round(this.video.videoWidth));
//console.log("video Height:",Math.round(this.video.videoHeight));
this.ctx1.drawImage(this.video, 0, 0, this.width, this.height);
if (Math.floor(this.video.currentTime) == offset) {
this.ctx1.lineWidth=5;
this.ctx1.strokeStyle = "rgba(255,0,0,1)";
this.ctx1.strokeRect(dotx,doty,dotw,doth);
}
return;
}
};
processor.doLoad();
}