30분짜리 하나가 조각 181개. 10초 보고 끄면 1.18MB, 끝까지 보면 213MB다.
애플이 시험용으로 공개해 둔 스트림을 받아서 세어 봤다. 30분짜리 영상 하나가 조각 181개로 나뉘어 있었다. 조각 하나는 9.97667초이고, 마지막 하나만 4.20333초다.
9.97667 × 180 + 4.20333 = 1,800.0초 = 30분
목록에 적힌 길이를 모두 더하면 정확히 30분이 된다. 조각 파일의 확장자는 .ts, MPEG-2 전송 스트림이다. 하나를 받아서 열어 보니 H.264 영상과 AAC 소리가 들어 있었고, 받을 때 서버가 붙여 준 형식은 video/MP2T였다.
조각만 있으면 순서를 알 수 없다. 그래서 목록 파일이 따로 있고, 확장자는 .m3u8이다. 규격은 이것을 「UTF-8 text files containing URIs and descriptive tags」라고 적는다. 말 그대로 글자다. 이 영상의 목록 파일은 6,701바이트였다. 7KB도 안 된다.
안은 이렇게 생겼다.
#EXTM3U
#EXT-X-TARGETDURATION:10
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-PLAYLIST-TYPE:VOD
#EXTINF:9.97667,
fileSequence0.ts
#EXTINF:9.97667,
fileSequence1.ts
…(181번 반복)
#EXTINF:4.20333,
fileSequence180.ts
#EXT-X-ENDLIST
길이를 적고, 파일 이름을 적는다. 그게 전부다. 재생기는 이 목록을 읽고 조각을 차례로 받는다.
태그 몇 개의 뜻은 규격에 이렇게 적혀 있다.
| 태그 | 규격의 정의 |
|---|---|
#EXTM3U | 「MUST be the first line of every Media Playlist and every Master Playlist」 |
#EXT-X-TARGETDURATION | 「specifies the maximum Media Segment duration」 (필수) |
#EXTINF | 「specifies the duration of a Media Segment」 (조각마다 필수) |
#EXT-X-ENDLIST | 「indicates that no more Media Segments will be added to the Media Playlist file」 |
조각 181개의 용량을 하나씩 전부 재서 더했다. 추정이 아니다.
| 값 | |
|---|---|
| 전체 합계 | 223,206,948바이트 = 212.9MB |
| 조각 평균 | 1,233,187바이트 ≈ 1.18MB |
| 가장 작은 조각 / 가장 큰 조각 | 0.49MB / 1.21MB |
| 첫 조각 | 1,238,732바이트 |
| 비율 | 223,206,948 ÷ 1,238,732 = 180배 |
가장 작은 조각이 0.49MB인 것은 마지막 조각이 4.2초로 짧기 때문이다. 10초만 보고 끄면 1.18MB를 받은 것이고, 끝까지 보면 213MB를 받는다. 180배 차이다. 파일 하나를 통째로 받는 방식이었다면 10초를 보려고 213MB를 받아야 했다.
목록 위에 목록이 하나 더 있다. 511바이트짜리이고, 조각은 하나도 없이 다른 목록들의 주소만 적혀 있다. 화질 다섯 단이 들어 있었다.
| BANDWIDTH (초당 비트) | 목록 | CODECS |
|---|---|---|
| 41,457 | gear0 | mp4a.40.2 (소리만) |
| 232,370 | gear1 | mp4a.40.2, avc1.4d4015 |
| 649,879 | gear2 | mp4a.40.2, avc1.4d401e |
| 991,714 | gear3 | mp4a.40.2, avc1.4d401e |
| 1,927,833 | gear4 | mp4a.40.2, avc1.4d401f |
규격은 BANDWIDTH를 구간의 최고 비트율(peak segment bit rate)로 정의한다. 네트워크가 느려지면 재생기가 낮은 쪽 목록으로 갈아탄다. 규격은 「Clients should switch between different Variant Streams to adapt to network conditions」라고만 적고, 어떻게 고를지는 「beyond the scope of this document」라며 정해 두지 않았다. 그래서 재생기마다 다르게 동작한다.
목록 끝의 #EXT-X-ENDLIST는 「조각이 더 늘지 않는다」는 뜻이다. 다 만들어진 영상에는 이 표시가 있고, 생중계에는 없다. 표시가 없으면 재생기는 목록을 주기적으로 다시 받아 새 조각이 붙었는지 확인한다. 규격은 「The client MUST periodically reload a Media Playlist file to learn what media is currently available」라고 적는다.
서버가 새 목록을 내놓는 간격도 정해 두었다. 이전 판으로부터 목표 길이의 0.5배보다 이르지 않게, 1.5배보다 늦지 않게다.
서버에 특별한 것은 없다. 파일을 쪼개서 놔둔 것뿐이고, 보통의 웹 서버가 그대로 내려 준다. 스트리밍 전용 서버가 필요하지 않다는 점이 이 방식이 퍼진 이유 중 하나다.
.ts만 있는 것은 아니다. 규격은 조각난 MP4(fragmented MP4), 묶음 오디오(AAC/ADTS·MP3·AC-3·E-AC-3), 자막용 WebVTT도 허용한다. 요즘은 fMP4를 쓰는 곳이 많다. 「Transport of other media file formats is not defined」라고만 적혀 있다B=https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_4x3
curl -s $B/bipbop_4x3_variant.m3u8 # 마스터 목록 511B
curl -s $B/gear3/prog_index.m3u8 # 조각 목록 6,701B
curl -sI $B/gear3/fileSequence0.ts # 조각 하나 1,238,732B
목록 파일은 그냥 텍스트라 브라우저 주소창에 넣어도 내용이 보인다.