Computer >> 컴퓨터 >  >> 프로그래밍 >> JavaScript

HTML5 캔버스에서 비디오를 재생하고 마지막 프레임(이미지)까지 유지하는 방법

HTML5 캔버스에서 비디오 재생과 마지막 프레임 유지

HTML5에서는 <video> 요소와 <canvas> 요소를 함께 사용해 동영상을 캔버스 화면에 직접 렌더링할 수 있습니다. 핵심은 drawImage() 메서드입니다. 이 메서드는 이미지뿐만 아니라 재생 중인 비디오도 소스로 받아 캔버스에 그릴 수 있습니다.

비디오가 일시정지되거나 종료되면 프레임 그리기를 멈추기 때문에, 마지막으로 그려진 프레임이 캔버스에 그대로 남게 됩니다. 이 원리를 활용하면 별도의 추가 작업 없이도 비디오의 마지막 장면을 자연스럽게 보존할 수 있습니다.

예제 코드

먼저 HTML 마크업은 다음과 같이 작성합니다.

<video id="myPlayer" width="640" height="480" controls>
   <source src="sample.mp4" type="video/mp4">
</video>
<canvas width="640" height="480"></canvas>

그다음 아래 자바스크립트 코드를 실행하면, 비디오가 재생되는 동안 매 프레임이 캔버스에 그려지고 재생이 끝난 후에는 마지막 프레임이 그대로 유지됩니다.

var c = $('canvas')[0];
var context = c.getContext('2d');

c.width = 640;
c.height = 480;

$("#myPlayer").on('play', function (e) {
   var $this = this;
   (function loop() {
      if (!$this.paused && !$this.ended) {
         // 현재 비디오 프레임을 캔버스에 그림
         context.drawImage($this, 0, 0, 640, 480);
         // 초당 약 30프레임으로 반복 호출
         setTimeout(loop, 1000 / 30);
      }
      // paused 또는 ended 상태면 루프 종료 → 마지막 프레임 유지
   })();
});

코드 상세 설명

1. 캔버스와 드로잉 컨텍스트 준비

$('canvas')[0]으로 문서에서 첫 번째 캔버스 요소를 선택한 뒤, getContext('2d')로 2D 드로잉 컨텍스트를 얻습니다. 캔버스 크기는 640×480 픽셀로 설정해 비디오 해상도와 맞췄습니다.

2. play 이벤트에 프레임 루프 연결

jQuery의 .on('play', ...)를 사용해 비디오 재생이 시작되는 순간 루프를 시작합니다. 즉시 실행 함수 (function loop(){ ... })()가 재귀적으로 자신을 호출하며 프레임을 계속 갱신합니다.

3. 프레임 그리기와 종료 조건

pausedended 속성을 검사해 비디오가 실제로 재생 중일 때만 drawImage()를 호출합니다. setTimeout(loop, 1000 / 30)은 초당 약 30프레임(30fps) 주기로 화면을 갱신합니다.

재생이 끝나거나 일시정지되면 조건문이 false가 되어 루프가 멈춥니다. 이때 캔버스는 지워지지 않으므로 마지막 프레임이 그대로 화면에 남습니다. 바로 이 점이 별도 처리 없이 마지막 장면을 보존할 수 있는 이유입니다.

참고 사항

  • 더 부드러운 재생 품질을 원한다면 setTimeout 대신 requestAnimationFrame()을 사용하는 것이 좋습니다.
  • 동일 출처 정책(CORS) 때문에 외부 도메인의 비디오를 캔버스에 그리면 캔버스가 오염(tainted)될 수 있으므로, 가급적 같은 서버에 있는 영상을 사용하는 것이 안전합니다.
  • 필요에 따라 seeked, pause 등 다른 비디오 이벤트에도 루프를 연결해 다양하게 응용할 수 있습니다.