โปรโตคอลสตรีมมิงของตัวรับสัญญาณเว็บ

ปัจจุบัน Web Receiver SDK รองรับโปรโตคอลสตรีมมิง 3 ประเภทดังนี้

DASH, HTTP Live Streaming และ Smooth Streaming

ในเอกสารนี้เราแสดงการสนับสนุนสําหรับโปรโตคอลสตรีมมิงแต่ละโปรโตคอล โปรดทราบว่าคําอธิบายแท็กที่รองรับสําหรับแต่ละโปรโตคอลนั้นค่อนข้างย่อเมื่อเทียบกับข้อกําหนดโปรโตคอลโดยละเอียด โดยมีเป้าหมายเพื่อให้เห็นภาพคร่าวๆ และเข้าใจวิธีใช้โปรโตคอลต่างๆ และฟีเจอร์ใดของอุปกรณ์ที่รองรับในอุปกรณ์ที่พร้อมใช้งาน Cast เพื่อมอบประสบการณ์การสตรีม

การสตรีมที่ปรับเปลี่ยนได้แบบไดนามิกผ่าน HTTP (DASH)

ข้อกําหนดโดยละเอียดของ DASH ของ ISO

DASH เป็นโปรโตคอลสตรีมมิงอัตราบิตที่ปรับเปลี่ยนได้ ซึ่งทําให้สตรีมวิดีโอคุณภาพสูงผ่านเซิร์ฟเวอร์ HTTP(S) ได้ ไฟล์ Manifest ที่อยู่ในรูปแบบ XML ประกอบด้วยข้อมูลเมตาส่วนใหญ่เกี่ยวกับวิธีเริ่มต้นและดาวน์โหลดเนื้อหาวิดีโอ แนวคิดสําคัญที่ Web Receiver Player รองรับ ได้แก่ <Period>, <AdaptationSet>, <Representation>, <SegmentTemplate>, <SegmentList>, <BaseUrl> และ <ContentProtection>

ไฟล์ Manifest ของ DASH เริ่มต้นด้วยแท็กรูท <MPD> และภายในมีแท็ก <Period> อย่างน้อย 1 รายการที่แสดงถึงเนื้อหาสตรีมมิง 1 รายการ แท็ก <Period> ช่วยให้คุณจัดลําดับเนื้อหาสตรีมมิงต่างๆ ได้ และมักจะใช้เพื่อแยกเนื้อหาหลักและโฆษณา หรือเนื้อหาวิดีโอต่อเนื่องหลายรายการ

<AdaptationSet> ภายใต้ <MPD> คือชุดการนําเสนอสําหรับสตรีมสื่อประเภทหนึ่ง ในกรณีส่วนใหญ่คือวิดีโอ เสียง หรือคําบรรยายวิดีโอ Mimetype ที่ใช้กันโดยทั่วไปคือ "video/mp4", "audio/mp4" และ "text/vtt" คุณใส่ <ContentComponent contentType="$TYPE$"> หรือไม่ก็ได้ใน <AdaptationSet>

ภายใน <AdaptationSet> แต่ละรายการจะมีรายการแท็ก <Representation> ปรากฏขึ้น และโปรแกรมเล่นผู้รับเว็บจะใช้ข้อมูล codecs ในการเริ่มบัฟเฟอร์แหล่งที่มาของ MSE และข้อมูลของ bandwidth เพื่อเลือกตัวแทน/อัตราบิตที่ถูกต้องให้เล่นโดยอัตโนมัติ

สําหรับ <Representation> แต่ละรายการ ระบบจะอธิบายกลุ่มสื่อโดยใช้ <BaseURL> สําหรับการแสดงกลุ่มเดียว <SegmentList> สําหรับรายการกลุ่ม (คล้ายกับ HLS) หรือ <SegmentTemplate>

สําหรับ <SegmentTemplate> คอลัมน์นี้จะแสดงวิธีที่กลุ่มการเริ่มต้นและ กลุ่มสื่อเป็นตัวแทนผ่านเทมเพลต ในตัวอย่างด้านล่าง $Number$ ระบุหมายเลขกลุ่มที่พร้อมใช้งานจาก CDN โดยระบบจะแปลเป็น seg1.m4s, seg2.m4s ฯลฯ เมื่อการเล่นดําเนินต่อไป

<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" xmlns:ns2="http://www.w3.org/1999/xlink"
  profiles="urn:mpeg:dash:profile:isoff-live:2011,http://dashif.org/guidelines/dash264" type="static"
  publishTime="2016-10-05T22:07:14.859Z" mediaPresentationDuration="P1DT0H0M0.000S" minBufferTime="P0DT0H0M7.500S">
  <Period id="P0">
    <AdaptationSet lang="en" segmentAlignment="true">
      <ContentComponent id="1" contentType="audio"/>
      <SegmentTemplate media="seg$Number$.m4s" initialization="seginit.mp4"
        duration="10000" startNumber="1" timescale="1000" presentationTimeOffset="0"/>
      <Representation id="1" bandwidth="150123" audioSamplingRate="44100"
        mimeType="audio/mp4" codecs="mp4a.40.2" startWithSAP="1">
        <AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
        <BaseURL>http://www.google.com/testVideo</BaseURL>
      </Representation>
    </AdaptationSet>
    <AdaptationSet segmentAlignment="true">
      <ContentComponent id="1" contentType="video"/>
      <SegmentTemplate media="seg$Number$.m4s" initialization="seginit.mp4"
        duration="10000" startNumber="1" timescale="1000" presentationTimeOffset="0"/>
      <Representation id="1" bandwidth="212191" width="384" height="208" sar="26:27"
        frameRate="25" mimeType="video/mp4" codecs="avc1.42c01f" startWithSAP="1">
        <BaseURL>http://www.google.com/testVideo/bitrate1/</BaseURL>
      </Representation>
      <Representation id="1" bandwidth="366954" width="512" height="288" sar="1:1"
        frameRate="25" mimeType="video/mp4" codecs="avc1.42c01f" startWithSAP="1">
        <BaseURL>http://www.google.com/testVideo/bitrate2/</BaseURL>
      </Representation>
      <Representation id="1" bandwidth="673914" width="640" height="352" sar="44:45"
        frameRate="25" mimeType="video/mp4" codecs="avc1.42c01f" startWithSAP="1">
        <BaseURL>http://www.google.com/testVideo/bitrate3/</BaseURL>
      </Representation>
    </AdaptationSet>
  </Period>
</MPD>

สําหรับ <SegmentTemplate> มักจะใช้แท็ก <SegmentTimeline> เพื่อระบุระยะเวลาที่กลุ่มเป้าหมายแต่ละกลุ่มและกลุ่มที่เกิดซ้ํา timescale (หน่วยที่แสดงถึง 1 วินาที) มักรวมอยู่ในแอตทริบิวต์ของ <SegmentTemplate> เพื่อให้เราสามารถคํานวณเวลาของกลุ่มตามหน่วยนี้ได้ ในตัวอย่างด้านล่าง แท็ก <S> แสดงถึงแท็กกลุ่ม แอตทริบิวต์ d จะระบุระยะเวลาของกลุ่มและแอตทริบิวต์ r จะระบุจํานวนกลุ่มที่มีระยะเวลาเดียวกันซ้ําเพื่อให้คํานวณ $Time$ ได้อย่างถูกต้องสําหรับการดาวน์โหลดกลุ่มสื่อตามที่ระบุไว้ในแอตทริบิวต์ media

<SegmentTemplate>
  timescale="48000"
  initialization="$RepresentationID$-init.dash"
  media="$RepresentationID$-$Time$.dash"
    startNumber="1">
    <SegmentTimeline>
      <S t="0" d="96256" r="2" />
      <S d="95232" />
      <S d="96256" r="2" />
      <S d="95232" />
      <S d="96256" r="2" />
   </SegmentTimeline>
</SegmentTemplate>

สําหรับการนําเสนอโดยใช้ <SegmentList> ดูตัวอย่างดังนี้

<Representation id="FirstRep" bandwidth="2000000" width="1280"
  height="720">
  <BaseURL>FirstRep/</BaseURL>
  <SegmentList timescale="90000" duration="270000">
     <RepresentationIndex sourceURL="representation-index.sidx"/>
     <SegmentURL media="seg-1.ts"/>
     <SegmentURL media="seg-2.ts"/>
     <SegmentURL media="seg-3.ts"/>
  </SegmentList>
</Representation>

สําหรับไฟล์กลุ่มเดียว <SegmentBase> มักจะใช้กับคําขอช่วงไบต์เพื่อระบุว่าส่วนใดของไฟล์ <BaseURL> ที่มีดัชนี และดึงข้อมูล URL ที่เหลือได้ในขณะที่เล่นต่อหรือเกิดขึ้น ช่วง Initialization จะระบุช่วงข้อมูลเมตาเริ่มต้น และ indexRange จะระบุดัชนีสําหรับกลุ่มสื่อ โปรดทราบว่าตอนนี้เรารองรับเฉพาะช่วงไบต์ติดต่อกันเท่านั้น

<Representation bandwidth="4190760" codecs="avc1.640028"
  height="1080" id="1" mimeType="video/mp4" width="1920">
  <BaseURL>video.mp4<BaseURL>
  <SegmentBase indexRange="674-1149">
    <Initialization range="0-673" />
  </SegmentBase>
</Representation>

ไม่ว่าจะใช้สตรีมใดอยู่ก็ตาม หากสตรีมได้รับการป้องกัน ส่วน <ContentProtection> จะปรากฏขึ้นภายใต้ <AdaptationSet> โดยที่ schemeIdUri จะระบุระบบ DRM ที่ไม่ซ้ําเพื่อการใช้งาน และอาจรวมรหัสคีย์ที่ไม่บังคับสําหรับการเข้ารหัสทั่วไปด้วย

<!-- Common Encryption -->
<ContentProtection
  schemeIdUri="urn:mpeg:dash:mp4protection:2011"
  value="cenc"
  cenc:default_KID="7D2714D0-552D-41F5-AD56-8DD9592FF891">
</ContentProtection>

<!-- Widevine -->
<ContentProtection
  schemeIdUri="urn:uuid:EDEF8BA9-79D6-4ACE-A3C8-27DCD51D21ED">
</ContentProtection>

ดูตัวอย่างและรายละเอียดเพิ่มเติมได้ที่ข้อกําหนด MPEG-DASH ด้านล่างนี้คือรายการแอตทริบิวต์ DASH เพิ่มเติมในแท็กที่ไม่ได้ระบุไว้ข้างต้น ซึ่งเรารองรับในขณะนี้

ชื่อแอตทริบิวต์ ฟังก์ชันแอตทริบิวต์
ระยะเวลาการนําเสนอสื่อ ความยาวของเนื้อหาวิดีโอ
ระยะเวลาขั้นต่ําของการอัปเดต แอตทริบิวต์ของแท็ก <MPD> ระบุความถี่ในการโหลดไฟล์ Manifest ซ้ํา
ประเภท แอตทริบิวต์ของแท็ก <MPD> คือ "ไดนามิก" เพื่อระบุว่านี่เป็นสตรีมแบบสด
เวลาออฟเซ็ตงานนําเสนอ แอตทริบิวต์ของแท็ก <SegmentBase> ระบุออฟเซ็ตเวลาการนําเสนอตั้งแต่ต้นช่วงเวลา
เลขเริ่มต้น ระบุจํานวนกลุ่มสื่อแรกในงานนําเสนอในช่วงเวลา ซึ่งมักจะใช้ในสตรีมแบบสด

นอกจากนี้ เรายังรองรับการจดจําช่อง EMSG ภายในส่วน MP4 สําหรับ DASH และให้ EmsgEvent แก่นักพัฒนาแอป

แม้ว่าโปรแกรมเล่นตัวรับเว็บปัจจุบันจะรองรับกรณีการใช้งาน DASH หลักๆ แล้ว แต่รายการแอตทริบิวต์ทั่วไปที่ DASH ในปัจจุบันของเราไม่สนใจหรือไม่ได้ใช้มีดังนี้ ซึ่งหมายความว่าไฟล์ Manifest ไม่ได้รับผลกระทบจากประสบการณ์การเล่นของเนื้อหา

  • เวลาเริ่มต้นที่พร้อมใช้งาน
  • การจัดข้อความเป็นกลุ่ม

HTTP Live Streaming (HLS)

ดูภาพรวมและข้อกําหนดฉบับเต็มของสตรีมมิงแบบสด HTTP ได้ที่นี่

จุดแข็งอย่างหนึ่งของ Web Receiver Player คือความสามารถในการรองรับการเล่น HLS ใน MSE HLS ส่งเพลย์ลิสต์หลักที่มีรายการสตรีมตัวแปรทั้งหมดพร้อมกับ URL ที่เกี่ยวข้อง ซึ่งต่างจาก DASH ที่มีไฟล์ Manifest อยู่ในไฟล์เดียว เพลย์ลิสต์เวอร์ชันแปรผันคือเพลย์ลิสต์สื่อ แท็ก HLS หลัก 2 รายการที่โปรแกรมเล่นตัวรับเว็บรองรับในเพลย์ลิสต์หลักมีดังนี้

ชื่อแท็ก ฟังก์ชันการทำงาน
#สตรีม EXT-X-INF ระบุอัตราบิต/สตรีมตัวแปร ต้องมีแอตทริบิวต์ BANDWIDTH ซึ่งรองรับการเลือกสตรีมมิงอัตราบิตที่ปรับเปลี่ยนได้ ขอแนะนําให้ใช้แอตทริบิวต์ CODECS ในการเริ่มต้น MSE เช่น "avc1.42c01e,mp4a.40.2" หากไม่ได้ระบุ เคสเริ่มต้นจะตั้งไว้เป็นวิดีโอ H264 หลัก 3.0 และเนื้อหาที่เข้ารหัสเสียง "mp4a.40.2"
#สื่อ XT-X ระบุเพลย์ลิสต์สื่อเพิ่มเติม (ในแอตทริบิวต์ URI) ที่แสดงถึงเนื้อหา โดยปกติแล้วจะเป็นสตรีมเสียงรูปแบบอื่น (เสียงเซอร์ราวด์ 5.1) หรือภาษาอื่นๆ อนุญาตแอตทริบิวต์ TYPE ที่มี VIDEO, AUDIO, SUBTITLES หรือ CLOSED-CAPTIONS การตั้งค่าแอตทริบิวต์ DEFAULT เป็น YES จะระบุการเลือกสตรีมทางเลือกนี้โดยค่าเริ่มต้น

รายการแท็ก HLS ที่ Web Receiver Player รองรับในเพลย์ลิสต์สื่อในปัจจุบันมีดังนี้

ชื่อแท็ก ฟังก์ชันการทำงาน
#ยกเว้น ข้อมูลสตรีมมักจะตามด้วยระยะเวลาของกลุ่มเป้าหมายในหน่วยวินาที และในบรรทัดถัดไปคือ URL ของกลุ่ม
#EXT-X-TARGETDURATION ระยะเวลาเป็นวินาทีที่แต่ละกลุ่มใช้ และยังกําหนดความถี่ในการดาวน์โหลด/รีเฟรชไฟล์ Manifest ของเพลย์ลิสต์สําหรับสตรีมแบบสดด้วย โปรแกรมเล่นเว็บ ไม่รองรับโปรแกรมเล่นที่สั้นกว่า 0.1 วินาที
#EXT-X-MEDIA-SEQUENCE หมายเลขลําดับ (มักเป็นสตรีมแบบสด) ที่กลุ่มแรกในเพลย์ลิสต์นี้แสดงถึง
#EXT-X-KEY ข้อมูลคีย์ DRM แอตทริบิวต์ METHOD ช่วยให้เราทราบถึงระบบคีย์ที่จะใช้ วันนี้เรารองรับ AES-128 และ SAMPLE-AES
#EXT-X-BYTERANGE ช่วงไบต์ที่จะดึงข้อมูลสําหรับ URL ของกลุ่ม
#การไม่ยอมรับ XT-X ระบุความไม่ต่อเนื่องระหว่างกลุ่มที่อยู่ติดกัน ซึ่งมักจะปรากฏกับการแทรกโฆษณาฝั่งเซิร์ฟเวอร์ที่กลุ่มโฆษณาจะปรากฏตรงกลางของสตรีมหลัก
#EXT-X-โปรแกรม-วันที่-เวลา เวลาสัมบูรณ์ของตัวอย่างแรกของกลุ่มถัดไป เช่น "2016-09-21T23:23:52.066Z"
#EXT-X-ENDLIST ไม่ว่าจะเป็น VOD หรือสตรีมแบบสด

สําหรับสตรีมแบบสด เราใช้ #EXT-X-PROGRAM-DATE-TIME และ #EXT-X-MEDIA-SEQUENCE เป็นปัจจัยหลักในการพิจารณาวิธีรวมไฟล์ Manifest ที่เพิ่งรีเฟรชใหม่ หากมี ระบบจะใช้ #EXT-X-PROGRAM-DATE-TIME เพื่อจับคู่กลุ่มที่รีเฟรช ไม่เช่นนั้นจะใช้หมายเลข #EXT-X-MEDIA-SEQUENCE โปรดทราบว่าตามข้อกําหนดของ HLS เราจะไม่ใช้การเปรียบเทียบชื่อไฟล์สําหรับการจับคู่

การใช้งาน HLS ของเรารองรับการเลือกสตรีมเสียงอื่น เช่น เสียงเซอร์ราวด์ 5.1 เป็นเสียงหลัก ซึ่งทําได้โดยการมีแท็ก #EXT-X-MEDIA ที่มีตัวแปลงรหัสสํารอง รวมถึงระบุรูปแบบกลุ่มในการกําหนดค่าสตรีม

โปรแกรมเล่นตัวรับเว็บคาดว่าจะทํางานตามข้อมูลจําเพาะที่เจาะจง เช่น หลังจากแท็ก #EXT-INF เราคาดหวัง URI หากไม่ใช่ URI เป็นต้น #EXT-X-DISCOUNTINUITY จะทําให้การแยกวิเคราะห์สําหรับเพลย์ลิสต์ล้มเหลว

ทุก #EXT-X-TARGETDURATION วินาที เราจะโหลดซ้ําเพลย์ลิสต์/ไฟล์ Manifest เพื่อรับรายการกลุ่มใหม่และอัปเดตการอัปเดตภายในใหม่ของกลุ่มทั้งหมดไปยังกลุ่มใหม่ ทุกครั้งที่มีการขอข้อมูล เราจะค้นหาในช่วงที่ค้นหาได้เท่านั้น สําหรับการถ่ายทอดสด เราอนุญาตให้แสดงตั้งแต่จุดเริ่มต้นของรายการที่ใหม่ที่สุดไปจนถึงระยะเวลาเป้าหมาย 3 ช่วงจากตอนท้ายเท่านั้น ตัวอย่างเช่น หากคุณมีรายการกลุ่ม 10 กลุ่มและอยู่ในกลุ่ม 6 คุณก็ค้นหาได้เพียง 7 กลุ่ม ส่วน 8 กลุ่มก็ไม่ได้

การรองรับรูปแบบกลุ่ม

CAF SDK รองรับการเล่นเนื้อหาที่นําส่งในรูปแบบต่างๆ ตามที่อ้างถึงใน HlsSegmentFormat สําหรับเสียงและ HlsVideoSegmentFormat สําหรับวิดีโอ ซึ่งรวมถึงการสนับสนุนสําหรับเสียงที่แพ็กให้แล้ว เช่น การเล่น AAC และ AC3 ทั้งที่เข้ารหัสและไม่ได้เข้ารหัส คุณต้องระบุข้อมูลนี้ในMediaInformationของ LoadRequestData เพื่ออธิบายเนื้อหาของคุณอย่างเหมาะสมให้โปรแกรมเล่นเห็น หากไม่ได้ระบุ การกําหนดค่าโปรแกรมเล่นเริ่มต้นจะพยายามเล่นเนื้อหาเป็นเนื้อหาแพ็กเกจ Transport Stream คุณตั้งค่าพร็อพเพอร์ตี้นี้จากผู้ส่งคนใดก็ได้ในข้อมูลคําขอโหลด (Android, iOS และเว็บ) หรือภายในผู้รับผ่านโปรแกรมรับข้อความ

ดูตัวอย่างข้อมูลโค้ดด้านล่างหรือคู่มือการโหลดสื่อโดยใช้ contentId, contentUrl และเอนทิตี เพื่อดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีการเตรียมเนื้อหาในเครื่องรับข้อมูลบนเว็บ

playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.LOAD, loadRequestData => {
      ...
      // Specify segment format for an HLS stream playing CMAF packaged content.
      loadRequestData.media.contentType = 'application/x-mpegurl';
      loadRequestData.media.hlsSegmentFormat = cast.framework.messages.HlsSegmentFormat.FMP4;
      loadRequestData.media.hlsVideoSegmentFormat = cast.framework.messages.HlsVideoSegmentFormat.FMP4;
      ...
      return loadRequestData;
    });

การปกป้องเนื้อหา

Cast SDK รองรับ SAMPLE-AES หรือ SAMPLE-AES-CTR ซึ่งใช้ระบุ URI ของเวกเตอร์การเริ่มต้นได้ตามที่ระบุไว้ในส่วนแท็ก #EXT-X-KEY ด้านบน

EXT-X-KEY: METHOD=SAMPLE-AES, \
URI="data:text/plain;base64,XXXXXX", \
IV=0x6df49213a781e338628d0e9c812d328e, \
KEYFORMAT="com.widevine", \
KEYFORMATVERSIONS="1"

KEYFORMAT ที่เรารองรับคือ Widevine และ URI มีข้อมูล DRM ที่เข้ารหัส Base64 XXXXXXX ซึ่งเมื่อถอดรหัสจะมีรหัสคีย์ ดังนี้

{
   "content_id": "MTQ1NjkzNzM1NDgxNA==",
   "key_ids": [
      "xxxxxxxxxxxxxxxx"
   ]
}

เวอร์ชัน 1 จะกําหนดแอตทริบิวต์ต่อไปนี้

แอตทริบิวต์ ตัวอย่าง คำอธิบาย
KEYFORMATVERSIONS "1" ข้อเสนอนี้กําหนดรูปแบบคีย์เวอร์ชัน 1
KEYFORMAT "urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed" UUID คือ UUID ของ Widevine จาก DASH IF IOP สตริงเดียวกันนี้จะใช้กับ MPD ที่มีสตรีมที่เข้ารหัส Widevine
URI "data:text/plain;base64, <base64 encoded PSSH box>" URI ของสตรีมที่มีประเภทข้อมูลและช่อง PSSH
METHOD SAMPLE-AES-CTR ระบุการเข้ารหัสที่ใช้เมื่อเข้ารหัสเนื้อหา SAMPLE-AES บ่งชี้ว่าเนื้อหาได้รับการเข้ารหัสโดยใช้ "cbcs" SAMPLE-AES-CTR เป็นสัญญาณว่าเนื้อหาได้รับการเข้ารหัสโดยใช้รูปแบบการป้องกัน AES-CTR รูปแบบใดรูปแบบหนึ่ง นั่นคือ "cenc"

แอตทริบิวต์ที่แมปกับ DASH MPD:

แอตทริบิวต์ คำอธิบาย
KEYFORMAT แอตทริบิวต์ schemeIdUri ขององค์ประกอบ ContentProtection
URI เนื้อหาขององค์ประกอบ cenc:pssh
KEYID สตริงเลขฐานสิบหก 16 ไบต์ที่เข้ารหัสรหัสคีย์ซึ่งมีบทบาทเดียวกันกับ default_kid ใน MPEG DASH หากใช้รูปแบบคีย์แบบลําดับชั้น คีย์นี้จะเป็นคีย์ "root"

ตัวอย่างเพลย์ลิสต์ HLS ที่มีการส่งสัญญาณ V2:

#EXTM3U
#EXT-X-VERSION:6
#EXT-X-TARGETDURATION:2
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-MAP:URI="init_segment.mp4"
#EXTINF:1.001,
output_video-1.mp4
#EXT-X-DISCONTINUITY
#EXT-X-KEY:METHOD=SAMPLE-AES,URI="data:text/plain;base64,AAAAPXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAB0aDXdpZGV2aW5lX3Rlc3QiDHRlc3QgY29udGVudA==",KEYID=0x112233445566778899001122334455,KEYFORMAT="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed",KEYFORMATVERSION="1"
#EXTINF:1.001,
output_video-2.mp4
#EXTINF:0.734,
output_video-3.mp4
#EXT-X-ENDLIST

ด้านล่างนี้คือรายการฟีเจอร์และแท็กใน HLS ที่เราไม่ได้ใช้หรือไม่รองรับ การปรากฏหรือขาดหายไปไม่ส่งผลต่อลักษณะการทํางานของสตรีมมิง

  • ระบบจะไม่สนใจแอตทริบิวต์ RESOLUTION= ใน #EXT-X-STREAM-INF
  • ไม่ได้ใช้แอตทริบิวต์ AUTOSELECT= ใน #EXT-X-MEDIA แต่เราอาศัย DEFAULT=
  • ระบบจะไม่สนใจ #EXT-X-I-FRAME-STREAM-INF ในเพลย์ลิสต์หลัก
  • ไม่สนใจ #EXT-X-DISCONTINUITY-SEQUENCE แล้ว
  • #EXT-X-PLAYLIST-TYPE:EVENT แสดงในสตรีมแบบสดได้และ #EXT-X-PLAYLIST-TYPE:VOD อาจแสดงในสตรีม VOD ได้ด้วย แต่ในปัจจุบัน ตัวรับสัญญาณบนเว็บของเราจะใช้เฉพาะ #EXT-X-ENDLIST เพื่อระบุ VOD สดกับ VOD เท่านั้น

สตรีมมิงอย่างราบรื่น

ข้อมูลจําเพาะของสตรีมมิงที่ราบรื่นของ Microsoft

สตรีมมิงที่ราบรื่นมีโปรโตคอลสตรีมมิงแบบปรับขนาดได้และข้อกําหนด XML ผ่าน HTTP (คล้ายกับ DASH) Smooth Streaming ต่างจาก DASH โดยแนะนําให้ใช้เฉพาะแพ็กเกจ MPEG-4 สําหรับกลุ่มสื่อเท่านั้น

ตารางแท็กและแอตทริบิวต์ที่พบบ่อยที่สุดในสตรีมมิงอย่างราบรื่นที่โปรแกรมเล่นตัวรับเว็บรองรับในปัจจุบันมีดังนี้ มีแนวคิดมากมายอธิบายไว้ในส่วน DASH ข้างต้น

แท็ก/แอตทริบิวต์ การใช้งาน
<SmoothStreamingMedia> แท็กหลักของไฟล์ Manifest มีแอตทริบิวต์ดังนี้
  • TimeScale: จํานวนหน่วยที่แสดงถึง 1 วินาที ซึ่งโดยปกติจะเพิ่มขึ้น 10,000,000 รายการ
  • ระยะเวลา: ความยาวของเนื้อหาในการปรับขนาดเวลา ตัวรับสัญญาณเว็บไม่รองรับระยะเวลาที่เก่ากว่า 0.1 วินาที
  • IsLive: ไฟล์ Manifest เป็นสื่อสดหรือไม่
<สตรีมดัชนี> สตรีมชุดหนึ่งที่คล้ายกับ AdaptationSet ของ DASH ซึ่งโดยปกติแล้วจะเป็น "ข้อความ", "วิดีโอ" หรือ "เสียง" โดยปกติแล้วแอตทริบิวต์ URL จะมี URL ส่วนย่อยของเทมเพลตโดยใช้ข้อมูลต่างๆ เช่น อัตราบิตหรือเวลาเริ่มต้น
<ระดับคุณภาพ> แท็ก QualityLevel แต่ละแท็กจะระบุอัตราบิตและตัวแปลงรหัส FourCC โค้ด FourCC มักจะเป็น "H264", "AVC1", "AACL" ฯลฯ ส่วนวิดีโอจะระบุความละเอียดผ่าน MaxWidth และ MaxHeight สําหรับเสียง จะระบุความถี่ (เช่น 44100) ผ่านการสุ่มตัวอย่างและอัตราของช่อง
<c> สตรีมองค์ประกอบ Fragment มีรายการต่อไปนี้
  • d: ระยะเวลาของส่วนย่อย
  • t: เวลาสื่อของส่วนย่อย
<การป้องกัน> แท็กที่มีแอตทริบิวต์ SystemID ที่ไม่บังคับซึ่งมีรหัสของระบบ DRM เพื่อใช้ใต้แท็ก <SmoothStreamingMedia>
<ส่วนหัวการป้องกัน> ในส่วน <Protection> อาจมีแอตทริบิวต์ SystemID และข้อมูลที่กําหนดเอง ซึ่งโดยทั่วไปจะเข้ารหัส Base64 ส่วน Widevine จะมีรหัสคีย์ ความยาวคีย์ รหัสอัลกอริทึม เช่น AESCTR, LA_URL (URL การได้ผู้ใช้ใหม่สําหรับใบอนุญาต), LUI_URL (URL อินเทอร์เฟซผู้ใช้ใบอนุญาต) และ DS_ID (รหัสบริการโดเมน)

การปกป้องเนื้อหา

หากต้องการเข้ารหัสรหัสระบบการป้องกันอย่างเหมาะสม โปรดใช้การแมปด้านล่าง

  • WIDEVINE: "EDEF8BA9-79D6-4ACE-A3C8-27DCD51D21ED",
  • ล้าง: "1077EFEC-C0B2-4D02-ACE3-3C1E52E2FB4B",
  • MPEG_DASH_MP4PROTECTION: "URN:MPEG:DASH:MP4PROTECTION:2011"

สําหรับ <ProtectionHeader> ด้านล่างนี้เป็นตัวอย่างข้อมูลที่เข้ารหัส Base64 เมื่อถอดรหัสแล้ว ข้อมูลจะอยู่ในรูปแบบที่ถอดรหัสเหมือนกับที่อธิบายไว้ในการสนับสนุนการคุ้มครองเนื้อหา DASH ข้างต้น

<Protection>
  <ProtectionHeader SystemID="9a04f079-9840-4286-ab92-e65be0885f95">
    $BASE64ENCODED_DATA
  </ProtectionHeader>
</Protection>

ด้านล่างเป็นตัวอย่างของไฟล์ Manifest สตรีมมิงแบบ Smooth แบบสดที่มีเนื้อหาระยะเวลา 3,000 วินาที

<?xml version="1.0"?>
  <SmoothStreamingMedia MajorVersion="2" MinorVersion="0" Duration="3000000000"
    TimeScale="10000000" IsLive="TRUE" LookAheadFragmentCount="2" DVRWindowLength="600000000" CanSeek="TRUE" CanPause="TRUE">
    <StreamIndex Type="text" Name="textstream301_swe" Language="swe" Subtype="CAPT" Chunks="0"
      TimeScale="10000000" Url="QualityLevels({bitrate})/Fragments(textstream301_swe={start time})">
      <QualityLevel Index="0" Bitrate="20000" CodecPrivateData="" FourCC="DFXP"/>
        <c d="40000000" t="80649382288125"/>
        <c d="39980000"/>
        <c d="40020000"/>
    </StreamIndex>
    <Protection>
      <ProtectionHeader> SystemID="$BASE64ENCODEDDRMDATA$"</ProtectionHeader>
    </Protection>
    <StreamIndex Type="audio" Name="audio101_eng" Language="eng" Subtype="AACL" Chunks="0"
      TimeScale="10000000" Url="QualityLevels({bitrate})/Fragments(audio101_eng={start time})">
      <QualityLevel Index="0" Bitrate="128000" CodecPrivateData="1290" FourCC="AACL" AudioTag="255"
        Channels="2" SamplingRate="32000" BitsPerSample="16" PacketSize="4"/>
      <c d="40000000" t="80649401327500"/>
      <c d="40000000"/>
      <c d="40000000"/>
    </StreamIndex>
    <StreamIndex Type="video" Name="video" Subtype="AVC1" Chunks="0" TimeScale="10000000"
      Url="QualityLevels({bitrate})/Fragments(video={start time})">
      <QualityLevel Index="0" Bitrate="400000" CodecPrivateData="000000016742E01596540C0EFCB808140000000168CE3880"
        FourCC="AVC1" MaxWidth="384" MaxHeight="216"/>
      <QualityLevel Index="1" Bitrate="800000" CodecPrivateData="00000001674D401E965281004B6020500000000168EF3880"
        FourCC="AVC1" MaxWidth="512" MaxHeight="288"/>
      <QualityLevel Index="2" Bitrate="1600000" CodecPrivateData="00000001674D401E965281B07BCDE020500000000168EF3880"
        FourCC="AVC1" MaxWidth="854" MaxHeight="480"/>
      <QualityLevel Index="3" Bitrate="2200000" CodecPrivateData="00000001674D401F96528080093602050000000168EF3880"
        FourCC="AVC1" MaxWidth="1024" MaxHeight="576"/>
      <c d="40000000" t="80649401378125"/>
      <c d="40000000"/>
      <c d="40000000"/>
    </StreamIndex>
  </SmoothStreamingMedia>

ในตัวอย่างข้างต้นของสตรีมวิดีโอ เทมเพลต URL คือ

QualityLevels({bitrate})/Fragments(video={start time})

ดังนั้น 2 กลุ่มแรก (สมมติว่าเราอยู่ในระดับคุณภาพดัชนี 2) จะเป็นค่าต่อไปนี้ โดยเวลาเริ่มต้นจะดึงมาจาก t="80649401378125" ใต้ดัชนีสตรีมวิดีโอและเพิ่มเวลา 4 วินาที * 10000000 ต่อกลุ่ม

QualityLevels(2)/Fragments(video=80649401378125)
QualityLevels(2)/Fragments(video=80649441378125)
...

ต่อไปนี้คือรายการแอตทริบิวต์สตรีมมิงที่ราบรื่นที่เราไม่สนใจในขณะนี้ และไม่ส่งผลต่อประสบการณ์การใช้งานสตรีมมิง ไม่ว่าจะระบุหรือไม่ก็ตาม

  • CanSeek, CanPaused ในแท็ก <SmoothStreamingMedia>
  • กลุ่ม คุณภาพระดับ ในแท็ก <StreamIndex> แต่จะคํานวณจํานวนกลุ่มและระดับคุณภาพโดยอิงตามข้อมูลที่ระบุภายใน <StreamIndex> เช่น แท็ก QualityLevel จริงและแท็ก <c> แทน
  • ระบบจะไม่ใช้ BitsPerSample และไม่มีPacketSize ใน <QualityLevel>

ตรวจสอบประเภทการแสดงผล

เมธอด canDisplayType จะตรวจหาความสามารถของวิดีโอและเสียงของอุปกรณ์ Web Receiver และการแสดงผลโดยตรวจสอบพารามิเตอร์สื่อที่ส่งมาซึ่งส่งคืนบูลีน พารามิเตอร์ทั้งหมดแต่พารามิเตอร์แรกจะมีหรือไม่ก็ได้ ยิ่งใส่พารามิเตอร์มาก การตรวจสอบก็จะยิ่งแม่นยํามากขึ้น

ลายเซ็นของ canDisplayType(<em>mimeType</em>,<em>codecs</em>,<em>width</em>,<em>height</em>,<em>framerate</em>)

ตัวอย่างเช่น

ตรวจสอบว่าอุปกรณ์ Web Receiver และจอแสดงผลรองรับประเภทวิดีโอ/mp4 ด้วยตัวแปลงรหัส ขนาด และอัตราเฟรมนี้หรือไม่

canDisplayType("video/mp4", "avc1.42e015,mp4a.40.5", 1920, 1080, 30)

ตรวจสอบว่าอุปกรณ์ Web Receiver และจอแสดงผลรองรับรูปแบบวิดีโอ 4K สําหรับตัวแปลงรหัสนี้หรือไม่โดยระบุความกว้าง 3840 และความสูง 2160

canDisplayType("video/mp4", "hev1.1.2.L150", 3840, 2160)

ตรวจสอบว่าอุปกรณ์ Web Receiver และจอแสดงผลรองรับ HDR10 สําหรับตัวแปลงรหัส มิติข้อมูล และอัตราเฟรมนี้หรือไม่

canDisplayType("video/mp4", "hev1.2.6.L150", 3840, 2160, 30)

ตรวจสอบว่าอุปกรณ์ Web Receiver และจอแสดงผลรองรับ Dolby Vision (DV) สําหรับตัวแปลงรหัส ขนาด และอัตราเฟรมนี้หรือไม่

canDisplayType("video/mp4", "dvhe.04.06", 1920, 1080, 30)

DRM

หมายเหตุ: ประโยชน์หลักอย่างหนึ่งของการใช้ Web Receiver SDK คือแอปของคุณไม่จําเป็นต้องโหลด MPL อีกต่อไปและรองรับการเล่นสื่อแยกกัน เนื่องจาก Web Receiver SDK จะจัดการให้คุณ

เนื้อหาสื่อบางอย่างต้องใช้การจัดการสิทธิ์ดิจิทัล (DRM) สําหรับเนื้อหาสื่อที่มีใบอนุญาต DRM (และ URL ของคีย์) ที่เก็บไว้ในไฟล์ Manifest (DASH หรือ HLS) แล้ว Cast SDK จะจัดการเคสนี้ให้คุณ ชุดย่อยของเนื้อหานั้นต้องใช้ licenseUrl ซึ่งจําเป็นสําหรับการขอคีย์การถอดรหัส ใน Web Receiver คุณสามารถใช้ PlaybackConfig เพื่อตั้งค่า licenseUrl ได้ตามต้องการ

ข้อมูลโค้ดต่อไปนี้อธิบายวิธีตั้งค่าข้อมูลคําขอสําหรับคําขอใบอนุญาต เช่น withCredentials

const context = cast.framework.CastReceiverContext.getInstance();
const playbackConfig = new cast.framework.PlaybackConfig();
// Customize the license url for playback
playbackConfig.licenseUrl = 'http://widevine/yourLicenseServer';
playbackConfig.protectionSystem = cast.framework.ContentProtection.WIDEVINE;
playbackConfig.licenseRequestHandler = requestInfo => {
  requestInfo.withCredentials = true;
};
context.start({playbackConfig: playbackConfig});

// Update playback config licenseUrl according to provided value in load request.
context.getPlayerManager().setMediaPlaybackInfoHandler((loadRequest, playbackConfig) => {
  if (loadRequest.media.customData && loadRequest.media.customData.licenseUrl) {
    playbackConfig.licenseUrl = loadRequest.media.customData.licenseUrl;
  }
  return playbackConfig;
});

หากคุณผสานรวม Google Assistant ข้อมูล DRM บางอย่าง เช่น ข้อมูลเข้าสู่ระบบที่จําเป็นสําหรับเนื้อหาอาจลิงก์กับบัญชี Google ของคุณโดยตรงผ่านกลไกต่างๆ เช่น OAuth/SSO ในกรณีดังกล่าว หากเนื้อหาสื่อโหลดผ่านเสียงหรือมาจากระบบคลาวด์ ระบบจะเรียกใช้ setCredentials จากระบบคลาวด์ไปยังอุปกรณ์แคสต์ที่ให้บริการข้อมูลเข้าสู่ระบบดังกล่าว แอปพลิเคชันที่เขียนแอป Web Receiver สามารถใช้ข้อมูล setCredentials เพื่อดําเนินการ DRM ได้ตามความจําเป็น ต่อไปนี้เป็นตัวอย่างการใช้ข้อมูลเข้าสู่ระบบเพื่อสร้างสื่อ

เคล็ดลับ: โปรดดูการโหลดสื่อโดยใช้ contentId, contentUrl และเอนทิตีด้วย

การจัดการช่องเสียง

เมื่อโปรแกรมเล่นแคสต์โหลดสื่อ ระบบจะตั้งค่าบัฟเฟอร์แหล่งที่มาของเสียงเดียว พร้อมกันนั้น ยังเลือกตัวแปลงรหัสที่เหมาะสมให้บัฟเฟอร์ใช้ตามประเภท MIME ของแทร็กหลักด้วย วิธีตั้งค่าบัฟเฟอร์และตัวแปลงรหัสใหม่

  • เมื่อวิดีโอเริ่มเล่น
  • ในทุกช่วงพักโฆษณา และ
  • ทุกครั้งที่เนื้อหาหลักกลับมาทํางานอีกครั้ง

เนื่องจากบัฟเฟอร์ใช้ตัวแปลงรหัสตัวเดียว และเนื่องจากมีการเลือกตัวแปลงรหัสตามแทร็กหลัก อาจมีบางกรณีที่ระบบกรองแทร็กสํารองออกและไม่ได้ยินเสียง ปัญหานี้อาจเกิดขึ้นได้เมื่อแทร็กหลักของโปรแกรมสื่ออยู่ในเสียงเซอร์ราวด์ แต่แทร็กเสียงรองใช้เสียงสเตอริโอ เนื่องจากแทร็กรองมักใช้เพื่อแสดงเนื้อหาในภาษาอื่นๆ การระบุสื่อที่มีแทร็กจํานวนมากอาจส่งผลอย่างมาก เช่น ผู้ชมจํานวนมากไม่ได้ยินเนื้อหาในภาษาของตน

สถานการณ์ต่อไปนี้แสดงให้เห็นถึงความสําคัญของการจัดโปรแกรมเมื่อแทร็กหลักและแทร็กรองมีจํานวนช่องเท่ากัน

สถานการณ์ที่ 1 - สตรีมสื่อที่ไม่มีความเท่าเทียมของช่องในแทร็กหลักและแทร็กรอง

  • ภาษาอังกฤษ - ช่อง AC-3 5.1 (หลัก)
  • sweuce - AAC 2 ช่อง
  • ฝรั่งเศส - AAC 2 ช่อง
  • เยอรมนี - AAC 2 ช่อง

ในสถานการณ์นี้ หากตั้งค่าภาษาของโปรแกรมเล่นเป็นภาษาอื่นที่ไม่ใช่ภาษาอังกฤษ ผู้ใช้จะไม่ได้ยินแทร็กที่ตนต้องการฟังเนื่องจากแทร็ก 2 ช่องทั้งหมดถูกกรองออกระหว่างการเล่น แทร็กเดียวที่เล่นได้คือ AC-3 5.1-channel หลักและจะมีการตั้งค่าภาษาเป็นภาษาอังกฤษเท่านั้น

สถานการณ์ที่ 2 - สตรีมสื่อที่มีความเท่าเทียมของช่องในแทร็กหลักและแทร็กรอง

  • ภาษาอังกฤษ - ช่อง AC-3 5.1 (หลัก)
  • สวีเดน - ช่อง AC-3 5.1
  • french - ช่อง AC-3 5.1
  • เยอรมนี - ช่อง AC-3 5.1

เนื่องจากแทร็กของสตรีมทั้งหมดมีช่องจํานวนเท่ากัน กลุ่มเป้าหมายจะได้ยินแทร็กโดยไม่คํานึงถึงภาษาที่เลือก

การจัดการช่องเสียงของ Shaka

โปรแกรมเล่น Shaka (DASH) จะมีค่าเริ่มต้นเป็นจํานวนแชแนลที่ต้องการ 2 ตัวเป็นมาตรการบรรเทาเมื่อพบสื่อที่ไม่มีความเท่าเทียมกันในแทร็กเสียงรอง

หากแทร็กหลักไม่ใช่เสียงเซอร์ราวด์ (เช่น แทร็กสเตอริโอแบบ 2 ช่อง) โปรแกรมเล่น Shaka จะมีค่าเริ่มต้นเป็น 2 ช่องและจะกรองแทร็กสื่อรองที่มีช่องมากกว่า 2 ช่องโดยอัตโนมัติ

นอกจากนี้ คุณยังกําหนดค่าจํานวนช่องเสียงของ Shaka ได้โดยการตั้งค่า preferredAudioChannelCount ในพร็อพเพอร์ตี้ shakaConfig ของ cast.framework.PlaybackConfig

เช่น

shakaConfig = { "preferredAudioChannelCount": 6 };

เมื่อตั้ง preferredAudioChannelCount เป็น 6 แล้ว Shaka Player จะตรวจสอบว่ารองรับตัวแปลงสัญญาณเสียงเซอร์ราวด์ (AC-3 หรือ EC-3) ได้หรือไม่ และกรองแทร็กสื่อที่ไม่สอดคล้องกับจํานวนช่องที่ต้องการออกโดยอัตโนมัติ