뷰포트 이탈 시 비디오 자동 일시 정지 기능 구현

Auto-pause Video Player with Stimulus | Rails Designer

작성자
발행일
2025년 06월 19일

핵심 요약

  • 1 Stimulus와 Intersection Observer를 활용하여 뷰포트 이탈 시 비디오를 자동으로 일시 정지하고, 뷰포트 진입 시 재생을 재개하는 기능을 구현합니다.
  • 2 비디오의 가시성 상태를 감지하여 재생 여부를 기억하고, HTML5 비디오 API의 `play()` 메서드 Promise 반환 특성을 고려한 안정적인 재생 로직을 포함합니다.
  • 3 프라이빗 메서드, 배열 비구조화, 옵셔널 체이닝 등 최신 JavaScript 기능을 사용하여 깔끔하고 유지보수 가능한 코드를 작성합니다.

도입

소셜 미디어 플랫폼에서 흔히 볼 수 있는, 스크롤을 통해 뷰포트 밖으로 벗어난 비디오가 자동으로 일시 정지되고 다시 뷰포트 안으로 들어오면 재생되는 기능은 사용자 경험을 크게 향상시킵니다. 본 글은 Rails UI 컨설팅 프로젝트의 일환으로 이러한 기능을 구현하는 방법을 다루며, JavaScript의 Intersection Observer와 Stimulus를 활용한 직관적이면서도 흥미로운 기술적 접근 방식을 소개합니다. 이 글은 학습 플랫폼에 적용될 비디오 자동 재생/일시 정지 기능의 전체 구현 과정을 설명합니다.

뷰포트 기반 비디오 자동 재생/일시 정지 구현

이 기능은 Stimulus 컨트롤러와 JavaScript의 Intersection Observer API를 활용하여 비디오의 뷰포트 가시성을 동적으로 감지하고 재생 상태를 제어합니다.

1. HTML 구조 설정

비디오 요소에 data-controller="video"data-video-percentage-visible-value 속성을 추가하여 Stimulus 컨트롤러를 연결하고, 비디오가 ‘보이는’ 것으로 간주될 최소 가시성 비율(예: 50%)을 정의합니다. ```html

```

2. Stimulus 컨트롤러 정의

bin/rails generate Stimulus video 명령으로 컨트롤러를 생성한 후, 두 가지 static values를 정의합니다. * playing: 비디오가 뷰포트를 벗어날 때 재생 중이었는지 여부를 추적합니다 (Boolean, 기본값 false). * percentageVisible: 비디오가 ‘보이는’ 것으로 간주될 최소 가시성 비율입니다 (Number, 기본값 20).

3. 연결 및 해제 로직

  • connect(): 컨트롤러 연결 시 #detectViewport() 메서드를 호출하여 뷰포트 감지를 시작합니다.
  • disconnect(): 컨트롤러 해제 시 this.observer?.disconnect()를 통해 Intersection Observer를 정리하여 메모리 누수를 방지합니다. 옵셔널 체이닝을 사용하여 옵저버가 존재하지 않을 경우의 오류를 방지합니다.

4. 뷰포트 감지 (#detectViewport)

IntersectionObserver 인스턴스를 생성하여 비디오 요소의 가시성 변화를 감지합니다. * 콜백 함수로 #adjustPlayback(entry)를 지정하여 가시성 변화 시 재생 상태를 조정합니다. * threshold 옵션은 #thresholdValue 게터를 통해 설정됩니다. 이 게터는 percentageVisibleValue를 100으로 나누어 Intersection Observer API가 요구하는 0과 1 사이의 소수점 값으로 변환합니다.

5. 재생 상태 조정 (#adjustPlayback)

IntersectionObserver 콜백에 의해 호출됩니다. * entry.isIntersecting 속성을 통해 비디오가 뷰포트 내에 있는지 확인합니다. * 뷰포트 이탈 시: #pauseWhenOutOfView()를 호출하여 비디오를 일시 정지하고, playingValuetrue로 설정하여 이전에 재생 중이었음을 기록합니다. * 뷰포트 진입 시: #resumeIfPreviouslyPlaying()를 호출하여 이전에 재생 중이었다면 비디오 재생을 다시 시도합니다.

6. 비디오 재생 시도 (#attemptToPlay)

HTML5 비디오 API의 play() 메서드는 Promise를 반환합니다. * #attemptToPlay()this.element.play() || Promise.reject()를 사용하여 항상 Promise를 반환하도록 합니다. 이는 브라우저의 자동 재생 정책으로 인해 play()가 실패할 경우를 대비하고, 구형 브라우저에서 Promise를 반환하지 않을 수 있는 상황에 대응합니다. * 재생 실패 시(Promise reject), 호출부의 .catch() 핸들러에서 playingValuefalse로 설정하여 불필요한 자동 재생 시도를 방지합니다.

이 컨트롤러는 프라이빗 메서드, 배열 비구조화, 옵셔널 체이닝 등 최신 JavaScript 기능을 활용하여 깔끔하고 유지보수 가능한 코드를 제공합니다.

결론

이 Stimulus 컨트롤러는 Intersection Observer를 효과적으로 활용하여 뷰포트 가시성에 따라 비디오를 지능적으로 제어하는 기능을 구현합니다. 비디오가 뷰포트 밖으로 벗어날 때 자동으로 일시 정지하고, 다시 뷰포트 안으로 들어왔을 때 이전에 재생 중이었다면 매끄럽게 재생을 재개함으로써 사용자 경험을 크게 향상시킵니다. HTML5 비디오 API의 잠재적인 자동 재생 제약사항까지 고려한 견고한 로직은 Rails 애플리케이션에서 동적이고 반응적인 UI를 구축하는 데 있어 Stimulus의 강력함과 현대 JavaScript의 유연성을 잘 보여주는 모범 사례입니다.

댓글 0

댓글 작성

0/1000
정중하고 건설적인 댓글을 작성해 주세요.

아직 댓글이 없습니다

첫 번째 댓글을 작성해보세요!