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>
รายการอยู่ และ 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
(หน่วยที่ใช้แทน 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>
ที่มีดัชนี และระบบจะดึงข้อมูลส่วนที่เหลือตามคำขอได้เมื่อเล่นไปเรื่อยๆ หรือการค้นหาเกิดขึ้น ในส่วนนี้ ช่วง 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 | ระบุจำนวนสื่อกลุ่มแรกในงานนำเสนอในช่วงเวลาหนึ่ง ซึ่งมักจะใช้ในสตรีมแบบสด |
นอกจากนี้เรายังรองรับการใส่กล่อง EMSG ภายใน Fragment MP4 สำหรับ DASH และให้ EmsgEvent
แก่นักพัฒนาแอปด้วย
แม้ว่าโปรแกรมเล่นเว็บรีซีฟเวอร์ปัจจุบันของเราจะรองรับ Use Case หลักของ DASH แต่นี่คือรายการแอตทริบิวต์ทั่วไปที่การใช้ DASH ในปัจจุบันไม่สนใจหรือไม่ได้ใช้ ซึ่งหมายความว่าไม่ว่าไฟล์ Manifest จะมีไฟล์ Manifest อยู่หรือไม่ก็ตาม จะไม่มีผลต่อประสบการณ์การเล่นของเนื้อหา
- availabilityStartTime
- segmentAlignment
HTTP Live Streaming (HLS)
ดูภาพรวมและข้อกำหนดทั้งหมดของสตรีมมิงแบบสดด้วย HTTP ได้ที่นี่
จุดแข็งที่สำคัญอย่างหนึ่งของ Web Receiver Player คือความสามารถในการรองรับการเล่น HLS ใน MSE HLS จะส่งเพลย์ลิสต์หลักที่มีรายการสตรีมรูปแบบต่างๆ ทั้งหมดพร้อม URL ที่เกี่ยวข้อง ซึ่งต่างจาก DASH ที่ไฟล์ Manifest จะมาอยู่ในไฟล์เดียว เพลย์ลิสต์เวอร์ชันแปรผันคือเพลย์ลิสต์สื่อ แท็ก HLS หลัก 2 รายการที่ Web Receiver Player สนับสนุนในขณะนี้ในเพลย์ลิสต์หลัก ได้แก่
ชื่อแท็ก | ฟังก์ชันการทำงาน |
---|---|
#EXT-X-STREAM-INF | ระบุสตรีมแบบอัตราบิต/ตัวแปร คุณต้องระบุแอตทริบิวต์ BANDWIDTH ซึ่งรองรับการเลือกสตรีมมิงแบบอัตราบิตที่ปรับเปลี่ยนได้ ขอแนะนำอย่างยิ่งให้ใช้แอตทริบิวต์ CODECS ในการเริ่มต้น MSE เช่น "avc1.42c01e,mp4a.40.2" หากไม่ได้ระบุไว้ ระบบจะใช้เคสเริ่มต้นเป็นวิดีโอ 3.0 ของโปรไฟล์หลัก H264 และเนื้อหาที่เข้ารหัสเสียง "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 ของเพลย์ลิสต์สำหรับสตรีมแบบสดด้วย Web Receiver ไม่รองรับระยะเวลาที่สั้นกว่า 0.1 วินาที |
#EXT-X-MEDIA-SEQUENCE | หมายเลขลำดับ (ซึ่งมักจะเป็นของสตรีมแบบสด) ที่แสดงส่วนแรกในเพลย์ลิสต์นี้ |
#EXT-X-KEY | ข้อมูลคีย์ DRM แอตทริบิวต์ METHOD จะช่วยให้เรา
ใช้ระบบคีย์ใด วันนี้เรารองรับ AES-128 และ SAMPLE-AES |
#EXT-X-BYTERANGE | ช่วงไบต์ที่จะดึงข้อมูล URL ของกลุ่ม |
#EXT-X-DISCONTINUITY | ระบุความไม่ต่อเนื่องระหว่างกลุ่มที่ต่อเนื่องกัน ซึ่งมักพบบ่อยในการแทรกโฆษณาฝั่งเซิร์ฟเวอร์ที่มีกลุ่มโฆษณาปรากฏขึ้นกลางสตรีมหลัก |
#EXT-X-PROGRAM-DATE-TIME | เวลาสัมบูรณ์ของตัวอย่างแรกของส่วนถัดไป เช่น "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
ที่มีตัวแปลงรหัสทางเลือก รวมถึงการระบุรูปแบบกลุ่มในการกำหนดค่าสตรีม
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
เพื่ออธิบายเนื้อหาของคุณแก่โปรแกรมเล่นอย่างเหมาะสม หากไม่ได้ระบุไว้ การกำหนดค่าโปรแกรมเล่นเริ่มต้นจะพยายามเล่นเนื้อหาเป็นเนื้อหาแพ็กเกจ Transport Stream พร็อพเพอร์ตี้นี้ตั้งค่าจากผู้ส่งรายใดก็ได้ในข้อมูลคำขอโหลด (Android, iOS และเว็บ) หรือภายในตัวรับผ่านตัวดักจับข้อความ
ดูตัวอย่างข้อมูลโค้ดด้านล่างหรือคู่มือการโหลดสื่อโดยใช้ contentId, contentUrl และเอนทิตี เพื่อดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีเตรียมเนื้อหาใน 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 Widevine จาก DASH IF IOP ใช้สตริงเดียวกันใน MPD กับสตรีมที่เข้ารหัส ไวด์ไวน์ |
URI |
"data:text/plain;base64, <base64 encoded PSSH box>" |
URI ของสตรีมที่มีประเภทข้อมูลและช่อง PSSH |
METHOD |
SAMPLE-AES-CTR |
ระบุวิธีการเข้ารหัสที่ใช้เมื่อเข้ารหัสเนื้อหา SAMPLE-AES ส่งสัญญาณว่าเนื้อหาได้รับการเข้ารหัสโดยใช้ "cbcs" ตัวอย่าง-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 ได้ แต่ปัจจุบัน Web Receiver Player อาศัยเพียง#EXT-X-ENDLIST
เพื่อตัดสินการถ่ายทอดสดกับ VOD เท่านั้น
สตรีมมิงอย่างราบรื่น
ข้อมูลจำเพาะของ Smooth Streaming อย่างเป็นทางการของ Microsoft
การสตรีมที่ราบรื่นมีโปรโตคอลสตรีมมิงแบบปรับอัตโนมัติและข้อกำหนด XML ผ่าน HTTP (คล้ายกับ DASH) Smooth Streaming แนะนำให้ใช้แพ็กเกจ MPEG-4 สำหรับสื่อเป็นกลุ่มเท่านั้น ซึ่งแตกต่างจาก DASH
ตารางต่อไปนี้เป็นตารางของแท็กและแอตทริบิวต์ที่ใช้กันมากที่สุดใน Smooth Streaming ซึ่ง Web Receiver Player รองรับในปัจจุบัน มีคำอธิบายแนวคิดหลายอย่างอยู่แล้วในส่วน DASH ข้างต้น
แท็ก/แอตทริบิวต์ | การใช้งาน |
---|---|
<SmoothStreamingMedia> | แท็กหลักสำหรับไฟล์ Manifest มีแอตทริบิวต์ต่อไปนี้
|
<StreamIndex> | สตรีม 1 ชุด ซึ่งคล้ายกับ AdaptationSet ของ DASH ประเภทมักจะเป็น "ข้อความ" "วิดีโอ" หรือ "เสียง" แอตทริบิวต์ URL มักมี URL ส่วนย่อยที่เป็นเทมเพลต โดยใช้ข้อมูล เช่น อัตราบิตหรือเวลาเริ่มต้น |
<QualityLevel> | แท็ก QualityLevel แต่ละแท็กจะระบุบิตเรตและตัวแปลงรหัส FourCC โค้ด FourCC มักจะเป็น "H264", "AVC1", "AACL" ฯลฯ ส่วนวิดีโอจะระบุความละเอียดผ่าน MaxWidth และ MaxHeight สำหรับเสียง จะระบุความถี่ (เช่น 44100) ผ่าน SamplingRate และจำนวนช่องสัญญาณ |
<c> | องค์ประกอบส่วนย่อยของสตรีม ประเภทมีดังนี้
|
<การป้องกัน> | แท็กที่มีแอตทริบิวต์ SystemID ที่ไม่บังคับ ซึ่งแสดงรหัสของระบบ DRM ที่จะใช้ภายใต้แท็ก <SmoothStreamingMedia> |
<ProtectionHeader> | ในส่วน <Protection> อาจมีแอตทริบิวต์ของ SystemID และข้อมูลที่กำหนดเอง ซึ่งโดยปกติแล้วจะเข้ารหัส Base64 ส่วน Widevine จะมีรหัสคีย์, ความยาวของคีย์, รหัสอัลกอริทึม เช่น AESCTR, LA_URL (URL การซื้อใบอนุญาต), LUI_URL (URL อินเทอร์เฟซผู้ใช้ของใบอนุญาต) และ DS_ID (รหัสบริการโดเมน) |
การปกป้องเนื้อหา
โปรดใช้การแมปด้านล่างเพื่อเข้ารหัสรหัสระบบป้องกันอย่างถูกต้อง
- WIDEVINE: "EDEF8BA9-79D6-4ACE-A3C8-27DCD51D21ED",
- CLEARKEY: '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 สำหรับสตรีมอย่างลื่นไหลแบบสดที่มีเนื้อหายาว 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" ในส่วน 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
จะตรวจสอบความสามารถด้านวิดีโอและเสียงของอุปกรณ์ Web Receiver และการแสดงผลโดยการตรวจสอบความถูกต้องของพารามิเตอร์สื่อที่ส่งผ่าน โดยแสดงผลบูลีน พารามิเตอร์ทั้งหมดยกเว้นพารามิเตอร์แรกเป็นตัวเลือกที่ไม่บังคับ ยิ่งคุณใส่พารามิเตอร์มากเท่าไหร่ การตรวจสอบก็ยิ่งแม่นยำมากขึ้นเท่านั้น
ลายเซ็นคือ canDisplayType(<em>mimeType</em>,<em>codecs</em>,<em>width</em>,<em>height</em>,<em>framerate</em>)
ตัวอย่างเช่น
ตรวจสอบว่าอุปกรณ์และจอแสดงผล Web Receiver รองรับวิดีโอ/mp4 mimetype ที่มีตัวแปลงรหัส ขนาด และอัตราเฟรมเฉพาะนี้หรือไม่
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)
ตรวจสอบว่าอุปกรณ์เว็บรีซีฟเวอร์และจอแสดงผลรองรับ 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
เนื้อหาสื่อบางอย่างต้องใช้การจัดการสิทธิ์ด้านดิจิทัล (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 ของแทร็กหลัก ตั้งค่าบัฟเฟอร์และตัวแปลงรหัสใหม่แล้ว:
- เมื่อวิดีโอเริ่มเล่น
- ที่ทุกช่วงพักโฆษณา และ
- ทุกครั้งที่เนื้อหาหลักกลับมาเล่นต่อ
เนื่องจากบัฟเฟอร์ใช้ตัวแปลงรหัสตัวเดียวและตัวแปลงรหัสถูกเลือกโดยอิงตามแทร็กหลัก จึงมีสถานการณ์ที่อาจมีการกรองแทร็กรองออกและไม่ได้ยินเสียง ปัญหานี้อาจเกิดขึ้นเมื่อแทร็กหลักของโปรแกรมสื่อ อยู่ในเสียงเซอร์ราวด์ แต่แทร็กเสียงที่ 2 ใช้เสียงสเตอริโอ เนื่องจากแทร็กรองมักถูกใช้เพื่อนำเสนอเนื้อหาในภาษาอื่น การจัดหาสื่อที่มีแทร็กจำนวนมากจึงอาจมีผลกระทบอย่างมาก เช่น ผู้ชมจำนวนมากไม่ได้ยินเนื้อหาในภาษาท้องถิ่นของตน
สถานการณ์ต่อไปนี้แสดงให้เห็นความสำคัญของการจัดโปรแกรมโดยที่แทร็กหลักและแทร็กรองมีจำนวนช่องเท่ากัน
สถานการณ์ 1 - สตรีมสื่อขาดความเท่าเทียมของช่องทางในแทร็กหลักและแทร็กรอง
- อังกฤษ - AC-3 เวอร์ชัน 5.1 (หลัก)
- ภาษาสวีเดน - AAC 2-channel
- ฝรั่งเศส - AAC 2 ช่อง
- เยอรมัน - AAC 2 ช่อง
ในสถานการณ์นี้ หากตั้งค่าภาษาของผู้เล่นเป็นภาษาอื่นที่ไม่ใช่ภาษาอังกฤษ ผู้ใช้จะไม่ได้ยินแทร็กที่คาดว่าจะได้ยิน เนื่องจากแทร็ก 2 ช่องทั้งหมดจะถูกกรองออกระหว่างการเล่น แทร็กเดียวที่คุณเล่นได้คือ AC-3 5.1-channel หลัก และเฉพาะเมื่อตั้งค่าภาษาเป็นภาษาอังกฤษ
สถานการณ์ 2 - สตรีมสื่อที่มีความเท่าเทียมกันของช่องทางในแทร็กหลักและแทร็กรอง
- อังกฤษ - AC-3 เวอร์ชัน 5.1 (หลัก)
- สวีเดน - AC-3 5.1 Channel
- ฝรั่งเศส - 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 จะตรวจสอบว่าสามารถรองรับตัวแปลงรหัสเสียงเซอร์ราวด์ (AC-3
หรือ EC-3
) ได้ไหม และกรองแทร็กสื่อที่ไม่สอดคล้องกับจำนวนช่องสัญญาณที่ต้องการออกโดยอัตโนมัติ