logo hsb.horse
← 블로그 목록으로 돌아가기

블로그

HTMLVideoElement에서 이미지를 생성하는 TypeScript 구현

Canvas와 VideoElement를 사용하여 동영상의 현재 프레임을 이미지로 추출하는 TypeScript 구현. Promise 기반으로 blob 생성하는 방법을 정리.

게시일:

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);
});
}

포인트

  1. video.videoHeightvideo.videoWidth로 동영상 해상도 얻기
  2. ctx.drawImage(video, 0, 0, width, height)로 현재 프레임을 Canvas에 그리기
  3. canvas.toBlob로 Canvas의 내용을 Blob화
  4. 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를 조합함으로써 동영상의 임의의 프레임을 이미지로 추출할 수 있다.

썸네일 생성이나 동영상 프리뷰 기능의 구현에 활용할 수 있다.