JS实现视频截图
截图原理:
文件上传,将视频绘制到canvas中进行截图
贴代码
base64 转成文件
下面需要用到
export const dataURLtoFile = ({ dataURL = "", filename = "" }: { dataURL: string filename: string }) => { const arr = dataURL.split(",") const mime = arr[0].match(/:(.*?);/)[1] const bstr = atob(arr[1]) let n = bstr.length const u8arr = new Uint8Array(n) while (n--) { u8arr[n] = bstr.charCodeAt(n) } return new File([u8arr], filename, { type: mime }) }
将视频绘制到canvas上
后面会用到
function drawVideoToCanvas({ videoElement, filename }: { filename: string videoElement: HTMLVideoElement }): Promise<{ file: Blob; url: string }> { return new Promise(resolve => { const canvas = document.createElement("canvas") const ctx = canvas.getContext("2d") canvas.width = videoElement.videoWidth canvas.height = videoElement.videoHeight if (!ctx) { return new Error("ctx is not defined!") } ctx.drawImage(videoElement, 0, 0, canvas.width, canvas.height) const dataURL = canvas.toDataURL("image/png") const file = dataURLtoFile({ dataURL, filename }) const url = URL.createObjectURL(file) // 实现本地预览 resolve({ file, url }) }) }
播放视频,图片截取
export function captureFrame({ file, time = 0, filename = "screenshot.png" }: { file: Blob time?: number filename?: string }): Promise<{ file: Blob; url: string }> { return new Promise(resolve => { // 因为dom节点没有渲染到浏览器,视频播放到指定的时间就会停止播放 const videoElement = document.createElement("video") videoElement.currentTime = time // 设置截取的帧时间 // 自动播放存在兼容性问题,设置静音解决自动播放在不同浏览器的兼容性问题 videoElement.muted = true videoElement.autoplay = true videoElement.src = URL.createObjectURL(file) videoElement.oncanplay = async function () { const flame = await drawVideoToCanvas({ filename, videoElement }) resolve(flame) } }) }
下面是react代码示例
const Example28 = () => { return ( <div> <input type="file" onChange={event => { const [file] = event.target.files || [] captureFrame({ file, time: 1 }).then(data => { console.log(data) const IMG = new Image() IMG.src = data.url IMG.width = 200 document.body.append(IMG) }) }} /> </div> ) } export default Example28
示例截图
愿你走出半生,归来仍是少年