DASH를 통한 라이브 YouTube 콘텐츠 제공

이 문서에서는 HTTP 동적 적응형 스트리밍 (DASH) 전송 형식을 사용하여 인코더에서 YouTube로 실시간 데이터를 스트리밍하는 방법을 안내합니다. 인코더 공급업체가 제품에 DASH 전송 지원을 추가할 수 있도록 지원하기 위한 것입니다.

DASH 이해하기

아래 목록에는 몇 가지 주요 DASH 기능과 속성이 나와 있습니다.

  • 개방형 표준을 기반으로 합니다.
  • HTTP 기반 따라서 DASH는 인터넷 인프라 친화적이며 방화벽을 통과할 수 있습니다.
  • 높은 전송 비트 전송률을 지원합니다. DASH는 여러 동시 HTTP 세션과 비순차적 세그먼트 전송을 지원하므로 단일 TCP 연결에 의존하는 프로토콜보다 복원력이 뛰어납니다.
  • HTTPS를 통한 보안 전송
  • HTTP 및 HTTPS를 통한 무손실 전송
  • 코덱에 구애받지 않습니다.
  • H264 및 AAC가 포함된 MP4와 VP8/VP9 및 Vorbis/Opus가 포함된 WebM을 지원합니다.

사양

요구사항

다음 하위 섹션에서는 DASH를 사용하여 YouTube에 라이브 스트림을 전송하기 위한 요구사항을 설명합니다.

시간

YouTube DASH 엔드포인트는 인코더에서 전송된 PUT 메서드 호출을 기록하는 수동 HTTP 서버로 작동합니다.

  • DASH 엔드포인트는 동시 TCP 연결을 지원합니다. HTTP/1.1에 따라 연결을 재사용할 수 있습니다.
  • MPD와 초기화 세그먼트는 첫 번째 미디어 세그먼트로부터 3초 이내에 PUT되어야 합니다. (MPD에 초기화 세그먼트를 포함하는 것이 좋습니다.)
  • 각 세그먼트 또는 MPD는 별도의 PUT 요청을 사용해야 합니다. 여러 세그먼트의 멀티파트 업로드는 지원되지 않습니다.
  • 미디어 세그먼트의 PUT 작업은 업로드 대역폭을 개선하기 위해 시간상으로 중복될 수 있습니다.
  • 세그먼트는 약 3초의 시간 범위 내에서 순서가 지정되지 않은 상태로 제공될 수 있습니다.
  • MPD와 초기화 세그먼트는 업데이트된 availabilityStartTimestartNumber로 최소 60초마다 업데이트해야 합니다. (위에서 설명한 것처럼 초기화 세그먼트는 MPD에 포함될 수 있습니다. 이 경우 하나의 PUT 요청으로 두 세그먼트를 모두 업데이트할 수 있습니다.)

URL 구조

인코더는 YouTube 엔드포인트 기본 URL에 문자열을 추가하여 PUT URL을 형성해야 합니다. YouTube Live Streaming API를 사용하여 DASH 수집 엔드포인트를 만들어야 합니다.

그런 다음 인코더는 YouTube Live Streaming API를 통해 엔드포인트의 기본 URL을 프로그래매틱 방식으로 가져올 수 있습니다. 인코더에 URL을 수동으로 제공하려는 경우 YouTube 라이브 이벤트 UI에서도 기본 URL을 확인할 수 있습니다.

기본 URL에 추가되는 문자열에는 다음 ASCII 문자 집합이 포함될 수 있습니다.

  • 소문자: a~z
  • 대문자: A~Z
  • 숫자: 0~9
  • 특수 문자: _ (밑줄), - (하이픈), . (마침표)

MPD URL

위 요구사항 외에도 MPD URL은 .mpd로 끝나야 YouTube 서버가 MPD를 쉽게 식별할 수 있습니다. 기타 세그먼트 URL은 .mpd로 끝나면 안 됩니다.

초기화 및 미디어 세그먼트 URL

데이터가 ISO BMFF 컨테이너에 있는 경우 초기화 세그먼트 URL과 모든 미디어 세그먼트 URL은 .mp4로 끝나야 하고, 데이터가 WebM 컨테이너에 있는 경우 .webm로 끝나야 합니다.

MPD 콘텐츠

MPD는 완전해야 하며 DASH 표준을 준수해야 합니다. 다음 요소를 각각 하나씩 포함해야 합니다. 이 목록은 YouTube에서 특별히 요구하는 요소를 식별하며 DASH 표준은 추가 필수 요소를 식별할 수 있습니다. 요소는 XPath 구문을 사용하여 표현되며 DASH 표준과 일치합니다.

  • /mpd:MPD/attribute::type
  • /mpd:MPD/mpd:Period
  • /mpd:MPD/mpd:Period/mpd:AdaptationSet
  • /mpd:MPD/mpd:Period/mpd:AdaptationSet/attribute::mimeType (video/mp4 or video/webm)
  • /mpd:MPD/mpd:Period/mpd:AdaptationSet/mpd:SegmentTemplate
  • /mpd:MPD/mpd:Period/mpd:AdaptationSet/mpd:SegmentTemplate/attribute::media
  • /mpd:MPD/mpd:Period/mpd:AdaptationSet/mpd:SegmentTemplate/attribute::initialization
  • /mpd:MPD/mpd:Period/mpd:AdaptationSet/mpd:SegmentTemplate/attribute::startNumber

요소 값에 대한 다음 요구사항을 참고하세요.

  • <MPD> 요소의 minimumUpdatePeriod 속성은 60초 (PT60S) 이하의 값으로 설정해야 합니다.
  • <SegmentTemplate> 요소의 media 속성은 미디어 세그먼트 URL이 $Number$를 사용하여 생성된다고 지정해야 합니다. (startNumber 속성은 첫 번째 미디어 세그먼트에 할당될 번호를 식별합니다.)

초기화 세그먼트 길이

초기화 세그먼트는 100kb를 초과해서는 안 됩니다. (일반적으로 초기화 세그먼트는 이보다 훨씬 작습니다.) 초기화 세그먼트가 MPD에 포함된 경우 세그먼트가 포함된 data: URL은 100kb를 초과해서는 안 됩니다.

인코더 출력

초기화 세그먼트와 미디어 세그먼트는 닫힌 GOP (사진 그룹)가 있는 다중화된 ISO BMFF 또는 WebM 파일 스트림을 구성해야 합니다.

  • GOP 크기는 약 2초여야 하며 8초 미만이어야 합니다.
  • 멀티플렉싱된 스트림에는 오디오 트랙과 동영상 트랙이 모두 포함되어야 합니다.

추가 권장사항

암호화

YouTube는 HTTPS를 통한 스트림 암호화를 지원합니다. 이 기능을 사용하는 것이 좋습니다.

MPD의 초기화 세그먼트

RFC 2397에 따라 data: URL을 사용하여 MPD에서 초기화 세그먼트를 직접 나타낼 수 있습니다. 이렇게 하면 스트림 설정이 간소화되고 초기화 세그먼트가 스트림의 나머지 부분과 일치하지 않을 가능성이 줄어듭니다.

이 요소의 XPath는 다음과 같습니다.

/mpd:MPD/mpd:Period/mpd:AdaptationSet/mpd:SegmentTemplate/attribute:data

타겟 세그먼트 길이

처리량과 지연 시간 간의 균형을 유지하면서 원활한 처리 성능을 구현하려면 미디어 세그먼트의 길이가 1~5초여야 합니다. 다음 두 요소를 사용하여 MPD에서 이러한 세그먼트의 타겟 기간을 전달하는 것이 좋습니다.

  • /mpd:MPD/mpd:Period/mpd:AdaptationSet/mpd:SegmentTemplate/attribute::duration
  • /mpd:MPD/mpd:Period/mpd:AdaptationSet/mpd:SegmentTemplate/attribute::timescale

이러한 속성에서 계산된 기간은 모든 실제 세그먼트 기간의 2배 이내여야 합니다. 그렇지 않으면 스트리밍 성능이 저하될 수 있습니다.

인제스트의 타겟 지속 시간은 YouTube에서 생성하는 라이브 스트림의 청크 지속 시간과 같지 않습니다. YouTube는 입력을 트랜스코딩하고 다시 청크합니다. 출력 타겟 기간은 스트림이 스트리밍 품질에 최적화되어 있는지 아니면 지연 시간에 최적화되어 있는지에 따라 달라집니다.

재시도 및 지수 백오프

모든 HTTP PUT 요청은 시간 제한 내에 수행해야 하며, 시간 제한은 세그먼트 지속 시간보다 500밀리초 큰 값으로 설정하는 것이 좋습니다.

시간 초과 또는 기타 오류로 인해 실패한 미디어 세그먼트 PUT 요청은 동영상 스트림의 간격에 해당합니다. 따라서 무작위로 지정된 바이너리 지수 백오프를 사용하여 이러한 요청을 재시도해야 합니다.

  1. 실패 후 [0 ... 100]밀리초 사이의 임의의 기간을 기다린 후 요청을 다시 시도합니다.
  2. 요청이 다시 실패하면 [0 ... 200]밀리초 사이의 무작위 기간을 기다린 후 요청을 다시 시도합니다.
  3. 요청이 다시 실패하면 [0 ... 400]밀리초 사이의 무작위 기간을 기다린 후 요청을 다시 시도합니다.

반복되는 실패는 브로드캐스트 실패에 해당하므로 인코더 운영자에게 알려야 합니다.

HTTP 응답 코드

다음 섹션에서는 DASH를 통해 전송된 세그먼트에 대한 응답으로 YouTube에서 반환하는 응답 코드를 설명합니다.

200 (OK)

HTTP 200 (OK) 응답은 YouTube 서버가 예상된 작업을 수신하여 성공적으로 처리했음을 나타냅니다.

202(허용됨)

PUT 또는 POST 작업에 대한 HTTP 202 (수락됨) 응답은 작업이 예상치 못했지만 지연된 처리를 위해 수락되었음을 나타냅니다. 하지만 지연된 작업이 성공할 수도 있고 실패할 수도 있으므로 응답이 YouTube에서 실제로 작업을 성공적으로 처리할 수 있음을 보장하지는 않습니다.

이 응답은 세그먼트가 순차적으로 전송되지 않을 때 가장 자주 발생합니다. 일반적으로 YouTube는 앞의 세그먼트를 수신한 후 수락된 세그먼트를 올바르게 처리할 수 있으므로 세그먼트를 다시 보낼 필요가 없습니다.

예를 들어 YouTube는 다음 경우에 202 응답을 반환할 수 있습니다.

  • 초기화 세그먼트가 MPD보다 먼저 수신됩니다.
  • 미디어 세그먼트는 MPD 및 초기화 세그먼트보다 먼저 수신됩니다.
  • 이전 세그먼트보다 먼저 미디어 세그먼트가 수신됩니다(예: 세그먼트 2보다 먼저 세그먼트 3이 수신됨).

하지만 YouTube에서 POST 또는 PUT 요청을 수신한 후 식별자를 완전히 검증할 수 없는 경우 202 응답은 항목 식별자가 잘못되었음을 나타낼 수도 있습니다. 예를 들어 YouTube가 MPD를 수신하기 전에 초기화 세그먼트를 수신하여 수락했지만 초기화 세그먼트가 잘못된 것으로 판명된 경우에 이러한 상황이 발생합니다. 이 경우 YouTube는 초기화 세그먼트를 수락하고 202를 반환한 다음 MPD를 수신하면 세그먼트가 유효한지 확인합니다. MPD에 초기화 세그먼트를 포함하면 이 시나리오를 방지할 수 있습니다.

400 (Bad Request)

HTTP 400 (잘못된 요청) 응답은 다음 문제 중 하나가 발생했음을 나타냅니다.

  • URL 형식이 잘못되었습니다.
  • 게시물이 너무 큽니다 (> 10MB).
  • MPD를 파싱할 수 없습니다.
  • MPD의 초기화 세그먼트가 손상되었습니다.

401 (Unauthorized)

HTTP 401 (인증되지 않음) 응답은 YouTube DASH 엔드포인트의 기본 URL이 손상되었거나 만료되었음을 나타냅니다.

405 (허용되지 않는 메서드)

HTTP 405 (허용되지 않는 방식) 응답은 POST 또는 PUT 이외의 요청이 전송되었음을 나타냅니다.

409(충돌)

PUT 또는 POST 작업에 대한 HTTP 409 (충돌) 응답은 YouTube에서 요청을 처리할 수 없음을 나타냅니다. 예를 들어 요청자가 미디어 세그먼트를 많이 보냈지만 YouTube에 아직 MPD 또는 초기화 세그먼트가 없거나 둘 다 없는 경우 이 응답이 발생할 수 있습니다. 이 예에서 인코더는 실패한 요청을 다시 시도하기 전에 MPD 및 초기화 세그먼트를 다시 전송해야 합니다.

500 (내부 서버 오류)

HTTP 500 (내부 서버 오류) 응답은 서버가 요청을 처리할 수 없음을 나타냅니다. 이 오류의 경우 지수 백오프로 요청을 다시 시도하는 것이 좋습니다.

URL 시퀀스

아래 URL 시퀀스는 DASH를 통해 콘텐츠를 전송하기 위해 이루어지는 일련의 PUT 요청을 보여줍니다. 이 시퀀스는 YouTube DASH 엔드포인트의 기본 URL이 다음과 같다고 가정합니다.

http://upload.youtube.com/dash_upload?cid=xxxx-xxxx-xxxx-xxxx&copy=0&file=

이 시퀀스에서는 MPD와 초기화 세그먼트가 별도로 전송됩니다. 하지만 초기화 세그먼트는 MPD에 직접 표시할 수 있으며 이 방법을 사용하는 것이 좋습니다. 또한 MPD 및 초기화 세그먼트는 최소 60초마다 업데이트해야 합니다. 따라서 결국 이러한 세그먼트의 URL이 이 시퀀스에 다시 표시되고 더 많은 미디어 세그먼트의 URL이 뒤따릅니다.

PUT upload.youtube.com/dash_upload?cid=xxxx-xxxx-xxxx-xxxx&copy=0&file=dash.mpd
PUT upload.youtube.com/dash_upload?cid=xxxx-xxxx-xxxx-xxxx&copy=0&file=init.mp4
PUT upload.youtube.com/dash_upload?cid=xxxx-xxxx-xxxx-xxxx&copy=0&file=media001.mp4
PUT upload.youtube.com/dash_upload?cid=xxxx-xxxx-xxxx-xxxx&copy=0&file=media002.mp4
PUT upload.youtube.com/dash_upload?cid=xxxx-xxxx-xxxx-xxxx&copy=0&file=media003.mp4
...

WebM 세그먼트

초기화 세그먼트가 삽입된 MPD

다음 샘플 MPD에는 RFC 2397 데이터 URL에 삽입된 초기화 세그먼트가 있습니다. 별도로 전송하는 대신 이러한 방식으로 초기화 세그먼트를 삽입하는 것이 좋습니다.

이 예는 YouTube에 WebM (VP8 또는 VP9, Opus)을 인제스트하는 데 적합합니다. 가독성을 위해 데이터 URL의 대부분이 생략되었습니다.

<?xml version="1.0" encoding="UTF-8"?>
<MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns="urn:mpeg:dash:schema:mpd:2011"
     xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd"
     type="dynamic" 
     profiles="urn:mpeg:dash:profile:isoff-live:2011" 
     minimumUpdatePeriod="PT60S"
     minBufferTime="PT12S"
     availabilityStartTime="2016-04-13T20:52:58" >
  <Period start="PT0S" id="1">
    <AdaptationSet mimeType="video/webm">
      <ContentComponent contentType="video" id="1"/>
      <SegmentTemplate timescale="1000"
           duration="2000"
           startNumber="1"
           initialization="data:video/mp4;base64,AAAAGGZ0eXBpc...AAA"
           media="/dash_upload?cid=xxxx-xxxx-xxxx-xxxx&copy=0&file=media-$Number%09d$.webm"/>
      <Representation id="1" width="1920" height="1080">
        <SubRepresentation contentComponent="1"/>
      </Representation>
    </AdaptationSet>
  </Period>
</MPD>

MPD

다음 샘플 MPD는 삽입된 초기화 세그먼트가 없으며 YouTube에 WebM (VP8 또는 VP9, Opus)을 인제스트하는 데도 적합합니다.

<?xml version="1.0" encoding="UTF-8"?>
<MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns="urn:mpeg:dash:schema:mpd:2011"
     xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd"
     type="dynamic" 
     profiles="urn:mpeg:dash:profile:isoff-live:2011" 
     minimumUpdatePeriod="PT60S"
     minBufferTime="PT12S"
     availabilityStartTime="2016-04-13T20:52:58" >
  <Period start="PT0S" id="1">
    <AdaptationSet mimeType="video/webm">
      <ContentComponent contentType="video" id="1"/>
      <SegmentTemplate timescale="1000"
           duration="2000"
           startNumber="1"
           initialization="/dash_upload?cid=xxxx-xxxx-xxxx-xxxx&copy=0&file=init.webm"
           media="/dash_upload?cid=xxxx-xxxx-xxxx-xxxx&copy=0&file=media-$Number%09d$.webm"/>
      <Representation id="1" width="1920" height="1080">
        <SubRepresentation contentComponent="1"/>
      </Representation>
    </AdaptationSet>
  </Period>
</MPD>

초기화

다음은 샘플 WebM 초기화 세그먼트의 레이아웃을 보여줍니다. 첫 번째 클러스터를 포함하지 않는 WebM 스트림 부분으로 구성됩니다.

미디어

다음은 샘플 WebM 미디어 세그먼트의 레이아웃을 보여줍니다. 단일 WebM 클러스터로 구성됩니다. ISO BMFF 스트림과 마찬가지로 일련의 클러스터에 추가된 초기화 세그먼트는 유효한 WebM 스트림을 생성해야 합니다.

ISO BMFF 세그먼트

초기화 세그먼트가 삽입된 MPD

다음 샘플 MPD에는 RFC 2397 데이터 URL에 삽입된 초기화 세그먼트가 있습니다. 별도로 전송하는 대신 이러한 방식으로 초기화 세그먼트를 삽입하는 것이 좋습니다.

이 예는 YouTube에 ISO BMFF (H.264, AAC)를 인제스트하는 데 적합합니다. 가독성을 위해 데이터 URL의 대부분이 생략되었습니다.

<?xml version="1.0" encoding="UTF-8"?>
<MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="urn:mpeg:dash:schema:mpd:2011"   
    xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd" 
    type="dynamic"
    minimumUpdatePeriod="PT30S" 
    availabilityStartTime="2016-05-04T20:47:25" 
    minBufferTime="PT12S" 
    profiles="urn:mpeg:dash:profile:isoff-live:2011">
  <Period start="PT0S" id="1">
    <AdaptationSet mimeType="video/mp4" codecs="avc1.4d401e,mp4a.40.2">
      <ContentComponent contentType="video" id="1"/>
      <ContentComponent contentType="audio" id="2"/>
      <SegmentTemplate timescale="600"
             media="/dash_upload?cid=ug50-xg26-cbc1-2p0h&staging=1&copy=0&file=media$Number%09d$.mp4"
             initialization="data:video/mp4;base64,AAAAGGZ0eXBpc281AA...AA"
             duration="306"
             startNumber="1"/>
      <Representation id="1" width="640" height="360" bandwidth="526952">
        <SubRepresentation contentComponent="1" bandwidth="526952" 
codecs="avc1.4d401e"/>
        <SubRepresentation contentComponent="2" bandwidth="125584" codecs="mp4a.40.2"/>
      </Representation>
    </AdaptationSet>
  </Period>
</MPD>

MPD

다음 샘플 MPD는 삽입된 초기화 세그먼트가 없으며 YouTube에 ISO BMFF (H.264, AAC)를 인제스트하는 데도 적합합니다.

<?xml version="1.0" encoding="UTF-8"?>
<MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns="urn:mpeg:dash:schema:mpd:2011"
     xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd"
     type="dynamic"
     profiles="urn:mpeg:dash:profile:isoff-live:2011"
     minimumUpdatePeriod="PT60S" 
     minBufferTime="PT12S"
     availabilityStartTime="2016-04-13T20:51:31" >
  <Period start="PT0S" id="1">
    <AdaptationSet mimeType="video/mp4" codecs="avc1.4d401e,mp4a.40.2">
      <ContentComponent contentType="video" id="1"/>
      <ContentComponent contentType="audio" id="2"/>
      <SegmentTemplate timescale="600"
           duration="1200"
           startNumber="1"
           initialization="/dash_upload?cid=xxxx-xxxx-xxxx-xxxx&copy=0&file=init.mp4"
           media="/dash_upload?cid=xxxx-xxxx-xxxx-xxxx&copy=0&file=media$Number%09d$.mp4"/>
      <Representation id="1" width="640" height="360" bandwidth="526952">
        <SubRepresentation contentComponent="1" bandwidth="526952" codecs="avc1.4d401e"/>
        <SubRepresentation contentComponent="2" bandwidth="125584" codecs="mp4a.40.2"/>
      </Representation>
    </AdaptationSet>
  </Period>
</MPD>

초기화

다음 다이어그램은 샘플 멀티플렉스 ISO BMFF 초기화 세그먼트의 레이아웃을 보여줍니다. YouTube는 원자를 반드시 사용하지는 않지만, 이는 적합한 예입니다. 특히 오디오 트랙과 동영상 트랙이 모두 표시됩니다.

미디어

다음 다이어그램은 샘플 멀티플렉싱된 ISO BMFF 미디어 세그먼트의 레이아웃을 보여줍니다. YouTube에서 모든 원자를 사용하는 것은 아니지만 이는 규정을 준수하는 예입니다. 특히 오디오 트랙과 동영상 트랙이 모두 표시됩니다. 이러한 세그먼트 시리즈를 초기화 세그먼트에 추가하여 유효하고 완전한 멀티플렉스 ISO BMFF 스트림을 생성할 수 있습니다.

알려진 제한사항

RTMP 및 DASH 인제션

YouTube에 RTMP와 DASH 인제션을 혼합할 수는 없습니다. 이는 방송 중에 두 가지를 전환하는 경우뿐만 아니라 하나를 기본 수집 방법으로 사용하고 다른 하나를 백업 수집 방법으로 사용하는 경우에도 적용됩니다.