DEV Community

yqqwe
yqqwe

Posted on

NYTimes 비디오 스트리밍 구조 해부: HLS와 FFmpeg를 활용한 고성능 추출 엔진 구축기

서론

개발자로서 우리는 대규모 플랫폼이 전 세계적으로 멀티미디어 데이터를 어떻게 관리하고 배포하는지에 대해 항상 호기심을 갖습니다. 세계 최고의 언론사인 뉴욕 타임스(The New York Times)의 비디오 배포 아키텍처는 단순한 파일 호스팅이 아니라, HLS(HTTP Live Streaming)를 기반으로 하는 복잡하고 동적인 어댑티브 스트리밍 시스템을 채택하고 있습니다.
연구자나 개발자들에게 NYTimes의 고화질 뉴스 영상을 아카이브하는 것은 기술적으로 큰 의미가 있습니다. 그러나 DRM(디지털 저작권 관리)의 강화와 스트리밍 프로토콜의 파편화로 인해 이러한 리소스를 효율적으로 추출하는 진입 장벽은 점점 높아지고 있습니다. 이 문제를 해결하기 위해 저는 NYTimes 비디오 다운로더를 개발했습니다. 본 아티클에서는 그 이면에 숨겨진 공학적 구현, 즉 HLS 프로토콜 역공학, 동적 토큰 검증 루프, 그리고 서버 사이드 무손실 머싱(Lossless Muxing)에 대해 자세히 설명하고자 합니다.

1. 미디어 배포 프로토콜의 진화: MP4에서 HLS로

초기 웹 비디오 배포 방식은 매우 단순했습니다.

  1. Master Playlist(마스터 플레이리스트): 다양한 해상도(예: 480p, 720p, 1080p)에 대응하는 하위 플레이리스트를 포함합니다.
  2. Media Playlist(미디어 플레이리스트): 특정 해상도에 대해 비디오 세그먼트의 시퀀스를 나열합니다. 각 세그먼트의 길이는 보통 2초에서 6초 사이입니다. 기술적 도전: 추출 엔진은 .m3u8의 트리 구조를 재귀적으로 해석하는 기능을 갖추어야 합니다. 특히 저대역폭용 저화질 버전이 아닌, 사용자가 원본 화질을 얻을 수 있도록 최고 비트레이트(Highest Bitrate) 트랙을 자동으로 식별하고 격리해야 합니다.

2. 역공학: 동적 인증 장벽 돌파하기

NYTimes는 비디오 API에 대해 다중 보호 계층을 적용합니다. 표준 curl 명령어로 내부 미디어 인터페이스에 요청을 보내면 대개 403 Forbidden 또는 401 Unauthorized 오류가 발생합니다.
서명 메커니즘 및 세션 관리
NYTimes 웹 클라이언트는 복잡한 인증 로직에 의존합니다.
• API Key 검증: 난독화된 JavaScript 번들(JS Bundles) 내부에 숨겨져 있습니다.
• 동적 서명(Signatures): 각 세그먼트 요청에 대해 생성되는 시효성 있는 해시값입니다.
엔지니어링 구현: 저희 백엔드는 자가 치유형 세션 풀(Self-healing Session Pool)을 유지합니다. 토큰 만료나 속도 제한(Rate Limiting)으로 인해 요청이 실패할 경우, 엔진은 자동으로 현대 브라우저의 '핸드셰이크' 흐름을 시뮬레이션합니다. 여기에는 최소한의 브라우저 핑거프린팅(Fingerprinting)이 포함되어 봇 감지 시스템을 우회하면서도, 고빈도 병렬 처리를 지원할 수 있는 경량성을 유지합니다.

3. 백엔드 아키텍처: Async I/O 기반 고가용성 처리

글로벌 다운로드 요청을 감당하기 위해, nytimes_downloader_ko의 백엔드는 전통적인 블로킹 요청 모델을 버리고 Python Asyncio + Httpx 기반의 완전 비동기 스택을 채택했습니다.
왜 비동기인가?
비디오 추출은 본질적으로 I/O 바운드(I/O-bound) 작업입니다. 하나의 사용자 요청은 다음과 같은 과정을 거칩니다.

  1. 페이지 HTML을 파싱하여 메타데이터 추출.
  2. 내부 REST 또는 GraphQL 인터페이스를 쿼리하여 미디어 설정 획득.
  3. 네트워크를 통해 다단계 .m3u8 파일을 재귀적으로 스크레이핑. 동기 모델에서는 워커 프로세스가 네트워크 응답을 기다리는 동안 유휴 상태가 됩니다. 반면 asyncio를 사용하면 단일 프로세스로 수천 개의 병렬 추출 작업을 관리할 수 있어, 서버 하드웨어 비용을 극적으로 낮추면서 응답 시간을 단축할 수 있습니다.

4. 서버 사이드 처리: FFmpeg를 이용한 무손실 머싱

모든 HLS 세그먼트를 파싱한 후, 최종적으로 사용자에게 하나의 MP4 파일을 전달해야 합니다. 사용자에게 수백 개의 TS 조각을 수동으로 다운로드하게 하는 것은 최악의 UX입니다.
스트림 복사(Stream Copying) vs 인코딩(Transcoding)
저희는 FFmpeg를 파이프라인에 통합하여 실시간 머싱(결합)을 수행합니다. 여기서 가장 중요한 최적화는 스트림 복사(Stream Copying)를 사용하는 것입니다.
Bash
ffmpeg -i "concat:file1.ts|file2.ts|..." -c copy -map 0✌️0 -map 1🅰️0 output.mp4
기술적 통찰: -c copy 플래그가 핵심입니다. 이는 FFmpeg에게 하위 픽셀 인코딩을 건드리지 않고 데이터 패킷을 TS 컨테이너에서 MP4 컨테이너로 이동만 시키도록 지시합니다. 덕분에 처리는 거의 즉시 완료되며, CPU 집약적인 트랜스코딩 없이 100% 원본 화질을 유지할 수 있습니다. 화질 저하(Generation Loss)가 전혀 발생하지 않습니다.

5. 프론트엔드 최적화: Utility-First 도구 철학

프론트엔드 디자인은 '제로 번들' 원칙을 따릅니다.
• Vanilla JS 구현: 무거운 프레임워크를 배제하여 First Contentful Paint(FCP)를 1초 미만으로 단축했습니다.
• PWA 지원: 웹 사이트는 점진적 웹 앱(PWA) 사양을 지원하여 모바일 및 데스크톱 환경에서 네이티브 앱에 가까운 사용자 경험을 제공합니다.
• 보안성: 모든 분석 로직은 서버 사이드에서 완결되므로, 사용자는 개인정보 침해 우려가 있는 위험한 브라우저 확장 프로그램을 설치할 필요가 없습니다.

6. 윤리와 베스트 프랙티스

이러한 도구를 구축할 때는 기능성과 규정 준수 사이의 균형이 필요합니다.
• 개인정보 우선: 저희는 사용자의 비디오 파일을 영구적으로 저장하지 않습니다. 임시 데이터는 전달이 완료되는 즉시 파기됩니다.
• 속도 제한 인지: 시스템 내부에 큐 관리 기능을 갖추어 NYTimes의 공식 인프라에 불필요한 부하를 주지 않도록 설계되었습니다.

결론

고성능 다운로더를 구축하는 것은 단순한 크롤링 작업이 아니라 현대적인 웹 프로토콜, API 역공학, 그리고 효율적인 미디어 처리에 대한 깊은 실천입니다. HLS 파싱 로직을 최적화하고 비동기 백엔드 아키텍처를 활용함으로써, 저희는 원활한 1080p 비디오 추출 경험을 구현했습니다.
깔끔하고 광고가 없으며 기술적으로 견고한 방식으로 뉴욕 타임스의 비디오 콘텐츠를 아카이브하려는 개발자라면 저희 도구를 사용해 보시기 바랍니다.
👉 프로젝트 링크: 뉴욕 타임스 비디오 다운로더(한국어판)
기술 스택 요약:
• Backend: Python / Django / Redis / FFmpeg
• Architecture: Asyncio / Distributed Crawling
• Frontend: HTML5 / Tailwind CSS / Vanilla JS
• Infrastructure: Cloudflare / Docker / Nginx
HLS 파싱 로직이나 FFmpeg 스트림 조작에 대해 궁금한 점이 있다면 아래 댓글창에서 함께 토론해 봅시다!

WebDev #NYTimes #Python #FFmpeg #OpenSource #Programming #VideoStreaming #DevTools #KoreaDevelopers

Top comments (0)