最近有个需求是:在一个后台审核视频的系统中,需要截取视频首帧为图片上传当封面。
经过一番搜索,发现canvas的drawImage方法可以接受video元素作为参数。那么就简单了,实现此功能的思路大致是:
- 通过
drawImage方法,将video转为canvas - 使用
canvas.toBlob将canvas转为img
代码如下:
/**
* @param {string} src 视频地址
* canvas.toBlob(),canvas.toDataURL("image/png")等方法要求canvas和video/image同域,否则会报错
* https://developer.mozilla.org/zh-CN/docs/Web/HTML/CORS_enabled_image
*/
function uploadFirstframe(src) {
//video2Canvas
function videoToCanvas(src, callback) {
var video = document.createElement("video");
video.crossOrigin = "anonymous";
video.src = src;
//第一帧加载完成事件
video.onloadeddata = function () {
var scale = 0.5; //缩放
var canvas = document.createElement("canvas");
canvas.width = video.videoWidth * scale;
canvas.height = video.videoHeight * scale;
canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
callback && callback(canvas)
};
}
videoToCanvas(src, function (canvas) {
if (canvas) {
//图片预览
var output = document.getElementById("output");
var img = document.createElement("img");
img.src = canvas.toDataURL("image/png");
output.appendChild(img);
//上传首帧图片
canvas.toBlob(function (blob) {
// 图片ajax上传
var formData = new FormData();
formData.append("file", blob, "aa.png");
axios.post(
'上传地址',
formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
});
}
});
}
uploadFirstframe('xxx');
ps:canvas.toBlob(),canvas.toDataURL("image/png")等方法要求当前页面和video地址同域,否则会报错。可以通过设置CORS、代理等方法解决。