[2026] MPEG-DASH 완전 참조 — MPD(ISO 23009-1) · 세그멘트 · CENC/DRM · 플레이어
이 글의 핵심
ISO/IEC 23009-1의 MPD·세그멘트 주소 지정(템플릿·리스트·베이스)부터 CENC/DRM, DASH-IF 프로파일, UHD, 라이브/VoD, 캐싱·바이트 범위, dash.js·Shaka·ExoPlayer·AVPlayer 구현까지 한 번에 짚는 DASH 실무 참조서입니다.
MPEG-Dynamic Adaptive Streaming over HTTP(MPEG-DASH, 이하 DASH)는 ISO/IEC 23009-1이 정의한 적응형 HTTP 스트리밍 기술로, 콘텐츠를 세그멘트(일반적으로 fMP4)로 나누어 전송하고, MPD(Manifest, Media Presentation Description)에 비트레이트·해상도·시간정렬 등 메타를 기술해 플레이어가 ABR(Adaptive Bitrate)을 수행하도록 합니다. 본문은 MPD·세그멘트 전달 모델을 23009-1 관점에서 정리하고, FFmpeg·Bento4(MP4Box)·Shaka Packager로의 패키징, 다중 기간(광고)·다국어 오디오·자막, CENC/DRM·DASH-IF·UHD, 최적화(정렬·Range·캐시), dash.js·Shaka·ExoPlayer·AVPlayer 구현 힌트를 한 문서에 묶었습니다. 세부 키 길이·KID·라이선스 API는 벤더·보안 사항이므로, 여기서는 프로토콜/패키징/플레이어 측면에 초점을 둡니다.
규범·참고:
ISO/IEC 23009-1(MPEG-DASH MPD, 세그멘트, 프로파일), CENC: ISO/IEC 23001-7, 라이선스/키 교환은 EME·각 DRM 벤더 문서(예: Widevine, PlayReady)를 병행하십시오.
1. MPD(미디어 프레젠테이션 설명)의 역할
MPD는 하나의 프레젠테이션을 Period들의 시퀀스(타임라인) 로 표현하고, 각 기간 안에서 콘텐츠의 변형(Representation)·초기화/미디어 세그멘트를 어떻게 가져올지(템플릿, 목록, 베이스)를 XML로 기술합니다. 표준 XML 네임스페이스 urn:mpeg:dash:schema:mpd:2011 (문서/버전에 따른 URN 변형은 MPD profiles·도구 출력을 확인) 하에, 루트 MPD 요소가 전체 프로파일·이동(라이브 여부)·시간 힌트를 담고, 이하 Period → AdaptationSet → Representation → 세그멘트 정보(SegmentBase / SegmentList / SegmentTemplate)의 계층이 이어집니다.
MPD@type이 static이면 일반적으로 VoD(온디맨드)(미리 생성된 MPD)에 가깝고, dynamic이면 라이브/타임이동 가능한 MPD이며(업데이트 주기·버퍼 깊이 등), 플레이어는 MPD 재획득(폴링) 및 라이브 엣지에 맞춰 세그멘트를 요청합니다. availabilityStartTime·timeShiftBufferDepth·suggestedPresentationDelay 등의 의미는 23009-1 절(동적 MPD)을 따르며, 구현·플레이어는 이를 ABR·시크·라이브 딜레이에 반영합니다.
핵심 루트 속성(개념 정리):
| 속성(예) | 용도 |
|---|---|
type | static / dynamic — VoD·라이브·타임쉬프트 모드 구분(개념적) |
profiles | 인터롭(예: DASH-IF) 프로파일 URN, 도구/플레이어 호환 힌트 |
minBufferTime | 최소 버퍼(미디어 타임) — 플레이어 훈·언더런과 연관(휴리스틱) |
mediaPresentationDuration | 전체 프레젠테이션 길이(필요 시) |
availabilityStartTime / timeShiftBufferDepth / minimumUpdatePeriod | 동적 MPD·캐치업·MPD 갱신 주기 |
ProgramInformation, BaseURL(serviceLocation, priority, weight), Location 등 전역 메타/리다이렉트/다중 BaseURL은 CDN·페일오버·지역 전략에 쓰입니다. UTCTiming은 시계 동기(예: NTP/HTTP), 라이브에서 바이트·시간 정합에 중요할 수 있습니다.
2. Period · AdaptationSet · Representation
2.1 Period
Period는 연속(또는 메타에 의한 연속) 타임라인 상의 한 구간입니다. 다중 Period는 광고 삽입·챕터·서로 다른 권한 등으로 프레젠테이션을 쪼갤 때 사용하며, 인접 Period 간 끊김 없는 연속을 맞추려면 start·duration·미디어 내부 타임스탬프를 패키징 파이프라인에서 정확히 정렬해야 합니다(실무에서 가장 흔한 이슈 중 하나). BaseURL을 Period 수준에 둬 해당 기간만 다른 CDN/경로를 쓰기도 합니다. EventStream / InbandEventStream / SCTE-35 관련 캐리지(프로필/도구에 따라)는 광고 마커·동기에 연결됩니다.
2.2 AdaptationSet
AdaptationSet는 하나의 미디어 유형(비디오/오디오/자막) 이거나 같은 유형이지만 대체(예: 여러 언어 트랙) 을 논리적으로 묶습니다. contentType(video·audio·text), mimeType, codecs(*RFC 6381* 코덱 스트링), lang, label, role(예: main, dub, commentary 스킴) 등 클라이언트 UI·초기 선택에 쓰입니다. 같은 AdaptationSet 안의 Representation은 ABR 스위칭 후보(비슷한 미디어, 시간 정렬)여야 합니다(프로필/도구가 요구하는 정렬 규칙에 유의). 다중 오디오 트랙은 언어·역할별로 AdaptationSet를 분리하거나, Representation·Label·lang로 구분하는 패턴이 모두 등장하며, 플레이어가 AdaptationSet 단위/트랙 단위로 선택할 수 있어야 합니다.
2.3 Representation
Representation은 구체 품질(비트레이트, 해상도, 프레임레이트 등의 조합) 입니다. id, bandwidth, width/height, frameRate, codecs 등이 ABR·디코딩·UI에 사용됩니다. SegmentTemplate / SegmentList / SegmentBase는 대부분 여기(또는 상위)에 위치하며, 초기화 세그멘트(Initialization)와 미디어 세그멘트 경로, 타임스케일 timescale, 세그멘트 길이를 정의합니다. DASH-IF/도구는 fMP4 + in-band(moof/mdat) 또는 독립 인덱스 조합을 권하는 경우가 많습니다.
3. 세그멘트 지정: SegmentBase vs SegmentList vs SegmentTemplate
| 방식 | 요약 | 전형적 사용 |
|---|---|---|
| SegmentBase | 단일 미디어 리소스 + Range 또는 indexRange로 sidx(인덱스)·세그멘트 경계 | 단일 mp4 + sidx, 또는 작은 수의 조각 |
| SegmentList | 명시 URL 목록(SegmentURL 등) + 총 duration/timescale, 필요 시 initialization 소스 | URL이 비규칙·소수일 때, 도구·CMS가 리스트를 생성할 때 |
| SegmentTemplate | $Number$ / $Time$ / $RepresentationID$ 등 템플릿으로 세그멘트 이름 규칙 기술 | 대용량 VoD/라이브, fMP4 효율·CDN 캐싱에 유리 |
SegmentTemplate의 duration(timescale 기준)으로 고정 GOP·세그 길이를 드러내고, 라이브에서는 SegmentTimeline + $Time$ 기반 템플릿으로 가변 세그 길이를 기술할 수 있습니다(도구/프로필·실제 미디어가 일치해야 함).
Initialization / indexRange / Range / BaseURL: 초기화 세그멘트(보통 fMP4 ftyp+moov)와 미디어 세그멘트(보통 moof+mdat)를 분리해 두는 패턴이 일반적입니다. Range 기반(단일 파일) 은 바이트 범위(HTTP 206, Accept-Ranges) 를 전제로 하며, 캐시·CDN과 잘 맞을 때 한 파일 다중 구간 효율이 납니다(아래 10절).
4. MPD·세그멘트 XML 주요 요소(참고 목록)
아래는 23009-1 MPD에서 자주 쓰이는/도구가 출력하는 요소·속성의 역할을 참고용으로 압축한 것입니다(전 스키마의 모든 항목을 나열하는 것은 본 문서의 범위를 넘으므로, 식별·확장·XLink 등은 표준 문서를 병행하십시오).
MPD하위·공통
ProgramInformation — 제목·저작; BaseURL — 상대/절대 URL, 다중 BaseURL로 로드밸런싱/페일오버; Location — MPD 이전; UTCTiming — 시간 동기; ServiceDescription(프로필/확장)
Period: id, start, duration — 타임라인 슬롯; BaseURL — 기간 전용 베이스; EventStream — 캐리지 이벤트
AdaptationSet: id, contentType, lang, mimeType, codecs, segmentAlignment, subsegmentAlignment, bitstreamSwitching — ABR/트랙 스위칭 호환; Accessibility·Role·AudioChannelConfiguration — 접근·역할; SupplementalProperty / EssentialProperty — UHD HDR, DVB, CENC 키 식별자(URN) 메타
Representation: id, bandwidth, width, height, frameRate, codecs — ABR/디스플레이/디코딩; SubRepresentation, Subsegment, BaseURL — 세부 조각(드물게)
세그멘트 체인
SegmentBase — IndexRange·initialisation(영국식 철자) / Initialization / RepresentationIndex; SegmentList — SegmentTimeline·SegmentURL; SegmentTemplate — media, initialization, duration 또는 SegmentTimeline, @timescale
S 요소(타임라인 SegmentTimeline 내) — t, d 반복 — 가변 세그 길이, 이름 없는(묵시) 세그먼트 연속
AdaptationSet 내 ContentComponent — 컴포넌트 식별; AssetIdentifier·ContentProtection 는 CENC/DRM 메타(아래 8절)
4.1 MPD·Period·AdaptationSet·Representation 요소·속성(23009-1·실무 정렬)
표 1. MPD 루트(대표) — 스키마·에디션에 따른 선택/필수·이름(영국/미국 initialisation) 은 규범 문서를 확인하십시오.
| 요소/속성 | 설명(요지) |
|---|---|
MPD | 루트. type, profiles, minBufferTime, mediaPresentationDuration 등 프레젠테이션 전체 |
profiles (URN 목록) | DASH-IF/방송(예: HbbTV) 인터롭 식별 — 플레이어·검증기 입장 |
minimumUpdatePeriod | 동적 MPD 갱신 주기(미디어 타임 기준) — 최솟 의미(사양) |
minBufferTime | 최소 버퍼(미디어 타임) — ABR/언더런 휴리스틱 |
timeShiftBufferDepth | 타임쉬프트(라이브) 가능 최대 깊이 |
suggestedPresentationDelay | 라이브 엣지 대 지연 권고 — 저지연 vs 안정 절충 |
maxSegmentDuration | 최댓 세그(지시) — 도구/검사에 힌트 |
ProgramInformation | 제목, 저자, copyright 등 메타 |
BaseURL + @serviceLocation @priority @weight | 다중 베이스 — CDN·A/B·지역·페일오버 |
Location | MPD 새 URL — 이동/리다이렉트 |
UTCTiming + @value | NTP/HTTP 타임 — 동적/라이브 시계 |
ServiceDescription | 확장/프로필(예: LL-DASH 관련) 서비스 메타 |
표 2. Period
| 요소/속성 | 설명(요지) |
|---|---|
id / start / duration | 슬롯 식별·시작(미디어 프레젠테이션 타임라인) |
BaseURL | 해당 Period만 다른 오리진 |
EventStream / Event | MPD 이벤트 — 광고·캡션·동기 |
InbandEventStream | fMP4 인밴드 이벤트 (프로필) |
SCTE-35 캐리지 | 방송/광고 시그널 (확장·DASH-IF/방송) |
표 3. AdaptationSet
| 요소/속성 | 설명(요지) |
|---|---|
contentType | video / audio / text / application 등 — 초기 라우팅 |
segmentAlignment / subsegmentAlignment | ABR·스위칭 정렬 요구 (값 true 등) |
bitstreamSwitching | 코덱 전환(제한) — H.264 SPS 공유 등 패턴 |
mimeType / codecs | RFC 6381 코덱 문자열 — avc1, hvc1, mp4a.40.2 등 |
lang / label / Role / Accessibility | UI·접근성·역할(main, subtitle, alternate 등) |
ContentComponent / id | 다중 컴포넌트(예: 5.1+보조) 구분 |
FramePacking / AudioChannelConfiguration | 3D·채널 맵(URN·값) — UHD/Immersive |
EssentialProperty / SupplementalProperty | 필수/부가 URN(예: HDR 메타, CENC KID) |
ContentProtection + @schemeIdUri + cenc:default_KID + pssh (Base64) | DRM/라이선스 연결 |
InbandEventStream | (세트 수준) 이벤트 트랙 신호 |
표 4. Representation
| 요소/속성 | 설명(요지) |
|---|---|
id, bandwidth | ABR 선택·BPS (bits/s, 일반) |
qualityRanking | (선택) 품질 순위 힌트 |
width / height / frameRate / sar | 디스플레이·프레임·샘플 비율 |
codecs / mimeType | 로컬 오버라이드 (상위에서 상속) |
BaseURL | 레벨 전용 URL |
SegmentBase / SegmentList / SegmentTemplate | 세그 주소 (아래 3절) |
SubRepresentation / Subsegment | 서브 품질(드문 미세 ABR) |
표 5. SegmentBase / SegmentList / SegmentTemplate
| 요소/속성 | 설명(요지) |
|---|---|
SegmentBase@timescale | 미디어 클럭 (틱/초) |
Initialization@sourceURL / @range | 초기화 fMP4 URL / Range |
RepresentationIndex / indexRange / SegmentBase@indexRange | sidx·인덱스 바이트 구간 |
SegmentList@duration / timescale | 균일 세그 길이 (없으면 SegmentURL·타임라인) |
SegmentURL@mediaRange / @indexRange | 개별 바이트 구간 |
SegmentTemplate@media / initialization | $Number$ $Time$ $RepresentationID$ $Bandwidth$ 등 치환 |
SegmentTemplate@duration | 고정 세그 길이(timescale) |
SegmentTemplate.SegmentTimeline + S@t S@d S@r | 가변·라이브 열; r=반복 횟수(−1은 to end 의미 버전별) |
Metrics / Reporting (QoE), Failsafe성 URL 변형, XLink 주기 삽입 — 23009-1 후속 에디션·DASH-IF 문서에 자세히 있습니다. “모든” 요소를 이 표 하나에 넣는 대신, 스키마(XSD)와 23009-1 절을 1차 근거로 삼으십시오.
4.2 정적 MPD(최소) 예: SegmentTemplate + fMP4
<?xml version="1.0" encoding="UTF-8"?>
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011"
type="static"
minBufferTime="PT2S"
profiles="urn:mpeg:dash:profile:isoff-on-demand:2011,urn:dashif:adaption-set-switching:2016"
mediaPresentationDuration="PT0H10M0S">
<Period>
<AdaptationSet contentType="video" mimeType="video/mp4" segmentAlignment="true" par="16:9">
<Representation id="v0" width="1280" height="720" bandwidth="3000000" codecs="avc1.4d401f" frameRate="30">
<SegmentTemplate
timescale="90000"
media="v720_$Number$.m4s"
initialization="v720_init.mp4"
startNumber="1"
duration="180000" />
<!-- 180000/90000 = 2s @ 90k timescale; 실제 콘텐츠·GOP와 일치시킬 것 -->
</Representation>
</AdaptationSet>
</Period>
</MPD>
5. 타임라인 관리
미디어 타임은 timescale로 정수화됩니다(예: 90000, 48000, 1000). SegmentTemplate+$Time$·SegmentTimeline·S@t·S@d·S@r 반복은 라이브/가변 GOP에 쓰입니다. 다중 Period, SCTE-35, 광고는 각 Period 경계에서 강제 플러시/키프레임이 없으면 끊김·A/V 드리프트가 생깁니다. 정렬(alignment): DASH-IF/프로필이 요구하듯, 같은 타임윈도우의 비디오/오디오/자막 세그 경계를 GOP·캡처와 맞추고, 동일 MPD 내 초 단위 duration·실제 fMP4 타임스탬프를 교차검증하십시오.
MPEG-DASH IF: 상호운용을 위한 가이드라인·검증 도구가 DASH-IF에 정리돼 있으며, 프로파일 URN이
MPD@profiles에 명시되는 경우가 많습니다.
6. 실전: FFmpeg, MP4Box, Shaka Packager(개요)
이하 명령은 환경·빌드에 따라 옵션이 다릅니다. --help·공식 문서·출력 MPD 검증을 반드시 하십시오.
6.1 FFmpeg로 DASH(fMP4) 생성(예시)
ffmpeg이 DASH 뮤덱서·CENC 옵션을 빌드에 포함한 경우(배포판에 따라 libxml2·openssl 연계):
# 예: 비디오+오디오를 DASH(비트레이트 2개) + fMP4
ffmpeg -y -i input.mp4 -filter_complex \
"[0:v]split=2[v1][v2];[v1]scale=1280:-1[vout1];[v2]scale=854:-1[vout2]" \
-map "[vout1]" -map 0:a -c:v:0 libx264 -b:v:0 3000k -c:a:0 aac -b:a:0 128k \
-f dash -use_timeline 1 -use_template 1 -window_size 5 -remove_at_exit 1 \
-init_seg_name "init-stream$RepresentationID$.$ext$" \
-media_seg_name "chunk-stream$RepresentationID$-$Number%05d$.$ext$" \
-adaptation_sets "id=0,streams=v id=1,streams=a" \
./out_dash/master.mpd
설명(요지): -f dash는 MPD+세그멘트를 씁니다. adaptation_sets로 비디오/오디오를 분리한 AdaptationSet에 매핑합니다. init_seg_name·media_seg_name이 MP4Box의 SegmentTemplate과 유사한 템플릿 역할을 합니다. libx264·비트레이트·GOP(예: -g, -keyint_min)는 ABR/세그 길이에 직접 영향—2초~6초 GOP는 흔한 출발점입니다(콘텐츠·시나리오별 튜닝).
6.2 Bento4 MP4Box(예시)
Bento4의 mp4dash(또는 mp4box DASH 래퍼)로 MP4를 DASH 패키징:
# 예: 이미 fMP4로 변환한 트랙을 mp4dash로 (도구 래퍼/옵션은 배포에 따름)
mp4dash -o out_dash video_1080p.mp4 video_720p.mp4 -a audio_128k.mp4
mp4fragment + mp4dash 파이프라인으로 GOP·tfdt·세그 경계를 맞추는 전처리가 자주 따릅니다. Bento4 문서의 DASH/fragment 절을 확인하십시오.
6.3 Shaka Packager(예시)
packager는 CENC, 다중 기간(제한), 자막 등 프로덕션에서 널리 쓰입니다:
# 예: ABR 비디오(대표) + 오디오 + VTT(도구/버전에 따라 --stream 옵션명 상이)
packager in=input.mp4,stream=video,init_segment=init_v.mp4,segment_template=seg_v_\$Number\$.m4s \
in=input_en.mp4,stream=audio,init_segment=init_a_en.mp4,segment_template=seg_a_en_\$Number\$.m4s \
--mpd_output master.mpd
--enable_raw_key_encryption·--protection_scheme·--keys 등 CENC/DRM는 정책에 따라 widevine/playready 스트림 디스크립터를 추가합니다(키·KID는 비밀). 광고(다중 Period) 는 MPEG-DASH SCTE 확장 / VMAP·SSAI·MPE 파이프라인이 함께가 아니면 MPD 만으로는 부족한 경우가 많습니다(원본/SSAI/팩키저 스택 전체 동기).
6.4 MP4Box(Bento4): fMP4 분할 후 DASH(전형)
원본이 하나의 progressive MP4일 때, GOP/세그 정합을 위해 끊는 단계를 둡니다(도구/버전·매뉴얼 우선):
# 예(개략): 비디오를 고정 duration fragment → DASH
mp4fragment --fragment-duration 2000 unfragmented_v.mp4 frag_v.m4f
# 오디오도 동일 정책(샘플레이트/프레임**과** **정렬**)
mp4fragment --fragment-duration 2000 unfragmented_a.m4a frag_a.m4f
# 이후 mp4dash로 MPD+세그 출력 (Bento4 문서의 mp4dash 옵션 확인)
mp4dash -o ./dash_out frag_v.m4f frag_a.m4f
--fragment-duration(ms)은 2초 GOP 등 정책과 맞출 것; A/V 드리프트는 최종 MPD·실재생 검사로 확인합니다.
6.5 FFmpeg: 다중 비디오 Representation(스케일 + DASH) 개략
한 입력에서 2개 해상도를 만든 뒤·오디오는 공유·-f dash 한 번에 묶는 형태(빌드/버전에 따라 -adaptation_sets 문법·stream 번호 확인):
ffmpeg -y -i input.mkv -filter_complex \
"[0:v]split=2[v1][v2];[v1]scale=-2:1080[vo1];[v2]scale=-2:720[vo2]" \
-map "[vo1]" -map 0:a? -c:v:0 libx264 -b:v:0 5000k -g 60 -keyint_min 60 -c:a:0 aac -b:a:0 128k \
-map "[vo2]" -map 0:a? -c:v:1 libx264 -b:v:1 2500k -g 60 -keyint_min 60 -c:a:1 aac -b:a:1 128k \
-f dash -use_template 1 -use_timeline 1 -window_size 5 \
-init_seg_name "init-$RepresentationID$.$ext$" -media_seg_name "seg-$RepresentationID$-$Number%05d$.$ext$" \
-adaptation_sets "id=0,streams=0,1 id=1,streams=2,3" \
out_multi/master.mpd
-map 순서가 0: 첫 비디오, 1: 첫 오디오, 2: 둘째 비디오, 3: 둘째 오디오이면 위처럼 비+오 쌍으로 AdaptationSet 두 개에 매핑합니다(출력·-loglevel로 인덱스 검증). 필요 시 -adaptation_sets 문법은 빌드 도움말 우선입니다. 같은 -g·keyint_min은 퍼 Representation 간 세그 정렬에 유리합니다.
6.6 Shaka Packager: WebVTT(경로) + CENC(개략, 키는 비밀)
# VTT(파일) + 비디오/오디오. 정확한 --stream, drm 플래그는 packager --help
packager \
in=main.mp4,stream=video,init_segment=video_init.m4s,segment_template=video_$Number$.m4s \
in=main_en.mp4,stream=audio,init_segment=audio_init.m4s,segment_template=audio_$Number$.m4s \
in=captions.vtt,stream=text,init_segment=captions_init.m4s,segment_template=captions_$Number$.m4s \
--mpd_output master.mpd
# CENC(예시형 — 실 키/KID/라이선스는 운영 환경에서만)
# packager ... --enable_raw_key_encryption --keys label=A:key_id=HEX:KEYHEX: ...
stream=text·초기화/세그 네이밍은 도구·DASH-IF 자막 프로파일에 맞게 조정합니다.
7. 다중 Period(광고) · 다중 오디오 · 자막(WebVTT, TTML)
- 다중
Period: 프리롤/미드롤을 서로 다른 인코딩/권한의 Period로 쪼갤 때, 끝·시작 타임이 연속이어야 시크/ABR이 안정됩니다(키프레임·오디오 프레임 정렬).Event·SCTE-35인-밴드/아웃-오브-밴드는 광고 삽입·동기와 함께 읽을 것. - 다중 오디오:
AdaptationSet@lang·Role·Label로 언어/보조를 구분, 플레이어가setTextTrack/selectAudio유사 API로 전환(구현체마다 트랙 모델이 다름). - 자막:
mimeTypetext/vtt·application/mp4+webvtt(시그널) 또는 STPP/TTML in MP4(EBU-TT 등) — DASH-IF 가이드·콘솔(방송) 요구에 맞게 캡션 트랙을 fMP4에 끼우거나 외부 WebVTT를BaseURL+SegmentList로 제공하십시오(플레이어·DRM 정책 주의).
다 Period MPD(개략): Period@duration·start로 메인+광고를 시간상 이어 붙입니다(실 패키징에선 광고 MPD/세그를 SSAI/팩키저가 합성하기도 합니다).
<MPD type="static" minBufferTime="PT2S" mediaPresentationDuration="PT10M" xmlns="urn:mpeg:dash:schema:mpd:2011">
<Period id="main" duration="PT8M">
<AdaptationSet id="0" contentType="video" mimeType="video/mp4">...</AdaptationSet>
</Period>
<Period id="ad" duration="PT30S" start="PT8M">
<AdaptationSet id="0" contentType="video" mimeType="video/mp4">...</AdaptationSet>
</Period>
<Period id="post" start="PT8M30S" duration="PT1M30S">
<AdaptationSet id="0" contentType="video" mimeType="video/mp4">...</AdaptationSet>
</Period>
</MPD>
start/duration 조합은 23009-1 규칙(누락 시 암시 연속) 내에서 일관되게 쓰십시오(도구·검증기 오류 방지).
다국어 오디오 MPD(개략): AdaptationSet 둘·lang 분리가 가장 명시적입니다.
<Period>
<AdaptationSet id="0" contentType="audio" lang="ko" mimeType="audio/mp4" codecs="mp4a.40.2">...</AdaptationSet>
<AdaptationSet id="1" contentType="audio" lang="en" mimeType="audio/mp4" codecs="mp4a.40.2">...</AdaptationSet>
<AdaptationSet id="2" contentType="video" mimeType="video/mp4">...</AdaptationSet>
</Period>
WebVTT vs TTML(in MP4): WebVTT는 웹/피어·가벼움; TTML/IMSC/STPP는 방송/규제·XML 워크플로에 많음. CMAF·DASH-IF 캡션 IOP 문서에 권 서브 타입이 정리되어 있습니다. 썸네일/스프라이트는 별 AdaptationSet·image·MPEG-DASH IF 이미지 확장 등—Shaka·dash.js 릴리스 노트를 확인하십시오.
8. CENC(공통 암호화)와 DRM(개요)
CENC(Common Encryption)는 fMP4 샘플을 tenc·pssh·senc·KID로 암호화해 콘텐츠를 공통 포맷으로 둡니다. 납품은 EME(Encrypted Media Extensions) + CDM(예: Widevine, PlayReady, FairPlay); KID/키·라이선스 서버·권한은 엔드투엔드로 설계합니다. MPD ContentProtection@schemeIdUri(urn:uuid:...)·cenc:default_KID·pssh(Base64)는 CDM/플레이어가 키 요청을 연결하는 단서입니다. 서버 측 SPEKE·MSS·KMS 연동은 벤더 가이드가 우선합니다.
Widevine/PlayReady: MPD ContentProtection 중복 기입(멀티 DRM)으로 다양한 클라이언트에 대응. L1/L3(Widevine) 등 보안·해상도 cap은 정책입니다. iOS는 HLS가 주류일 때 DASH+FairPlay 조합 가능 여부를 기기/버전·정책으로 판단합니다.
9. DASH-IF 프로파일 · UHD/4K · Live vs On-Demand
- DASH-IF(예: DASH-IF IOP): fMP4·
profilesURN·최소 요구(코덱, 세그, 자막, 콘솔) — 접수·인증 시 필독입니다. - UHD/4K: HEVC/AV1
codecs·10bit·HDR(SupplementalPropertyPQ/HLG, Dolby 메타) — 디코딩·HDCP·DRM 레벨·최대 해상도 제한 동시 고려. - On-Demand:
MPD@type=static·가능하면 MPD/세그 불변 + 캐시 길게. - Live:
dynamic·minimumUpdatePeriod·availabilityStartTime·SegmentTimeline갱신·딜레이suggestedPresentationDelay·버퍼timeShiftBufferDepth— 플레이어가 MPD·세그 폴링; LL-HLS/저지연과 비교해 DASH-LL(저지연) 프로필/도구는 시나리오에 따라 추가됩니다(라이브 스포츠·대화형).
10. 최적화: 정렬, Range, 인덱스, 캐싱
- 세그멘트 정렬: 비트레이트 간 같은 미디어 타임 경계 — GOP/키프레임/오디오 프레임 동기. 도구
chunk, fixed GOP, 2^n×fpstimescale권장 패턴만 참고. - Byte Range(HTTP 206):
SegmentBase@indexRange+Range·sidx로 한 파일에서 초/중 구간—캐시 hit·HDD/SSD I/O—절충; 단일 대용량 vs 다중 fMP4 파일 Trade-off. - Index Segment / sidx: Movie Fragment 인덱스— 시크·부분 GET 효율; DASH-IF/도구는 fMP4+sidx 조합을 문서화.
- 캐싱: MPD(라이브는 짧은 TTL·
Cache-Control: no-cache혼합),init길게, 미디어 세그immutable+versioned URL(주로$Number$증가) — CDN Purge·쿼리 스트링 주의; CORS·Accept-Ranges·CORS+Range 조합은 크로스 오리진 플레이어 필수.
11. 플레이어: dash.js, Shaka, ExoPlayer, AVPlayer(요지)
- dash.js(브라우저): 23009-1 MPD 파싱·
SegmentBase/List/Template해석·ABR(Throughput/BOLA·버전에 따름) 내장;MediaPlayer().create().initialize(video, src, true); 보호콘텐츠는 EME+Widevine/PlayReadyprotectionData·서버 URL;TextTrack·자막; 로깅Debug/ 이벤트on(dashjs.MediaPlayer.events.*); 퍼포먼스setFastSwitchEnabled·buffer·abrlimitBitrateByPortal·useDeadTimeLatency·initialBitrate·autoSwitchBitrate등 — API는 메이저 간 변하므로 공식 문서(현재 버전) 필독입니다. - Shaka Player: DASH(·HLS 동시·빌드 선택)·
Player생성→attach→load·configure({drm·abr·streaming·text·mediaSource·cmcd… }); 오프라인shaka.offline.Storage; IMA/광고 UI; v4 이후shaka.net.NetworkingEngine·필터·Preload; CORS·CORS+Range·widevine/라이선스 CORS 실무 이슈 1순위. - ExoPlayer / Media3(Android):
MediaItem또는DashMediaSource빌더;MediaItem.DrmConfiguration(Widevine/PlayReady UUID+licenseUri);DefaultHttpDataSource·DefaultDataSource헤더;DefaultTrackSelector·Parameters언어/역할 우선;TrackSelectionView/ Exo UI 모듈;AnalyticsListener버퍼·DecoderCounters·DroppedFrames— R8/ProGuard·최소 API·Exo 2 vs Media3 API 차이 확인. - AVPlayer(iOS): HLS(EXT-X-) 가 1순위; DASH 직접·CMAF·fMP4 조합은 제한·3rd 또는 HLS 미러 운용. FairPlay는
AVContentKeySession/ 리소스 로더·SPC/CKC 흐름 — 애플 FairPlay 가이드·UHD/HDCP; 이중 매니페스트(DASH+HLS) 가 엔지니어링 현실에 잘 맞습니다.
11.1 dash.js(예시, 개념)
<script src="https://cdn.dashjs.org/latest/dash.all.min.js"></script>
<video id="v" controls></video>
<script>
const v = document.getElementById("v");
const p = dashjs.MediaPlayer().create();
p.initialize(v, "https://example.com/dash/master.mpd", true);
p.on("error", (e) => console.error("dash error", e));
// ABR/버퍼/품질: getSettings()·updateSettings(…) — dash.js **현재** 메이저 API 문서
</script>
보호콘텐츠(개념) : p.setProtectionData 또는 registerLicenseRequestFilter / getProtectionController·W3C requestMediaKeySystemAccess·MPD ContentProtection UUID·KID 정합 — CORS·POST 본문·CustomData·X- 헤더는 라이선스 서버·EME 스펙 동시 검토.
// dash.js: Widevine 예(개략) — com.widevine.alpha / 서버·헤더는 환경값
p.setProtectionData({
"com.widevine.alpha": { serverURL: "https://lic.example.com/wv", /* httpRequestHeaders, priority */ }
});
p.registerLicenseRequestFilter((req) => { /* req.uris, body 조작 */ return Promise.resolve() });
11.2 Shaka Player(예시, 개념)
<video id="v" controls></video>
<script src="https://cdnjs.cloudflare.com/ajax/libs/shaka-player/4.7.0/shaka-player.compiled.js"></script>
<script>
(async function () {
const video = document.getElementById("v");
const p = new shaka.Player();
await p.attach(video);
p.configure({
abr: { defaultBandwidthEstimate: 2e6, restrictions: { minHeight: 360 } },
streaming: { rebufferingGoal: 2, bufferBehind: 30 },
drm: { servers: { "com.widevine.alpha": "https://lic.example.com/widevine" } }
});
p.getNetworkingEngine().registerRequestFilter((type, request) => {
if (type === shaka.net.NetworkingEngine.RequestType.LICENSE) {
request.headers["X-My-Token"] = "bearer-…";
}
});
await p.load("https://example.com/dash/master.mpd");
p.selectAudioLanguage("ko", true);
p.setTextTrackVisibility(true);
})().catch(console.error);
</script>
selectTextTrack·getTextTracks·vtt·캡션 역할은 빌드·iOS·Safari·CORS·CORS+Range 검사·MSE 쿼리·EmeEncryptionSchemePolyfill(구형 브라우저)·콘솔 에러 로그를 같이 봅니다. 실제 키/라이선스 없이 재생 불가 — 스테이징 콘텐츠·퍼 clear 콘텐트·KID 모의 환경으로 개발합니다.
11.3 ExoPlayer / Media3(Kotlin, 개념)
Media3(Exo 2 → Media3 마이그레이션 권장): MediaItem+MimeTypes.APPLICATION_MPD·또는 DashMediaSource 직접 — 둘 다 가능합니다. DR·HLS 듀얼은 uri+MimeType 분기.
// Media3: MediaItem + DASH + Widevine(개략) — com.google.android.exoplayer2:exoplayer, androidx.media3
import androidx.media3.common.MediaItem
import androidx.media3.common.C
import androidx.media3.common.MimeTypes
val item = MediaItem.Builder()
.setUri("https://example.com/dash/master.mpd")
.setMimeType(MimeTypes.APPLICATION_MPD)
.setDrmConfiguration(
MediaItem.DrmConfiguration.Builder(C.WIDEVINE_UUID)
.setLicenseUri("https://lic.example.com/widevine")
.setLicenseRequestHeaders(mapOf("X-Token" to "…"))
.setMultiSession(true)
.build()
)
.build()
player.setMediaItem(item)
// TrackSelector: ParametersBuilder().setPreferredAudioLanguages("ko") …
DefaultRenderersFactory·LoadErrorHandlingPolicy·BandwidthMeter·AnalyticsListener·DecoderReuseEvaluation·HEVC/AV1·톤 맵·HDR surface — 기기·SoC·OEM 제한 주의합니다.
11.4 AVPlayer / FairPlay(개략, Swift)
// DASH: AVPlayer URL 직접(지원/코덱/포맷 제한) vs HLS 권장
let url = URL(string: "https://example.com/hls/master.m3u8")! // iOS: HLS 1차
let player = AVPlayer(url: url)
// FairPlay: AVContentKeyRequest / AVContentKeySession + SPC(서버) → CKC(응답) — Apple 샘플·문서
// AVAssetResourceLoaderDelegate: m3u8/세그/키·인증서·사용자 인증(선택) 오버라이드
AVURLAsset·http-header-fields·resourceLoader·Sideloaded·HLS fMP4·CMAF·EXT-X-SESSION-KEY — DASH·HLS 기기·iOS·3rd 플레이어·CocoaPods SDK·HLS+FairPlay 이중 출력 파이프라인 병행 검토 권장; iPad·M1 Mac·visionOS 등 OS별 가이드·백그라운드·AirPlay 2·PiP 제약 확인합니다.
크로스플랫폼 제품은 CMAF + DASH(Android/웹) + HLS(iOS/tvOS) 듀얼 매니페스트 전략이 흔합니다.
12. 정리
ISO/IEC 23009-1 MPD는 Period–AdaptationSet–Representation·SegmentTemplate/List/Base·시간 timescale/SegmentTimeline 으로 HTTP 적응형 재생을 기술하고, CENC+DASH-IF·UHD·라이브·광고는 패키징·DRM·SSAI 전부의 맞춤이 필수입니다. FFmpeg·Bento4·Shaka로 재현 가능한 파이프라인을 구축한 뒤, dash.js/Shaka/ExoPlayer/AVPlayer 각각의 ABR·DRM·트랙 API로 끝단을 완성하십시오. MPD/세그 변경 시에는 DASH-IF 검증·실기기 회귀를 습관으로 두는 것이 안전합니다.
본 가이드는 교육·기술 참조용이며, DRM·키·라이선스 운용은 보안·계약·지역 규정을 따릅니다.