封装视频截取封面函数:
/**
* 视频屏幕截图
* @param {object} file 视频文件对象
* @param {object} options 配置项
* @param {function} options.error 错误回调
* @param {function} options.success 成功回调
* @param {object} wrapper 可选 dom对象 默认body
*/
function videoScreenshot(file, options, wrapper) {
options = options || {};
options.error = options.error || $.noop;
options.success = options.success || $.noop;
wrapper = wrapper || document.body;
var videoUrl, video, canvas, duration, interval, currentTime = 0,
imgs = [],
result = {};
if(navigator.userAgent.indexOf('Chrome') < 0 && navigator.userAgent.indexOf('Safari') < 0) {
options.error('浏览器不支持视频截图,请使用 Chrome 浏览器!');
} else {
try {
videoUrl = (typeof file === 'string') ? file : window.URL.createObjectURL(file);
video = document.createElement('video');
canvas = document.createElement('canvas');
video.style.visibility = 'hidden';
wrapper.appendChild(video);
video.src = videoUrl;
video.muted = true;
video.addEventListener('seeked', videoSeeked, false);
var ctx = canvas.getContext("2d");
var k = 20;
var timeoutInterval = setInterval(function() {
if(!k) {
clearInterval(timeoutInterval);
options.error('视频截图失败')
} else {
if(video.readyState >= 1) {
clearInterval(timeoutInterval);
if(video.videoWidth == 0 || video.videoHeight == 0 || video.duration == 0) {
options.error('视频截图失败');
return
}
// 封面尺寸 375x200,使用2倍图
var scale = Math.max(750 / video.videoWidth, 400 / video.videoHeight);
scale > 1 && (scale = 1);
video.width = canvas.width = result.width = Math.floor(video.videoWidth * scale);
video.height = canvas.height = result.height = Math.floor(video.videoHeight * scale);
duration = video.duration;
interval = duration / 10;
video.currentTime = currentTime;
}
k--
}
}, 100);
function videoSeeked() {
try {
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
imgs.push(canvas.toDataURL("image/jpeg"));
if(imgs.length == 1 && isDrawSuccess()) {
options.error('视频截图失败');
return;
}
if(imgs.length == 10) {
imgs.splice(0, 1);
play();
return;
}
ctx.clearRect(0, 0, canvas.width, canvas.height);
currentTime += interval;
video.currentTime = currentTime
} catch(a) {
options.error('视频截图失败')
}
}
function videoPlaying() {
setTimeout(function() {
video.pause();
video.removeEventListener("playing", videoPlaying);
if(video.currentTime < video.duration) {
result.imgs = imgs;
options.success(result);
destroy();
} else {
options.error('视频截图失败');
}
}, 50)
}
function isDrawSuccess() {
var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
return imageData.data[imageData.data.length - 1] == 0 ? true : false;
}
function play() {
var time = duration - .5;
video.removeEventListener("seeked", videoSeeked);
video.addEventListener("playing", videoPlaying, false);
video.currentTime = time;
video.play()
}
} catch(err) {
options.error(err);
}
}
// 销毁
function destroy() {
try {
wrapper.removeNode(video);
window.URL.revokeObjectURL(videoUrl);
} catch(err) {}
}
}
调用函数:
videoScreenshot(file, {
error: function(err) {
toastr.error(err);
},
success: function(data) {
$.each(data.imgs, function(i, item) {
//在此处添加到Dom对象里
});
}
});