X (Twitter) 스트리밍 해부: HLS와 FFmpeg로 고성능 비디오 추출 엔진 구축
Source: Dev.to
소개
개발자로서 우리는 대규모 글로벌 데이터 전달을 어떻게 큰 플랫폼들이 관리하는지 이해하는 데 매료됩니다. X(이전의 Twitter)는 뛰어난 사례 연구입니다. 그들의 미디어 배포 인프라는 단순한 MP4 정적 링크에서 동적 적응형 스트리밍(DASH/HLS) 아키텍처로 진화했습니다.
웹 초창기에는 비디오를 다운로드하는 것이 간단했습니다: <video> 태그의 src 속성을 찾아서 보통 정적인 .mp4 파일을 가리키면 되었습니다. 오늘날 X는 HTTP Live Streaming (HLS) 을 사용해 다양한 네트워크 환경에서 시청 경험을 최적화합니다.
HLS 아키텍처
- Master Playlist: 360p, 720p, 1080p 등 다양한 해상도에 대한 하위 플레이리스트를 포함합니다.
- Media Playlist: 특정 해상도에 대해 2~4초 길이의 비디오 세그먼트 목록을 나열합니다.
기술적 과제
추출 엔진은 다음을 수행해야 합니다:
m3u8트리 구조를 재귀적으로 파싱합니다.- 가능한 최고의 품질을 보장하기 위해 자동으로 최고 비트레이트(Highest Bitrate) 트랙을 식별하고 격리합니다.
X는 다중 계층 인증 게이트를 구현하고 있습니다. 표준 curl 로 내부 미디어 API에 요청하면 401 Unauthorized 또는 403 Forbidden 오류가 반환될 가능성이 높습니다.
비동기 구현
전 세계 트래픽을 지원하기 위해 twittervideodownloaderx.com/sp 백엔드는 전통적인 블로킹 요청 모델에서 벗어나 Python Asyncio + httpx 전체 스택을 채택했습니다.
일반적인 프로세스 단계
- 트윗 HTML을 파싱해 메타데이터를 추출합니다.
- GraphQL 엔드포인트에 요청해 미디어 설정을 가져옵니다.
- 네트워크를 통해
m3u8세그먼트를 재귀적으로 가져옵니다.
동기 모델에서는 작업 프로세스가 네트워크 응답을 기다리는 동안 멈춥니다. asyncio 를 사용하면 하나의 프로세스가 수천 개의 추출 작업을 동시에 처리할 수 있어 서버 하드웨어 부하를 크게 줄일 수 있습니다.
다운로드 및 Muxing 과정
HLS 세그먼트를 파싱한 뒤에는 사용자에게 단일 MP4 파일을 제공해야 합니다. 수백 개의 작은 TS 파일을 직접 다운로드하면 사용자 경험이 저하됩니다. 일반적인 흐름은 다음과 같습니다:
# 1. 마스터 플레이리스트 다운로드
curl -L "https://example.com/master.m3u8" -o master.m3u8
# 2. 최고 비트레이트 변형을 선택하고 세그먼트 다운로드
ffmpeg -i master.m3u8 -c copy -bsf:a aac_adtstoasc output.mp4
이 명령은 FFmpeg 를 사용해:
- 자동으로 최고 품질 변형을 선택합니다.
- 재인코딩 없이 TS 세그먼트를 연결합니다(
-c copy). - 오디오 ADTS를 호환 컨테이너로 변환합니다(
-bsf:a aac_adtstoasc).
스택 요약
- 백엔드: Python / Django / Redis / FFmpeg
- 아키텍처: Asyncio / 분산 크롤링
- 프론트엔드: HTML5 / Tailwind CSS / Vanilla JS
- 인프라: Cloudflare / Docker / Nginx
연락처
HLS 분석이나 FFmpeg Muxing에 대해 궁금한 점이 있나요? 댓글로 남겨 주세요!
태그: WebDev, Twitter, Python, OpenSource, Programming, VideoStreaming, DevTools, SystemDesign