HTML5의 <video> 요소와 <canvas> 요소를 조합하면 재생 중인 영상의 원하는 순간을 이미지(스냅샷)로 손쉽게 캡처할 수 있습니다. 핵심 원리는 간단합니다. 비디오의 현재 프레임을 캔버스 위에 그려 주는 drawImage() 메서드를 활용하는 것입니다.
구현 단계
스냅샷 기능은 다음과 같은 흐름으로 구현됩니다.
- 비디오 준비 – <video> 태그에 영상 파일을 연결하고 controls 속성으로 재생 컨트롤을 표시합니다.
- 메타데이터 처리 – 'loadedmetadata' 이벤트가 발생하면 영상의 실제 해상도(videoWidth, videoHeight)를 읽어 화면비를 계산하고, 캔버스 크기를 영상에 맞게 조정합니다.
- 캡처 실행 – 버튼을 클릭하면 drawImage() 메서드가 현재 재생 중인 프레임을 캔버스에 그려 스냅샷을 완성합니다.
전체 예제 코드
<html>
<body>
<video controls>
<source src="new.mp4" type="video/mp4"></source>
</video>
<canvas id="canvas" width="600" height="300"></canvas>
<button id="snap" onclick="snap()">Snapshot</button>
<script>
var video = document.querySelector('video');
var canvas = document.querySelector('canvas');
var context = canvas.getContext('2d');
var myWidth, myHeight, ratio;
// 메타데이터가 로드되면 캔버스 크기를 영상 비율에 맞게 조정
video.addEventListener('loadedmetadata', function() {
ratio = video.videoWidth / video.videoHeight;
myWidth = video.videoWidth - 100;
myHeight = parseInt(myWidth / ratio, 10);
canvas.width = myWidth;
canvas.height = myHeight;
}, false);
// 스냅샷 버튼 클릭 시 현재 프레임을 캔버스에 그림
function snap() {
context.fillRect(0, 0, myWidth, myHeight);
context.drawImage(video, 0, 0, myWidth, myHeight);
}
</script>
</body>
</html>
코드 핵심 설명
- ratio = video.videoWidth / video.videoHeight – 영상의 원본 화면비를 구해 캔버스에 그려질 이미지가 왜곡되지 않도록 합니다.
- myWidth / myHeight – 캔버스 폭을 영상보다 100px 작게 설정하고, 화면비에 맞춰 높이를 정수로 계산합니다.
- context.fillRect() – 캔버스 영역을 먼저 채워 이전 내용을 지운 뒤 깨끗한 상태에서 그리기를 시작합니다.
- context.drawImage(video, 0, 0, w, h) – 첫 번째 인수로 video 요소를 전달하면 현재 재생 중인 프레임이 그대로 캔버스에 복사됩니다.
참고 사항
다른 도메인의 영상을 캡처할 때는 브라우저 보안 정책(CORS)으로 인해 캔버스가 오염(tainted)되어 오류가 발생할 수 있습니다. 이 경우 video 태그에 crossorigin="anonymous" 속성을 추가하고, 해당 서버가 CORS를 허용하도록 설정해야 합니다. 또한 캡처한 이미지를 파일로 저장하려면 canvas.toDataURL() 메서드를 활용하면 됩니다.