tutorials

M3U8/HLS 스트리밍 다운로드 방법: 완전 입문 가이드

브라우저에서 M3U8 및 HLS 동영상을 다운로드하는 방법을 안내합니다. 재생목록 URL 확인, MP4·TS 선택, CORS와 세그먼트 오류 해결, FlowPick 로컬 저장까지 다룹니다.
FlowPick 팀
14분 분량
# m3u8 # hls # 스트리밍 # 다운로드 # 튜토리얼

유료 강의를 시청 중이거나, 꼭 저장하고 싶은 라이브 다시보기가 있습니다. 동영상을 우클릭해도 "저장" 옵션이 없습니다. 다운로드 도구를 써봤더니 3KB짜리 .ts 파일만 받았고, VLC로도 열리지 않습니다.

이것이 사용자 관점에서 본 HLS 스트리밍의 모습입니다. 이 가이드는 그底层 원리를 분석하고, 동영상을 완전히 추출하는 방법을 단계별로 안내합니다.

HLS란 무엇이고, 왜 존재하는가?

HLS — HTTP Live Streaming — 2009년 Apple이 iPhone 스트리밍을 위해 만들었습니다. 핵심 아이디어는 간단합니다: 거대한 동영상 파일 하나를 전송하는 대신, 작은 조각으로 잘라 표준 HTTP를 통해 하나씩 전송하는 것입니다.

모든 세그먼트를 연결하는 재생 목록 파일이 바로 M3U8 파일입니다. 확장자가 .m3u8인 일반 텍스트 파일이죠. 브라우저 Network 패널에서 보이는 .m3u8 URL은 동영상 자체가 아니라 동영상의 목차입니다.

일반적인 M3U8은 이렇게 생겼습니다:

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:10
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:9.960000,
segment_000.ts
#EXTINF:9.960000,
segment_001.ts
...
#EXT-X-ENDLIST

#EXTINF 줄은 세그먼트 길이를 정의하고, 그 뒤에 해당 세그먼트의 URL이 옵니다. 1시간짜리 동영상을 10초 단위로 나누면 360개의 .ts 파일이 생깁니다. 플레이어는 순서대로 다운로드하고, 사용자에게는 연속된 스트림으로 보입니다.

적응형 비트레이트 (ABR)

대부분의 HLS 스트림은 사실 적응형 비트레이트 스트림입니다. 하나의 M3U8만 있는 게 아니라, 여러 화질 버전을 나열하는 마스터 M3U8이 있습니다:

#EXTM3U
#EXT-X-STREAM-INF:BANDWIDTH=5000000,RESOLUTION=1920x1080
1080p/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=2500000,RESOLUTION=1280x720
720p/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=800000,RESOLUTION=640x360
360p/index.m3u8

플레이어는 대역폭에 따라 적절한 화질을 선택하고, 대역폭이 변하면 매끄럽게 전환합니다. 이것이 YouTube가 네트워크가 나빠도 버퍼링 없이 재생되는 이유입니다. 4GB 파일이 다 다운로드되길 기다리는 게 아니라, 다음 10초 분량만 가져오는 것입니다.

왜 사이트들은 직링크 MP4 대신 HLS를 선호할까

세그먼트 전송은 불법 복제를 훨씬 어렵게 만듭니다:

  • 세그먼트 URL은 자주 만료됨 — 2시간 전에 유효했던 URL이 지금은 403을 반환할 수 있음
  • AES-128 암호화로 각 세그먼트를 개별 암호화, 키 순환 가능
  • 단일 다운로드 파일이 없음 — "다른 이름으로 저장"할 대상이 없음
  • CDN 분산 — 실제 .ts 파일이 전 세계 수십 대 서버에 분산되어 있을 수 있음

합법적인 용도(아카이빙, 오프라인 학습, 접근성)에는 정말 골치 아픈 일입니다. 이것이 HLS 다운로드 도구가 존재하는 이유입니다.

잘못된 도구를 쓰면 어떻게 되는가

DevTools에서 M3U8 URL을 찾아 직접 다운로드하려고 한다고 가정해 봅시다:

  • wget/curl M3U8: 재생 목록 텍스트 파일을 받음, 동영상이 아님
  • 브라우저 "링크 저장": 몇 KB짜리 M3U8 텍스트 다운로드, 당연히 재생 불가
  • 일반 다운로드 도구: 오류를 내거나 첫 번째 세그먼트만 가져옴
  • youtube-dl/yt-dlp: 지원하는 사이트에서는 되지만, 명령줄, Python이 필요하고 사이트 변경에 따라 계속 업데이트해야 함

진정한 HLS 다운로드에는 다음을 수행할 수 있는 소프트웨어가 필요합니다:

  1. M3U8 포맷 파싱
  2. 상대 URL을 절대 URL로 변환
  3. 수백 개의 .ts 세그먼트 다운로드 (병렬 처리 권장)
  4. #EXT-X-KEY의 키로 AES-128 암호화 세그먼트 복호화
  5. 재생 가능한 컨테이너 포맷(MP4 또는 TS)으로 결합 또는 리먹싱

이것은 단순 다운로드가 아니라 처리 파이프라인입니다.

FlowPick으로 HLS 스트림 다운로드하기

방법 1: 브라우저 확장 프로그램 (권장)

확장 프로그램은 브라우저에서 조용히 M3U8 요청을 감지하므로 수동으로 URL을 찾을 필요가 없습니다.

1단계: FlowPick 설치

Chrome 웹 스토어, Edge 확장 또는 Firefox 부가 기능에서 설치하세요.

2단계: 페이지를 열고 재생 시작

M3U8 요청은 플레이어 초기화 시에만 발생합니다. 페이지를 열기만 해서는 안 되고, 동영상이 실제로 재생되어야 합니다.

3단계: FlowPick 아이콘 클릭

도구 모음 아이콘에 숫자 배지가 표시되며, 이는 감지된 스트림 수입니다. 클릭하여 팝업을 엽니다.

4단계: 화질 선택

적응형 스트림의 경우, FlowPick이 마스터 M3U8을 읽고 사용 가능한 모든 화질을 표시합니다. 필요한 해상도를 선택하세요.

5단계: 다운로드 및 병합

Pick을 클릭합니다. FlowPick이 설정된 스레드 수(기본 2개, 설정에서 조정 가능)로 세그먼트를 병렬 다운로드하고, 암호화된 세그먼트를 로컬에서 복호화한 후, MP4 또는 TS 파일(설정에 따라)로 병합합니다. 전체 과정에서 어떤 서버도 거치지 않으며, 파일은 CDN에서 직접 디스크로 이동합니다.

다운로드 진행 상황

FlowPick 팝업 하단에 현재 다운로드 작업의 실시간 진행 상황이 표시됩니다: 다운로드된 세그먼트 수/총 세그먼트 수, 현재 속도, 예상 남은 시간. 수백 개 세그먼트의 긴 동영상도 보통 몇 분이면 완료됩니다.

방법 2: 온라인 도구 (설치 불필요)

이미 M3U8 URL이 있다면 M3U8 온라인 다운로드 도구를 바로 사용할 수 있습니다. 확장 프로그램 설치가 필요 없습니다.

URL을 붙여넣고, 화질을 선택하고, 다운로드를 클릭하세요. 공개 스트림에는 잘 작동하지만, 일부 플랫폼에는 CORS 제한이 있습니다(이때는 확장 프로그램이 더 유리합니다. 페이지 자체의 자격 증명을 가지고 실행되기 때문입니다).

M3U8 URL을 수동으로 찾는 방법: 개발자 도구 열기(F12) → Network 탭 → 필터에 m3u8 입력 → 동영상 재생 → Content-Type이 application/x-mpegurl인 요청 찾기.

출력 포맷: MP4 vs TS?

FlowPick은 두 가지 출력 포맷을 지원하며, 설정에서 전환할 수 있습니다:

MP4TS
호환성최고, 거의 모든 플레이어 지원일부 구형 플레이어 미지원
처리 속도FFmpeg WASM 리먹싱 필요, 약간 느림직접 바이너리 결합, 매우 빠름
파일 크기TS보다 5-15% 작음 (컨테이너 오버헤드 적음)약간 큼
적합한 상황장기 보관, 플랫폼 업로드, 동영상 편집속도 우선, 이후 FFmpeg로 추가 처리

일상적으로는 MP4를 사용하세요. 이후 FFmpeg 명령줄로 추가 처리를 할 계획이거나, 네트워크가 느려 리먹싱 단계를 건너뛰고 싶을 때만 TS를 고려하세요.

암호화 스트림: AES-128

많은 유료 콘텐츠는 암호화된 HLS를 사용하며, M3U8에 다음과 같은 줄이 있습니다:

#EXT-X-KEY:METHOD=AES-128,URI="https://api.example.com/key?token=abc123"

의미: 각 .ts 세그먼트가 128비트 AES 키로 암호화되어 있으며, 키는 해당 URI에서 가져옵니다. 키가 없으면 원시 세그먼트 바이트는 아무 의미가 없습니다.

FlowPick은 이 모든 것을 자동으로 처리합니다:

  1. URI에서 키 가져오기 (브라우저의 Cookie와 세션 사용 — 그래서 로그인 상태에서 사용 가능)
  2. 브라우저 내장 Web Crypto API로 각 세그먼트를 클라이언트 측에서 복호화
  3. 키와 세그먼트 데이터는 어떤 외부 서버에도 전송되지 않음

FlowPick이 처리할 수 없는 것: Widevine, PlayReady, FairPlay DRM. 이들은 하드웨어 수준 콘텐츠 보호로, 복호화 키가 기기에 바인딩되어 있으며 JavaScript로 접근할 수 없습니다. Netflix와 Disney+가 이 부류에 속합니다.

실제 사용 시나리오

온라인 강의 플랫폼 (Udemy, Coursera 등)

대부분의 강의 플랫폼은 수강생이 다운로드 후 환불하는 것을 방지하기 위해 암호화된 HLS를 사용합니다. FlowPick은 AES-128 암호화를 처리할 수 있습니다. 단, 로그인되어 있고 접근 권한이 있어야 합니다.

작업 리듬: 강의 동영상 열기 → 5초 재생 → FlowPick 열기 → 720P 선택 (강의 콘텐츠는 이 정도면 충분하고 파일도 작음) → Pick. 다운로드 후 즉시 재생 확인하여 오디오 동기화를 검증하세요.

라이브 다시보기 녹화

라이브 방송 종료 후 보통 짧은 다시보기 기간(24-72시간)이 있으며, 이후 플랫폼이 삭제하거나 유료 회원 전용으로 전환합니다. 이 기간 내에 다운로드하는 것이 가장 깔끔합니다. 스트림이 정적이고, URL이 실시간 라이브처럼 빠르게 만료되지 않습니다.

판단 방법: 실시간 라이브라면 M3U8에 #EXT-X-ENDLIST 태그가 없습니다. 이 태그가 있으면 라이브가 종료되었고 완전히 다운로드 가능한 정적 스트림입니다.

다국어 오디오 트랙 콘텐츠

일부 플랫폼의 HLS 스트림에는 다국어 오디오 트랙이 포함되어 있으며, M3U8에 #EXT-X-MEDIA:TYPE=AUDIO로 나열됩니다. FlowPick이 이를 감지하고 사용 가능한 오디오 트랙을 표시합니다.

일반적인 문제 해결

"0개 스트림 감지됨"

가장 흔한 원인: 동영상이 아직 재생되지 않음. M3U8 요청은 플레이어 초기화 시에만 발생합니다. 재생을 누르고 버퍼링이 1-2초 진행된 후 다시 확인하세요.

사이트가 플레이어를 iframe에 넣은 경우(임베디드 플레이어, 강의 플랫폼), 동영상을 우클릭 → "새 탭에서 프레임 열기" → 해당 탭에서 FlowPick을 사용하세요.

"X%에서 다운로드가 멈췄어요"

스트림 URL이 만료되었습니다. 대부분 플랫폼의 세그먼트 URL은 4-6시간 유효하며, 라이브 콘텐츠는 30분밖에 안 될 수 있습니다.

해결: 페이지 새로고침, 동영상 다시 재생하여 새 URL 획득, FlowPick으로 다시 감지.

"다운로드한 파일이 재생되지 않아요"

몇 가지 가능성:

  • 세그먼트 손상: 손상된 단일 .ts가 병합을 망칠 수 있음. 낮은 화질 버전 시도.
  • 비표준 TS 포맷: FlowPick은 FFmpeg WASM으로 리먹싱을 처리하지만 엣지 케이스가 존재.
  • 오디오/비디오 동기화 불량: VLC로 열고 "항상 복구" 선택 (미디어 → 변환/저장 → 프로필 → 비디오 코덱 → "손상되거나 누락된 AV 동기화 복구/무시" 체크).

"단일 .ts 파일만 받았어요"

Firefox에서 또는 병합 단계가 조용히 실패했을 때 발생합니다. Chrome이나 Edge로 전환하세요. 병합 지원이 더 좋습니다. Chrome의 File System Access API는 대용량 파일을 디스크에 직접 쓸 수 있습니다.

다운로드 속도가 매우 느림

기본 동시 스레드가 2개로 보수적인 설정입니다. FlowPick 설정에서 스레드 수를 4-6으로 올리면 보통 눈에 띄게 빨라집니다. 너무 높이지 마세요. 과도한 동시 연결은 서버 측 속도 제한을 유발할 수 있습니다.

대용량 파일 다운로드 참고

FlowPick은 브라우저의 File System Access API를 통해 스트리밍 쓰기를 수행하므로 이론상 파일 크기 제한이 없습니다. 4K 동영상, 몇 GB짜리 긴 콘텐츠도 문제없이 처리하며, 파일이 커서 브라우저가 충돌하거나 메모리가 터지는 일이 없습니다.

Chrome과 Edge가 대용량 파일 지원이 가장 좋습니다(완전한 FSA 스트리밍 쓰기). Firefox도 지원하지만 다른 쓰기 전략을 사용하므로, 초대용량 파일 시나리오에서는 Chrome보다 안정성이 약간 낮습니다.

빠른 참고: HLS와 다른 포맷

.mpd 파일을 만난다면 .m3u8이 아니라 DASH를 상대하고 있는 것입니다. DASH는 또 다른 관련 스트리밍 프로토콜입니다. 자세한 분석은 DASH 스트리밍이란? MPD 파일 해설을 참고하세요.

둘 다 FlowPick으로 처리할 수 있으며, 조작 흐름은 기본적으로 동일합니다. 주요 차이점은 DASH에 독립적인 오디오/비디오 트랙이 있어 병합이 필요하고 처리 시간이 약간 더 길다는 점입니다.


추천 글