YouTube Most Replayed 히트맵을 분석해 시청자 행동을 정량화하는 영상 분석 서비스
Why this project?
YouTube의 "Most Replayed" 히트맵은 시청자 행동의 풍부한 데이터를 담고 있지만, 단순 시각적 표시에 그칩니다. 어떤 구간이 왜 많이 재시청되었는지, 이탈이 심한 구간은 어디인지, 전체적인 시청 안정성은 어떤지를 정량적으로 분석하면 콘텐츠 크리에이터에게 유용한 인사이트가 됩니다. 하지만 이 데이터는 공식 API로 제공되지 않아, 수집부터 분석까지 전체 파이프라인을 직접 구축해야 했습니다.
Key Features
Playwright Headless Chrome으로 YouTube 영상 페이지를 로드하고, SVG path의 d 속성에서 M(이동)·C(Cubic Bezier)·L(직선) 명령어를 파싱합니다. Y좌표 반전·정규화를 거쳐 0~1 범위의 popularity 시계열 데이터를 생성합니다. 영상 길이(duration) 획득은 DOM 직접 추출 → 페이지 메타데이터 → YouTube Data API v3 → SVG 좌표 역추정의 4단계 fallback 체인으로 안정성을 확보했습니다.
YouTube 히트맵 SVG의 Cubic Bezier 세그먼트를 De Casteljau 알고리즘으로 N등분 보간하여 저해상도 데이터를 복원합니다. 영상 길이에 비례하여 목표 분당 포인트 밀도(targetPointsPerMinute)를 자동 산출하고, needsInterpolation() 함수가 영상 길이 대비 원본 포인트 부족 여부를 판단하여 보간을 적응적으로 적용합니다.
Replay Peak(원본 데이터에서 직접 최대값 탐색, 이동평균 왜곡 방지), Drop Rate(Window=3 스무딩 후 1차 차분 기반 최대 하락 구간 탐지), Stability Score(5초 단위 시간 기반 윈도우 + CRITICAL_VARIANCE=400 절대 임계값으로 영상 간 비교 가능한 안정성 지표), Highlight Density(IQR 적응형 임계값 + 피크 돌출도 + 로컬 딥 기반 분할), Engagement Curve(이동평균 스무딩 참여도 곡선)를 구현했습니다.
앱 내 /wiki 경로에서 각 지표의 수학적 계산 방식과 해석 가이드를 KaTeX 수식 렌더링으로 제공합니다. Stability Score의 공식(stability = 1 - min(1, localVariance / CRITICAL_VARIANCE))이나 Bezier 보간 공식 등 분석 엔진의 수학적 근거를 사용자가 직접 확인할 수 있습니다.
Tech Decisions
YouTube Most Replayed 데이터는 공식 API로 제공되지 않아, Headless Chrome 기반 스크래핑이 유일한 수집 방법이었습니다.
영상마다 popularity 분포가 다르므로, IQR(사분위수 범위) 기반 적응형 임계값이 고정 임계값보다 다양한 영상에 안정적으로 작동합니다.
상대적 Min-Max 정규화는 잔잔한 영상이 과대 표현되는 문제가 있어, 절대 임계값(CRITICAL_VARIANCE = 400)으로 영상 간 비교 가능한 지표를 설계했습니다.
Problem Solving
Problem
YouTube 페이지에서 영상 길이(duration)를 가져오는 방법이 환경에 따라 다르게 동작했습니다. 로컬 브라우저에서는 video.duration으로 바로 가져올 수 있지만, 클라우드 서버리스 환경에서는 DOM이 완전히 로드되지 않거나, 지역 제한 영상에서는 메타데이터 자체가 다른 형식으로 제공되어 duration을 안정적으로 획득할 수 없었습니다.
Approach
이 문제를 "단일 방법에 의존하면 어떤 환경에서든 실패할 수 있다"는 관점에서 접근했습니다. 4단계 fallback 체인을 설계하여 video.duration → ytInitialPlayerResponse(페이지 메타데이터) → DOM 파싱 → YouTube Data API v3 순으로 시도하되, 각 단계에서 실패하면 자동으로 다음 방법으로 전환됩니다. 각 fallback 단계에는 타임아웃과 유효성 검증을 포함하여, 잘못된 값이 전파되지 않도록 했습니다.
Result
클라우드 환경, 지역 제한 영상, 라이브 종료 영상 등 다양한 예외 상황에서도 안정적으로 duration을 획득하며, 프로덕션에서 duration 획득 실패로 인한 분석 중단이 발생하지 않습니다.
Problem
챕터가 있는 영상에서 히트맵이 전체 영상이 아닌 챕터별로 분리된 SVG로 제공되었습니다. 기존 파싱 로직은 단일 SVG path를 전제로 작성되어 있어, 챕터 영상에서는 첫 번째 챕터의 데이터만 파싱되고 나머지가 누락되는 문제가 있었습니다.
Approach
챕터별 SVG가 별도의 좌표계를 사용한다는 것을 분석하고, 각 챕터의 시간 범위(startTime, endTime)를 먼저 파악한 뒤, 챕터별 SVG 좌표를 전체 영상 타임라인의 해당 구간에 정확히 매핑하여 병합하는 로직을 구현했습니다. 챕터 경계에서 데이터가 불연속이 되지 않도록, 인접 챕터의 경계값을 보간으로 연결했습니다.
Result
챕터 유무에 관계없이 일관된 전체 영상 데이터를 분석 엔진에 제공하며, 분석 결과에서 챕터 경계가 인위적인 불연속으로 나타나지 않습니다.
Outcomes
Links