โปรโตคอลการสตรีมของ Web Receiver

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

DASH HTTP Live สตรีมมิง และ การสตรีมที่ราบรื่น

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

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

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

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

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

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

ภายใน <AdaptationSet> แต่ละรายการ รายการแท็ก <Representation> ควร และ Web Receiver Player จะใช้ข้อมูล 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 (หน่วยที่จะแสดงหนึ่งวินาที) มักรวมเป็นส่วนหนึ่งของแอตทริบิวต์ของ <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> ที่มีส่วน และสามารถดึงข้อมูลส่วนที่เหลือได้ตามความต้องการเมื่อการเล่นยังคงดำเนินต่อไปหรือการค้นหา เกิดขึ้น ช่วง Initialization จะระบุช่วงข้อมูลเมตา init และ 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 เพิ่มเติมในแท็กที่ไม่ได้กล่าวถึงข้างต้น ปัจจุบันที่รองรับ

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

เรายังรองรับการระบุกล่อง EMSG ภายในส่วนย่อย MP4 สำหรับ DASH และ โปรดระบุ EmsgEvent สำหรับนักพัฒนาซอฟต์แวร์

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

  • availabilityStartTime
  • segmentAlignment

HTTP Live Streaming (HLS)

รับภาพรวมและข้อกำหนดทั้งหมดของสตรีมมิงแบบสดผ่าน HTTP ได้ ที่นี่

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

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

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

ชื่อแท็ก ฟังก์ชันการทำงาน
#EXTINF ข้อมูลสตรีม ซึ่งโดยปกติแล้วตามด้วยระยะเวลาของกลุ่มใน วินาที และในบรรทัดถัดไป URL ของเซกเมนต์
#EXT-X-TARGETDURATION ความยาวเป็นวินาทีของแต่ละส่วน และยังกำหนดความถี่ ดาวน์โหลด/รีเฟรชไฟล์ Manifest ของเพลย์ลิสต์สำหรับสตรีมแบบสด เว็บรีซีฟเวอร์ โปรแกรมเล่นไม่รองรับระยะเวลาที่สั้นกว่า 0.1 วินาที
#EXT-X-MEDIA-SEQUENCE หมายเลขลำดับ (มักเป็นสตรีมแบบสด) ที่ส่วนแรกอยู่ ของเพลย์ลิสต์นี้
#EXT-X-KEY ข้อมูลคีย์ DRM แอตทริบิวต์ METHOD บอกคีย์ที่เรา ในการใช้งานได้ ปัจจุบันเรารองรับ AES-128 และ SAMPLE-AES ที่ใช้เวลาเพียง 2 นาที
#EXT-X-BYTERANGE ช่วงไบต์ที่จะดึงข้อมูลสำหรับ URL เซกเมนต์
#EXT-X-DISCONTINUITY ระบุความไม่ต่อเนื่องระหว่างเซกเมนต์ที่อยู่ติดกัน ซึ่งมักจะเห็น โดยใช้การแทรกโฆษณาฝั่งเซิร์ฟเวอร์ที่มีกลุ่มโฆษณาปรากฏขึ้นตรงกลาง ได้
#EXT-X-PROGRAM-DATE-TIME เวลาสัมบูรณ์ของตัวอย่างแรกของส่วนถัดไป เช่น &quot;2016-09-21T23:23:52.066Z&quot;.
#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 ที่มีตัวแปลงรหัสอื่น รวมถึงการระบุ รูปแบบกลุ่มในการกำหนดค่าสตรีม

Web Receiver Player คาดหวังลักษณะการทำงานบางอย่างต่อข้อมูลจำเพาะ ตัวอย่างเช่น หลังจาก #EXT-INF เราต้องการ URI หากไม่ใช่ URI ตัวอย่างเช่น #EXT-X-DISCOUNTINUITY จะทำให้การแยกวิเคราะห์ล้มเหลวสำหรับเพลย์ลิสต์

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

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

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

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

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;
    });

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

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

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 แบบกว้างจาก 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 หากใช้รูปแบบคีย์ตามลำดับชั้น นี่จะเป็น "รูท"

ตัวอย่างเพลย์ลิสต์ 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

สตรีมได้ราบรื่น

อย่างเป็นทางการของ Microsoft ข้อกำหนดของ Smooth Streaming

การสตรีมที่ราบรื่นมีโปรโตคอลสตรีมมิงแบบปรับอัตโนมัติและข้อมูลจำเพาะของ XML ผ่าน HTTP (คล้ายกับ DASH) Smooth Streaming ขอแนะนำที่แตกต่างจาก DASH เฉพาะบรรจุภัณฑ์ MPEG-4 สำหรับกลุ่มสื่อ

นี่คือตารางแท็กและแอตทริบิวต์ที่ใช้กันมากที่สุดใน Smooth Streaming ที่ Web Receiver Player รองรับในปัจจุบัน เราได้อธิบายแนวคิดหลายอย่างไว้ใน ส่วน DASH ด้านบน

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

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

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

  • วิดวิน: "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 Streaming แบบสดที่มีเวลา 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) ดังต่อไปนี้ พร้อมเวลาเริ่มต้นจาก t="80649401378125" ภายใต้ Video StreamIndex และการเพิ่มเวลา 4 วินาที * 10000000 ต่อกลุ่ม:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

DRM

เนื้อหาสื่อบางอย่างต้องมีการจัดการสิทธิ์ดิจิทัล (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 และentity

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

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

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

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

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

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

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

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

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

  • ภาษาอังกฤษ - ช่อง AC-3 5.1 (หลัก)
  • สวีเดน - ช่อง AC-3 5.1
  • ฝรั่งเศส - ช่อง 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) และ จะกรองแทร็กสื่อใดๆ ที่ไม่เป็นไปตามความต้องการโดยอัตโนมัติ จำนวนช่องสัญญาณ