- Published on
HLS 스트리밍 이해하기: 적응형 비트레이트와 m3u8 파일 설명
- Authors
- Name
- Deokgoo Kim

HLS 스트리밍 이해하기: 적응형 비트레이트와 m3u8 파일 설명
HLS를 도입한 배경
현재 진행 중인 프로젝트에서 영상 최적화가 중요한 요소로 작용했습니다. 특히 적응형 비트레이트(ABR, Adaptive Bitrate)와 캐싱을 활용하여 사용자에게 끊김 없는 스트리밍 경험을 제공하는 것이 핵심 과제였습니다.
초기에는 MP4 파일을 HTML5 <video>
태그를 이용해 직접 제공하는 방식을 고려했습니다. 이 방식에서는 Range Request를 활용하여 특정 구간만 로드할 수 있다는 장점이 있었지만, 파일 전체를 다루는 구조상 네트워크 환경이 좋지 않을 때 성능 저하 및 버퍼링 발생 가능성이 높다는 한계가 있었습니다.
이를 해결하기 위해 다양한 스트리밍 방식을 조사하던 중, 영상 공급 회사들이 널리 사용하는 **HLS(HTTP Live Streaming)**를 접하게 되었고, 이에 대해 심층적으로 연구하고 적용하게 되었습니다.
HLS란?
HTTP Live Streaming(HLS)은 Apple에서 개발한 적응형 스트리밍 프로토콜입니다. 기본적으로 HTTP를 이용하여 미디어 콘텐츠를 작은 조각(청크) 단위로 전송하며, 네트워크 상태에 따라 적절한 품질의 비디오를 선택할 수 있도록 설계되었습니다.
기존의 스트리밍 방식(RTMP 등)과 비교했을 때 HLS는 HTTP 기반이므로 방화벽 문제를 최소화하며, 적응형 비트레이트(ABR, Adaptive Bitrate)를 지원하여 원활한 재생 환경을 제공합니다.
기존 스트리밍 방식과의 차이점
HLS와 기존 스트리밍 방식(RTMP, DASH, MP4 등)의 차이를 정리하면 다음과 같습니다:
스트리밍 방식 | 전송 프로토콜 | 방화벽 문제 | ABR 지원 | CDN 친화성 | 청크 단위 전송 |
---|---|---|---|---|---|
MP4 | HTTP | 방화벽 문제 없음 | 지원 안됨 | 제한적 (전체 파일 캐싱) | 지원 안됨 (Range 요청 가능) |
RTMP | 전용 프로토콜 | 방화벽에 의해 차단될 가능성 높음 | 제한적 | 제한적 | 실시간 전송 |
DASH | HTTP | 방화벽 문제 없음 | 지원 | 가능 | 지원 |
HLS | HTTP | 방화벽 문제 없음 | 강력한 지원 | 매우 유리 | 지원 |
HLS에서 m3u8 파일이 중요한 이유
HLS 스트리밍에서 m3u8 파일은 매우 중요한 역할을 합니다. HLS는 미디어를 작은 조각(청크)으로 나누어 전송하는 방식이며, 이 청크들을 관리하고 재생할 수 있도록 하는 플레이리스트 파일이 바로 m3u8입니다.
하지만 HLS가 곧 m3u8 파일을 의미하는 것은 아닙니다. HLS는 특정한 파일 형식에 종속되지 않으며, JSON이나 XML 기반의 플레이리스트 형식을 사용할 수도 있습니다. 그럼에도 불구하고 대부분의 HLS 스트리밍 서비스에서는 m3u8 파일이 표준처럼 사용되는데, 이는 다음과 같은 이유 때문입니다:
- 단순한 텍스트 기반 포맷: 사람이 읽고 수정하기 용이하며, 새로운 해상도나 비트레이트를 쉽게 추가할 수 있음
- 광범위한 지원: Apple의 HLS 프로토콜이 m3u8을 기본적으로 사용하도록 설계되었으며, 대부분의 플레이어 및 스트리밍 서비스에서 기본적으로 지원
- CDN 및 캐싱 친화적: HTTP 기반의 m3u8 파일은 정적 파일처럼 다룰 수 있어 효율적인 배포가 가능
HLS의 주요 포맷과 m3u8 파일 구조
#EXTM3U
#EXT-X-STREAM-INF:BANDWIDTH=800000,RESOLUTION=640x360
https://example.com/low/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=1400000,RESOLUTION=1280x720
https://example.com/mid/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=2800000,RESOLUTION=1920x1080
https://example.com/high/index.m3u8
이처럼 HLS는 여러 해상도와 비트레이트를 지원하며, m3u8 파일을 이용해 각 스트림을 정의하고 관리합니다. 즉, m3u8은 HLS 스트리밍을 원활하게 작동시키는 핵심적인 구성 요소 중 하나이지만, 필수적인 유일한 방식은 아닙니다.
👇 아래 시퀀스 다이어그램은 HLS 스트리밍의 기본적인 동작 흐름을 보여줍니다. 클라이언트가 서버에서 m3u8 파일을 받아온 후, 적응형 비트레이트(ABR)를 기반으로 여러 해상도의 .ts 청크를 요청하고 재생하는 과정을 시각적으로 표현하였습니다.

🚨 Safari에서 MSE 방식 사용 및 iOS 특정 버전에서 발생하는 문제 🚨
일관성을 유지하기 위해 Safari에서도 MSE 방식을 활용하여 HLS.js를 통한 스트리밍을 적용했습니다. 하지만 iOS 특정 하위 버전(15, 16)에서 HLS.js 기반 MSE 스트리밍이 정상적으로 작동하지 않는 문제가 발견되었습니다.
⚠️ 원인
- iOS 15, 16에서도 MSE(Media Source Extensions) 지원됨으로 표시되지만,
- HLS.js 기반 MSE 스트리밍이 불안정하여 정상 재생되지 않음
- iOS 17부터 HLS.js를 활용한 MSE 스트리밍이 안정적으로 동작함
🔷 적용 방식
✅ iOS 15~16: Hls.js ❌
→ 네이티브 HLS (video.src = url
) ✅
이를 통해 iOS의 경우 네이티브 HLS를 활용하여 스트리밍하도록 예외처리하여 문제를 해결하였습니다.
결론
HLS는 라이브 스트리밍과 VOD(Video on Demand) 콘텐츠에도 최적화되어 있어 사용자에게 안정적이고 원활한 미디어 경험을 제공합니다. 특히 CDN 캐싱이 가능하다는 점이 가장 중요한 요소로 작용합니다. 이러한 장점을 봤을 때 사용하지 않을 이유가 없습니다.
Safari에서는 기본 지원되지만 다른 브라우저에서는 HLS.js 같은 라이브러리를 활용해야 합니다. 또한, iOS 15~16 버전에서는 HLS.js 기반 MSE 스트리밍이 원활하게 동작하지 않으므로, 네이티브 HLS를 활용하여 해결하는 것이 바람직합니다.