Skip to content

Instantly share code, notes, and snippets.

@vaebe
Created November 21, 2024 09:47
Show Gist options
  • Save vaebe/729899c839e4e237878c5c8d83021d74 to your computer and use it in GitHub Desktop.
Save vaebe/729899c839e4e237878c5c8d83021d74 to your computer and use it in GitHub Desktop.
获取视频首帧图片的base64数据
// https://www.npmjs.com/package/video-cover?activeTab=code
export class VideoCover {
private video: HTMLVideoElement
private canvas: HTMLCanvasElement
private ctx: CanvasRenderingContext2D
constructor(private url: string) {
this.video = document.createElement('video')
this.video.src = this.url
this.video.crossOrigin = 'Anonymous'
this.video.style.cssText = 'position: fixed; top: -100%; width: 400px; visibility: hidden;'
this.canvas = document.createElement('canvas')
this.ctx = this.canvas.getContext('2d')!
document.body.appendChild(this.video)
}
/**
* 获取视频首帧图片的base64数据
*/
getFirstFrame(): Promise<string> {
return new Promise((resolve, reject) => {
this.video.addEventListener('loadedmetadata', () => {
this.canvas.width = this.video.videoWidth
this.canvas.height = this.video.videoHeight
this.video.currentTime = 0
this.video.addEventListener('seeked', () => {
this.ctx.drawImage(this.video, 0, 0)
const base64 = this.canvas.toDataURL('image/png')
resolve(base64)
this.cleanup() // 清理DOM
})
this.video.addEventListener('error', () => {
reject(new Error('视频加载失败'))
this.cleanup() // 清理DOM
})
})
})
}
/**
* 清理DOM中的视频元素
*/
private cleanup() {
if (this.video.parentNode) {
this.video.parentNode.removeChild(this.video)
}
}
}
// 示例用法
(async () => {
const videoCover = new VideoCover('https://example.com/video.mp4');
try {
const base64 = await videoCover.getFirstFrame();
const imgElement = document.createElement('img');
imgElement.src = base64;
document.body.appendChild(imgElement);
} catch (error) {
console.error(error);
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment