注意视频必须播放才能截取到视频帧作为封面,可以监听播放进度来截取封面。不播放截取出来是黑屏,你可以监听vedio的timeupdate事件在事件处理中去完成截图。另外注意讲vedio标签的crossOrigin属性设置为"anonymous",防止跨域无法截取
/**
*@desc: base64转blob
*@param {WindowBase64} dataURI base64
*@return {Blob}
*/
export const dataURItoBlob = (dataURI: string) => {
const byteString = atob(dataURI.split(',')[1]);
const ab = new ArrayBuffer(byteString.length);
const ia = new Uint8Array(ab);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ia], { type: 'image/png' });
};
/**
*@desc: blob 转文 件对象
*@param {Blob} newBlob blob格式文件
*@param {String} fileName 文件名
*@param {String} fileType 文件类型
*@return {File}
*/
export const blobToFile = (
newBlob: Blob,
fileName: string,
fileType: string = 'image/png',
) => {
return new File([newBlob], fileName, {
type: fileType,
lastModified: Date.now(),
});
};
/**
*@desc: base64 转 file
*@param {String} src 图片base64
*@param {String} fileName 文件名
*@return {void}
*/
export const dataURIToFile = (src: string, fileName: string) => {
const blob = dataURItoBlob(src);
const file = blobToFile(blob, fileName);
return file;
};
/**
*@desc: 截取video画面帧 返回截取的图片(File文件对象格式以及base64格式) (实验结果必须在视频播放之后截取成功才有保证)
*@param {HTMLVideoElement} video video标签节点
*@param {String} fileName 文件名
*@param {string} imageType 图片格式
*@return {Object<{ file: File, src: WindowBase64 }>} res={file, src} 结果对象file是图片文件对象格式 src base64图片格式
*/
export const captureVideoPoster = (
video: HTMLVideoElement,
fileName: string,
imageType = 'image/png',
) => {
if (!video) return;
const width = video.videoWidth;
const height = video.videoHeight;
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d') as CanvasRenderingContext2D;
canvas.width = width;
canvas.height = height;
ctx.drawImage(video, 0, 0, width, height);
const src = canvas.toDataURL(imageType);
const file = dataURIToFile(src, fileName);
return {
src,
file,
};
};