본문으로 건너뛰기
Previous
Next
[2026] MPEG-DASH 완전 참조 — MPD(ISO 23009-1) · 세그멘트 · CENC/DRM · 플레이어

[2026] MPEG-DASH 완전 참조 — MPD(ISO 23009-1) · 세그멘트 · CENC/DRM · 플레이어

[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 요소가 전체 프로파일·이동(라이브 여부)·시간 힌트를 담고, 이하 PeriodAdaptationSetRepresentation세그멘트 정보(SegmentBase / SegmentList / SegmentTemplate)의 계층이 이어집니다.

MPD@typestatic이면 일반적으로 VoD(온디맨드)(미리 생성된 MPD)에 가깝고, dynamic이면 라이브/타임이동 가능한 MPD이며(업데이트 주기·버퍼 깊이 등), 플레이어는 MPD 재획득(폴링)라이브 엣지에 맞춰 세그멘트를 요청합니다. availabilityStartTime·timeShiftBufferDepth·suggestedPresentationDelay 등의 의미는 23009-1 절(동적 MPD)을 따르며, 구현·플레이어는 이를 ABR·시크·라이브 딜레이에 반영합니다.

핵심 루트 속성(개념 정리):

속성(예)용도
typestatic / dynamic — VoD·라이브·타임쉬프트 모드 구분(개념적)
profiles인터롭(예: DASH-IF) 프로파일 URN, 도구/플레이어 호환 힌트
minBufferTime최소 버퍼(미디어 타임) — 플레이어 훈·언더런과 연관(휴리스틱)
mediaPresentationDuration전체 프레젠테이션 길이(필요 시)
availabilityStartTime / timeShiftBufferDepth / minimumUpdatePeriod동적 MPD·캐치업·MPD 갱신 주기

ProgramInformation, BaseURL(serviceLocation, priority, weight), Location전역 메타/리다이렉트/다중 BaseURLCDN·페일오버·지역 전략에 쓰입니다. 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 또는 indexRangesidx(인덱스)·세그멘트 경계단일 mp4 + sidx, 또는 작은 수의 조각
SegmentList명시 URL 목록(SegmentURL 등) + duration/timescale, 필요 시 initialization 소스URL이 비규칙·소수일 때, 도구·CMS가 리스트를 생성할 때
SegmentTemplate$Number$ / $Time$ / $RepresentationID$ 템플릿으로 세그멘트 이름 규칙 기술대용량 VoD/라이브, fMP4 효율·CDN 캐싱에 유리

SegmentTemplateduration(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 / EssentialPropertyUHD HDR, DVB, CENC 키 식별자(URN) 메타

Representation: id, bandwidth, width, height, frameRate, codecs — ABR/디스플레이/디코딩; SubRepresentation, Subsegment, BaseURL — 세부 조각(드물게)

세그멘트 체인
SegmentBaseIndexRange·initialisation(영국식 철자) / Initialization / RepresentationIndex; SegmentListSegmentTimeline·SegmentURL; SegmentTemplatemedia, initialization, duration 또는 SegmentTimeline, @timescale
S 요소(타임라인 SegmentTimeline 내) — t, d 반복 — 가변 세그 길이, 이름 없는(묵시) 세그먼트 연속

AdaptationSetContentComponent — 컴포넌트 식별; AssetIdentifier·ContentProtectionCENC/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·지역·페일오버
LocationMPD URL — 이동/리다이렉트
UTCTiming + @valueNTP/HTTP 타임 — 동적/라이브 시계
ServiceDescription확장/프로필(예: LL-DASH 관련) 서비스 메타

표 2. Period

요소/속성설명(요지)
id / start / duration슬롯 식별·시작(미디어 프레젠테이션 타임라인)
BaseURL해당 Period만 다른 오리진
EventStream / EventMPD 이벤트 — 광고·캡션·동기
InbandEventStreamfMP4 인밴드 이벤트 (프로필)
SCTE-35 캐리지방송/광고 시그널 (확장·DASH-IF/방송)

표 3. AdaptationSet

요소/속성설명(요지)
contentTypevideo / audio / text / application 초기 라우팅
segmentAlignment / subsegmentAlignmentABR·스위칭 정렬 요구 (값 true 등)
bitstreamSwitching코덱 전환(제한) — H.264 SPS 공유패턴
mimeType / codecsRFC 6381 코덱 문자열 — avc1, hvc1, mp4a.40.2
lang / label / Role / AccessibilityUI·접근성·역할(main, subtitle, alternate 등)
ContentComponent / id다중 컴포넌트(예: 5.1+보조) 구분
FramePacking / AudioChannelConfiguration3D·채널 맵(URN·값) — UHD/Immersive
EssentialProperty / SupplementalProperty필수/부가 URN(예: HDR 메타, CENC KID)
ContentProtection + @schemeIdUri + cenc:default_KID + pssh (Base64)DRM/라이선스 연결
InbandEventStream(세트 수준) 이벤트 트랙 신호

표 4. Representation

요소/속성설명(요지)
id, bandwidthABR 선택·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@indexRangesidx·인덱스 바이트 구간
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), FailsafeURL 변형, 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에 정리돼 있으며, 프로파일 URNMPD@profiles명시되는 경우가 많습니다.

6. 실전: FFmpeg, MP4Box, Shaka Packager(개요)

이하 명령은 환경·빌드에 따라 옵션이 다릅니다. --help·공식 문서·출력 MPD 검증을 반드시 하십시오.

6.1 FFmpeg로 DASH(fMP4) 생성(예시)

ffmpegDASH 뮤덱서·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 dashMPD+세그멘트를 씁니다. adaptation_sets비디오/오디오분리AdaptationSet에 매핑합니다. init_seg_name·media_seg_nameMP4Box의 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(예시)

packagerCENC, 다중 기간(제한), 자막프로덕션에서 널리 쓰입니다:

# 예: 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로 전환(구현체마다 트랙 모델이 다름).
  • 자막: mimeType text/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·profiles URN·최소 요구(코덱, 세그, 자막, 콘솔) — 접수·인증필독입니다.
  • UHD/4K: HEVC/AV1 codecs·10bit·HDR(SupplementalProperty PQ/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×fps timescale 권장 패턴만 참고.
  • 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/PlayReady protectionData·서버 URL; TextTrack·자막; 로깅 Debug / 이벤트 on(dashjs.MediaPlayer.events.*); 퍼포먼스 setFastSwitchEnabled·buffer·abr limitBitrateByPortal·useDeadTimeLatency·initialBitrate·autoSwitchBitrate API메이저 변하므로 공식 문서(현재 버전) 필독입니다.
  • Shaka Player: DASH(·HLS 동시·빌드 선택Player 생성attachload·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·DroppedFramesR8/ProGuard·최소 API·Exo 2 vs Media3 API 차이 확인.
  • AVPlayer(iOS): HLS(EXT-X-)1순위; DASH 직접·CMAF·fMP4 조합제한·3rd 또는 HLS 미러 운용. FairPlayAVContentKeySession / 리소스 로더·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-KEYDASH·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·키·라이선스 운용은 보안·계약·지역 규정을 따릅니다.