HTMLVideoElementの現在フレームを画像として抽出する実装をまとめる。
CanvasAPIを使って動画フレームをキャプチャし、Blob形式で取得する。
利用するAPI
- HTMLCanvasElement
- HTMLVideoElement
- Promise API
実装
interface OutputImage { type: "png" | "jpeg" | "webp"; quality?: number;}
interface TransferOptions { canvas: HTMLCanvasElement; video: HTMLVideoElement; output: OutputImage;}
interface TransferredImage { blob: Blob; width: number; height: number; type: string;}
function transferImage(options: TransferOptions): Promise<TransferredImage> { const { canvas, video, output } = options;
const height = video.videoHeight; const width = video.videoWidth;
return new Promise<TransferredImage>((resolve, reject) => { const ctx = canvas.getContext("2d"); if (!ctx) { reject(new Error("Context2D is not defined")); return; }
ctx.drawImage(video, 0, 0, width, height);
const type = `image/${output.type}`; const q = output.quality || 1;
function toBlob(blob: Blob | null) { if (blob) { resolve({ blob, width, height, type }); } else { reject(new Error("Failed to create blob from canvas")); } }
canvas.toBlob(toBlob, type, q); });}ポイント
video.videoHeightとvideo.videoWidthで動画の解像度を取得ctx.drawImage(video, 0, 0, width, height)で現在フレームをCanvasに描画canvas.toBlobでCanvasの内容をBlob化- Promiseで非同期処理をラップ
使用例
const video = document.querySelector('video');const canvas = document.createElement('canvas');
const image = await transferImage({ canvas, video, output: { type: 'png', quality: 1 }});
// image.blob を使って画像をダウンロードしたり、表示したりできるconst url = URL.createObjectURL(image.blob);まとめ
HTMLVideoElementとCanvasAPIを組み合わせることで、動画の任意のフレームを画像として抽出できる。
サムネイル生成や動画プレビュー機能の実装に活用できる。
hsb.horse