使用js截取视频指定秒数的图片
点击按钮,选择本地视频后,截取指定秒数的图片
运行结果如下图:
直接上代码:
1、html代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
.sdddq {
font-size: 20px;
height: 35px;
width: 150px;
}
.sssd {
border-left-width: 1px;
border-left-style: solid;
border-left-color: #999;
text-align: center;
}
.bgColor {
filter: progid:DXImageTransform.Microsoft.Gradient(GradientType=0, StartColorStr='#22000000', EndColorStr='#33FFFFFF');
background-image: linear-gradient(to top, rgba(255, 255, 255, 0.1) 0%, rgba(0, 0, 0, 0.2) 80%, rgba(0, 0, 0, 0.4) 100%, #FFFFFF 100%);
}
#video {
width: 35%;
}
</style>
</head>
<body>
<!-- 视频播放器-->
<center>
<video id="video" src="" controls="controls" loop="loop" autoplay style="margin: auto;" preload="auto"
autoplay="autoplay" style="width: 35%"></video>
</center>
<!-- 视频地址 按钮-->
<center>
<p id="address"></p>
<p><br>
<marquee direction=left id="address">操作说明:输入要截取的秒数</marquee><br>
<input class="sdddq" id="inp" value="0"></input>
</p><br /></p>
</center>
<br>
<div style="text-align: center;" style="margin-top:30%;">
<input id="file" type="file" value="" onchange="look()">
<br /><br />
<button type="button" id="btn">开始截图</button>
<button type="button" onclick="xiazai()">下载图片</button>
</div>
<br>
<center>
<img id="img" style="margin: 0 auto; width: 35%">
</center>
</body>
<!-- 引入js文件-->
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="assets/js/indexjs.js"></script>
<script type="text/javascript">
var vid = document.getElementById("video");
var shi;
vid.onloadedmetadata = function() {
//console.log('metadata loaded!');
//console.log(vid.duration); //打印时长
shi = parseInt(vid.duration);
document.getElementById("address").innerHTML = "最大时长:" + shi + ", 您只能输入0到" + shi + "秒之间的秒数";
};
//使用事件监听方式捕捉事件
video.addEventListener("timeupdate", function() {
var timeDisplay;
//用秒数来显示当前播放进度
timeDisplay = Math.floor(video.currentTime);
console.log(Math.floor(video.currentTime));
//document.getElementById("current").innerHTML = timeDisplay+"秒";
shuru = document.getElementById('inp').value = timeDisplay;
}, false);
function look() {
let file = document.getElementById('file').files[0];
let url1 = URL.createObjectURL(file);
document.getElementById("video").src = url1;
}
function xiazai() {
var img = document.getElementById('img'); // 获取要下载的图片
var url = img.src; // 获取图片地址
var a = document.createElement('a'); // 创建一个a节点插入的document
var event = new MouseEvent('click') // 模拟鼠标click点击事件
a.download = 'beautifulGirl' // 设置a节点的download属性值
a.href = url; // 将图片的src赋值给a节点的href
a.dispatchEvent(event)
}
// 绑定下载
document.getElementById("btn").onclick = function() {
let file = document.getElementById('file').files[0];
let srcmp4 = URL.createObjectURL(file);
videoCover(srcmp4, null, null);
}
/**
* @param {String} src 视频链接
* @param {Number} width 视频容器播放的宽
* @param {Number} height 视频容器播放的高
* @param {Number} second 需要截图视频的帧数, 单位秒
* @param {Number} bufftime 视频加载缓冲的时长, 单位秒
*/
function videoCover(src, width, height, second, bufftime) {
const canvas = document.createElement('canvas'); // 创建canvas 用来截图
const video = document.createElement('video'); // 创建video 用来存放被截图的视频
const img = document.getElementById('img') // 用来显示截图的图片效果
const a = document.getElementById('a') // 用来自动下载图片保存到本地
video.setAttribute('crossOrigin', 'anonymous'); // 支持跨域
document.body.appendChild(video); // 把视频插入页面里
video.setAttribute('src', src); // 设置video路径
video.style.visibility = "show" // 视频不显示
// 监听视频播放
video.onplay = function() {
// 暂停
video.pause()
// 指定播放时间 1代表视频的第一秒帧 可以浮点数
var zhenshu = document.getElementById('inp').value;
video.currentTime = second || zhenshu;
// 设置视频容器的宽高播放 如果设置一项会自动按照比例生成 这里是高固定,宽自动
video.height = height || video.clientHeight;
// 设置canvas的截图大小,如果没给定宽高值会取视频容器的宽高
canvas.width = width || video.clientWidth;
canvas.height = height || video.height;
/*
使用定时器为了视频跳转到某一帧的时候视频进行缓冲,等视频加载完成之后进行截图
如果截图是黑屏说明视频未加载完成就开始截屏了
*/
setTimeout(() => {
// 使用canvas进行绘画 视频画面
canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
// 获取到base64图片 png格式
const IMG_TYPE = "png"
const b64 = canvas.toDataURL('image/' + IMG_TYPE);
// 展示到页面上给img的src赋值
document.getElementById('img').setAttribute('src', b64);
// // 模拟点击自动下载图片
// document.getElementById('a').click()
// 移除视频容器
document.body.removeChild(video);
}, bufftime * 1000 || 3000);
}
// 当视频准备就绪的时候
video.onloadeddata = () => {
// 播放它
video.play()
}
}
</script>
</html>
indexjs.js代码
(function($){
function getRandom(n){
return Math.floor(Math.random()*n+1)
}
var inputp={
indexInput:0,
addNew:function(obj,stepNum){
this.initNew(obj,stepNum);
this.indexInput++;
},
getDigit:function(val,num){
var digitNum=0;
if(num.toString().split(".")[1]){
digitNum=num.toString().split(".")[1].length;
}
if(digitNum>0){
val=val.toFixed(digitNum);
}
return val;
},
initNew:function(obj,stepNum){
var width=obj.width();
var height=obj.height();
var height1=height;
var _root = this;
width+=3;
//height+=0;
obj.css("border-style","none");
obj.css("border-width","0px");
obj.css("width",width-height1*2-7);
obj.css("text-align","center");
obj.css("outline","none");
obj.css("vertical-align","middle");
obj.css("line-height",height+"px");
obj.wrap("<div id='"+obj.attr('id')+"T' style='overflow:hidden;width:"+width+"px;height:"+height+"px;border: 1px solid #CCC;'></div>");
obj.before("<div id='"+obj.attr('id')+"l' onselectstart='return false;' style='-moz-user-select:none;cursor:pointer;text-align:center;width:"+height1+"px;height:"+height1+"px;line-height:"+height1+"px;border-right-width: 1px;border-right-style: solid;border-right-color: #CCC;float:left'>-</div>");
obj.after("<div id='"+obj.attr('id')+"r' onselectstart='return false;' style='-moz-user-select:none;cursor:pointer;text-align:center;width:"+height1+"px;height:"+height1+"px;line-height:"+height1+"px;border-left-width: 1px;border-left-style: solid;border-left-color: #CCC;float:right'>+</div>");
$("#"+obj.attr('id')+"l").click(function(){
_root.leftDo(obj,stepNum);
});
$("#"+obj.attr('id')+"r").click(function(){
_root.rightDos(obj,stepNum);
});
},
leftDo:function(obj,stepNum){
var val=this.formatNum(obj.val());
val=Math.abs(val);
val-=stepNum;
val=this.getDigit(val,stepNum);
if(val<0){
val=0;
obj.val(0);
}else{
this.moveDo(obj,val,true,stepNum);
};
},
rightDos:function(obj,stepNum){
var val=this.formatNum(obj.val());
val=Math.abs(val);
val+=stepNum;
val=this.getDigit(val,stepNum);
this.moveDo(obj,val,false,stepNum);
},
moveDo:function(obj,num,isup,stepNum){
var startTop=0;
var endTop=0;
if(stepNum>=1){
if(num.toString().split(".")[1]){
num=num.toString().split(".")[0];
obj.val(num);
}
}
var num1=num;
var lens1=num.toString().length;
var divwidth=parseFloat(obj.css("font-size"))/2;
if(isup){
obj.val(num1);
var isDecimal=false;
for(i=lens1-1;i>=0;i--){
var s=num.toString();
var s1=s.substr(i,1);
var s1num=parseFloat(s1);
if(s1num!=9||isNaN(s1num)){
if(isNaN(s1num)){
//num=parseFloat(s.substr(i-1,lens1-i));
// num++;
// num=this.getDigit(num,stepNum);
}else{
num=parseFloat(s.substr(i,lens1-i));
num++;
break;
}
}
}
//num=this.getDigit(num,stepNum)
startTop=0;
endTop=-40;
}else{
var isDecimal=false;
for(i=lens1-1;i>=0;i--){
var s=num.toString();
var s1=s.substr(i,1);
var s1num=parseFloat(s1);
if(s1num!=0||isNaN(s1num)){
if(isNaN(s1num)){
//num=parseFloat(s.substr(i-1,lens1-i));
// num=this.getDigit(num,stepNum);
isDecimal=true;
}else{
num=parseFloat(s.substr(i,lens1-i));
break;
}
}
}
if(isDecimal){
num=this.getDigit(num,stepNum);
}
startTop=40;
endTop=0;
}
if($("#"+obj.attr('id')+"Num").length <1){
//background-color:#fff;
var numstr=num.toString();
var widths=divwidth*numstr.length;
var stri="<div id='"+obj.attr('id')+"sy' style='position:relative;width:0px;height:0px'><div id='"+obj.attr('id')+"Num' style='width:"+widths+"px;z-index:100;position:absolute;height:"+obj.height()+"px;top:"+startTop+"px; line-height:"+obj.height()+"px;font-family: "+obj.css("font-family")+";font-size:"+obj.css("font-size")+";'>";
for(i=0;i<numstr.length;i++){
var nums=numstr.substr(i,1);
if(nums=="."){
stri+="<div style='float:left;width:"+divwidth+"px;'> ";
}else{
stri+="<div style='float:left;width:"+divwidth+"px;background-color:#fff'>";
stri+=nums;
}
stri+="</div>";
}
stri+="</div></div>";
$("#"+obj.attr('id')+"T").prepend(stri);
var leftOff=0;
if(num1.toString().length-num.toString().length>0){
leftOff=(divwidth*(num1.toString().length-num.toString().length))/2;
}
var pz=0;
if(/msie/.test(navigator.userAgent.toLowerCase())){
pz=1;
}
if(/firefox/.test(navigator.userAgent.toLowerCase())){
pz=1;
}
if(/webkit/.test(navigator.userAgent.toLowerCase())){
}
if(/opera/.test(navigator.userAgent.toLowerCase())){
pz=1;
}
var leftpx=(obj.width()/2)+obj.height()-($("#"+obj.attr('id')+"Num").width()/2)+1+leftOff+pz;
$("#"+obj.attr('id')+"Num").css("left",leftpx);
$("#"+obj.attr('id')+"Num").animate({
top:endTop+'px'
//,opacity:0.4
},
300,
function(){
$("#"+obj.attr('id')+"sy").remove();
if(isup){
}else{
obj.val(num1);
}
});
}
}
,
formatNum:function(val){
var val=parseFloat(val);
if(isNaN(val)){
val=0;
}
return val;
},
};
$(function(){
inputp.addNew($("#inputs"),0.1);
inputp.addNew($("#inp"),1);
})
})(jQuery); // JavaScript Document
// 把16进制颜色转换成rgb格式