เครื่องมือจัดการไฟล์ Manifest สำหรับสตรีมแบบสด

Pod Serve API ช่วยให้เข้าถึงกลุ่มโฆษณาที่เข้ารหัสและมีการปรับสภาพ ซึ่งจัดเตรียมให้สามารถต่อเข้าในเพลย์ลิสต์สื่อ HLS หรือ MPEG-DASH ที่ผู้ใช้เห็นโดยตรงได้ สำหรับ MPEG-DASH Pod Serve API ยังมีเทมเพลตไฟล์ Manifest เพื่อให้ข้อมูลและบริบทเพิ่มเติมสำหรับกลุ่มโฆษณาเหล่านี้

คู่มือนี้เน้นการใช้เซิร์ฟเวอร์การจัดการไฟล์ Manifest ที่แสดงในพ็อดแบบพื้นฐานสำหรับสตรีมแบบสด

สิ่งที่ต้องทำก่อน: กำหนดค่าเหตุการณ์สตรีมแบบสดใน Google Ad Manager

ก่อนที่จะส่งคำขอจาก API การแสดงพ็อด คุณต้องสร้างเหตุการณ์สตรีมแบบสดของ Ad Manager สำหรับแต่ละสตรีมที่คุณประมวลผล คุณสร้างกิจกรรมสตรีมแบบสดได้โดยใช้ LiveStreamEventService API หรืออินเทอร์เฟซเว็บของ Google Ad Manager

หากต้องการใช้เหตุการณ์สตรีมแบบสดกับ API การแสดงพ็อด คุณจะต้องป้อนข้อมูลแอตทริบิวต์หลายรายการของกิจกรรม ดังนี้

  • customAssetKey - ตัวระบุที่กำหนดเองที่ใช้สำหรับเหตุการณ์นี้ ต้องไม่ซ้ำกันในเหตุการณ์ทั้งหมดสำหรับเครือข่าย
  • adTags - URL ของแท็กโฆษณาหลักที่สร้างโดยเวิร์กโฟลว์การดูแลการแสดงโฆษณาของ Ad Manager
  • dynamicAdInsertionType - ต้องตั้งค่าเป็น POD_SERVING_REDIRECT
  • streamingFormat - ตั้งค่าเป็น HLS หรือ DASH ตามนั้น
  • segmentUrlAuthenticationKeyIds - คีย์ HMAC อย่างน้อย 1 รายการใช้ในการลงนามในคำขอกลุ่มโฆษณา
  • daiEncodingProfileIds - รายการรหัส DAIEncodingProfile ที่เปิดใช้สำหรับเหตุการณ์นี้
  • startDateTime - วันที่และเวลาเริ่มต้นของกิจกรรม
  • endDateTime - วันที่และเวลาสิ้นสุดที่กำหนดไว้ของกิจกรรมนี้ ต้องระบุแอตทริบิวต์นี้หากบูลีน unlimitedEndDateTimeis false and ignored ifunlimitedEndDateTimeis true.unlimitedEndDateTime` ดูด้านบน

รับคำขอไฟล์ Manifest ของสตรีม

เครื่องมือการจัดการไฟล์ Manifest ต้องระบุปลายทาง API เพื่อรับฟังคำขอไฟล์ Manifest จากแอปไคลเอ็นต์ของโปรแกรมเล่นวิดีโอ อย่างน้อยที่สุดปลายทางนี้ต้องรวบรวมรหัสสตรีมจากแอปโปรแกรมเล่นของไคลเอ็นต์ และต้องส่งคืนไฟล์ Manifest สตรีมที่ต่อกัน รหัสสตรีมจะใช้เพื่อระบุเซสชันสตรีมมิงใน Ad Manager

คุณยังต้องรวบรวมข้อมูลอื่นๆ เพื่อระบุสตรีมเนื้อหาที่เหมาะสม เช่น รหัสเนื้อหา

ตัวอย่างปลายทางของคำขอไฟล์ Manifest ที่เป็นไปได้

GET /api/video/{asset_key}/manifest.{format}
Host: {your_domain}
พารามิเตอร์เส้นทาง
asset_key รหัสสมมติที่เกี่ยวข้องกับสตรีมแบบสดที่ขอในระบบ
format พารามิเตอร์สมมติที่เกี่ยวข้องกับรูปแบบสตรีม ข้อใดข้อหนึ่งต่อไปนี้
mpd สำหรับสตรีม MPEG-DASH
m3u8 สำหรับสตรีม HLS
พารามิเตอร์การค้นหา
stream_id รหัสสตรีม Ad Manager จากแอปโปรแกรมเล่นวิดีโอของไคลเอ็นต์

ดึงข้อมูลสตรีมเนื้อหา

ใช้ Content ID ที่รวบรวมจากคำขอไฟล์ Manifest เพื่อเลือกสตรีมเนื้อหาที่จะต่อเข้ากับโฆษณา

ต่อกลุ่มโฆษณาลงในสตรีมเนื้อหา

การต่อ URL ของกลุ่มโฆษณาจะแตกต่างกันไปตามรูปแบบสตรีมของคุณ

สตรีม HLS

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

หมายเหตุ: เพื่อความเรียบง่าย คู่มือนี้จะถือว่ามีการเข้ารหัสสื่อ HLS ของคุณในรูปแบบที่นำภาพและเสียงมาไว้ในไฟล์กลุ่มเดียวกัน

เพลย์ลิสต์เวอร์ชันแปรผันหลายตัวแปรของพร็อกซี

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

ขั้นตอนที่เหลือสำหรับการต่อ HLS จะถือว่าอยู่ระหว่างการประมวลผลไฟล์ Manifest ของตัวแปรรายการเดียว

ตัวอย่างปลายทางคำขอตัวแปรที่เป็นไปได้
GET /api/video/{asset_key}/variant/{variant_id}.m3u8
Host: {your_domain}
พารามิเตอร์เส้นทาง
asset_key รหัสสมมติที่เกี่ยวข้องกับสตรีมแบบสดที่ขอในระบบ
variant พารามิเตอร์สมมติที่มีตัวระบุสำหรับผลิตภัณฑ์ย่อยที่เจาะจงซึ่งกำลังประมวลผล
พารามิเตอร์การค้นหา
stream_id รหัสสตรีม Ad Manager จากแอปโปรแกรมเล่นวิดีโอของไคลเอ็นต์ที่ใช้ที่นี่เพื่อระบุเซสชันของผู้ใช้ด้วยโปรแกรมจัดการไฟล์ Manifest
ตัวอย่างไฟล์ Manifest หลายตัวแปรที่ไม่ได้ประมวลผล
#EXTM3U
#EXT-X-STREAM-INF:BANDWIDTH=5000000,RESOLUTION=1920x1080,CODECS="avc1.4d000c,mp4a.40.5"
https://cdn.{...}/1080p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=2500000,RESOLUTION=1280x720,CODECS="avc1.4d000c,mp4a.40.5"
https://cdn.{...}/720p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=1000000,RESOLUTION=640x360,CODECS="avc1.4d000d,mp4a.40.5"
https://cdn.{...}/360p.m3u8
ตัวอย่างไฟล์ Manifest หลายตัวแปรที่ใช้พร็อกซี
#EXTM3U
#EXT-X-STREAM-INF:BANDWIDTH=5000000,RESOLUTION=1920x1080,CODECS="avc1.4d000c,mp4a.40.5"
https://{manifest_manipulator}/api/video/tears_of_steel/variant/1080p.m3u8?stream_id=6e69425c-0ac5-43ef-b070-c5143ba68541:CHS
#EXT-X-STREAM-INF:BANDWIDTH=2500000,RESOLUTION=1280x720,CODECS="avc1.4d000c,mp4a.40.5"
https://{manifest_manipulator}/api/video/tears_of_steel/variant/720p.m3u8?stream_id=6e69425c-0ac5-43ef-b070-c5143ba68541:CHS
#EXT-X-STREAM-INF:BANDWIDTH=1000000,RESOLUTION=640x360,CODECS="avc1.4d000d,mp4a.40.5"
https://{manifest_manipulator}/api/video/tears_of_steel/variant/360p.m3u8?stream_id=6e69425c-0ac5-43ef-b070-c5143ba68541:CHS

ระบุส่วนของช่วงพักโฆษณาและแทรกความไม่ต่อเนื่อง

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

ช่วงพักโฆษณาอาจแสดงออกจากกลุ่มเนื้อหาในลักษณะที่แตกต่างกัน โดยขึ้นอยู่กับโปรแกรมเปลี่ยนไฟล์ วิธีหนึ่งที่พบบ่อยในการกําหนดช่วงพักโฆษณาคือใส่แท็ก #EXT-X-CUE-OUT ไว้หน้ากลุ่มโฆษณา และตามด้วยแท็ก #EXT-X-CUE-IN

หากต้องการแยกช่วงพักโฆษณาที่โฮสต์โดย Google ออกจากกลุ่มเนื้อหา คุณต้องแทรกแท็ก #EXT-X-DISCONTINUITY ที่จุดเริ่มต้นและจุดสิ้นสุดของช่วงพักโฆษณาแต่ละช่วง หากแท็กความต่อเนื่องเหล่านี้ไม่ปรากฏในไฟล์ Manifest สุดท้าย การเล่นจะล้มเหลว

URI ของกลุ่มโฆษณาที่แทรกไว้ไม่ได้รับการเข้ารหัส หากเนื้อหามีการเข้ารหัส คุณจะต้องนำการเข้ารหัสออกด้วยการระบุ #EXT-X-KEY:METHOD=NONE ก่อนส่วนแรกของช่วงพักโฆษณาแต่ละช่วง แล้วเพิ่มกลับเข้าไปใหม่หลังจากช่วงพักโฆษณา

ตัวอย่างไฟล์ Manifest (ต้นฉบับ)
#EXTM3U
#EXT-X-VERSION:6
#EXT-X-TARGETDURATION:6
#EXT-X-MEDIA-SEQUENCE:0

#EXTINF:5.005,
contentorigin.com/1.ts
#EXTINF:5.005,
contentorigin.com/2.ts
#EXT-X-CUE-OUT:15.000
#EXTINF:5.005,
contentorigin.com/3.ts
#EXTINF:5.005,
contentorigin.com/4.ts
#EXTINF:5.005,
contentorigin.com/5.ts
#EXTINF:5.000,d
contentorigin.com/6.ts
#EXT-X-CUE-IN
#EXTINF:5.005,
contentorigin.com/7.mp4
#EXTINF:5.005,
contentorigin.com/8.mp4
ไฟล์ Manifest ที่แทรกความไม่ต่อเนื่อง
#EXTM3U
#EXT-X-VERSION:6
#EXT-X-TARGETDURATION:6
#EXT-X-MEDIA-SEQUENCE:0

#EXTINF:5.005,
contentorigin.com/1.ts
#EXTINF:5.005,
contentorigin.com/2.ts
#EXTINF:5.005,
#EXT-X-DISCONTINUITY
{... New segments will go here ...}
#EXT-X-DISCONTINUITY
#EXTINF:5.005,
contentorigin.com/7.mp4
#EXTINF:5.005,
contentorigin.com/8.mp4

ประมวลผลกลุ่มพ็อดโฆษณา

สำหรับแต่ละกลุ่มภายในพ็อดโฆษณา คุณต้องติดตามค่าเพิ่มเติม 2-3 ค่าดังนี้

  • segment_number: ดัชนีกลุ่มภายในพ็อดโฆษณา เริ่มต้นด้วย 0 หรือ "init" สำหรับกลุ่มการเริ่มต้น mp4
  • segment_duration: ระยะเวลาของกลุ่มปัจจุบันในหน่วยมิลลิวินาที ค่านี้ควรเหมือนกันสำหรับทุกกลุ่ม ยกเว้นรายการสุดท้ายในพ็อด
  • segment_offset: ออฟเซ็ตกลุ่มที่คำนวณโดยการเพิ่มระยะเวลาของกลุ่มก่อนหน้าลงในออฟเซ็ตกลุ่มในหน่วยมิลลิวินาที
  • last: ค่าบูลีนที่ระบุกลุ่มสุดท้ายในพ็อดโฆษณา ค่าเริ่มต้นคือ "เท็จ"

สร้าง URL ของกลุ่มโฆษณา

แทนที่แต่ละส่วนภายในช่วงพักโฆษณาด้วย URL ตามรูปแบบ ดังนี้

/linear/pods/v1/seg/network/{network_code}/custom_asset/{custom_asset_key}/pod/{pod_id}/profile/{profile_name}/{segment_number}.(ts|mp4|vtt|aac|ac3|eac3)
พารามิเตอร์เส้นทาง
network_code รหัสเครือข่าย Ad Manager 360 สำหรับเครือข่ายนี้
custom_asset_key คีย์เนื้อหาสตรีมแบบสดที่กำหนดเองที่ระบุใน LiveStreamEventService API หรือในหน้าสตรีมแบบสดในอินเทอร์เฟซเว็บของ Ad Manager 360
pod_id ตัวระบุของช่วงพักโฆษณา ควรเป็นจำนวนเต็มที่เริ่มต้นที่ 1 และเพิ่มขึ้น 1 ตัวสำหรับช่วงพักโฆษณาแต่ละครั้ง

ค่านี้ต้องเหมือนกันสำหรับผู้ใช้ทุกคนที่ดูช่วงพักโฆษณาเดียวกันในเหตุการณ์ปัจจุบัน

profile_name ตัวระบุของโปรไฟล์ที่ต้องการ
segment_number ดัชนีของกลุ่มนี้ภายในพ็อดโฆษณาปัจจุบัน ซึ่งจะเริ่มต้นที่ 0
เมื่อใช้คอนเทนเนอร์ MP4 คุณจะขอกลุ่มการเริ่มต้นได้โดยการตั้งค่าsegment_number เป็น "init"
พารามิเตอร์การค้นหา
stream_id จำเป็น พารามิเตอร์ stream_id ของผู้ใช้แสดงผลจากคำขอ Stream Create
sd จำเป็น segment_duration
so ไม่บังคับ segment_offset

หากไม่มี so ระบบจะถือว่ากลุ่มก่อนหน้าทั้งหมดมีระยะเวลาเท่ากัน และการชดเชยกลุ่มจะคำนวณจาก segment_number และ sd

pd ต้องระบุ ยกเว้นเหตุการณ์ที่เปิดใช้ช่วงพักโฆษณาที่ไม่มีระยะเวลา ระยะเวลา (เป็นมิลลิวินาที) ของช่วงพักโฆษณา หรือที่เรียกว่า ad_pod_duration
auth-token จำเป็น โทเค็น HMAC ที่เข้ารหัสและเข้ารหัสสำหรับพ็อดโฆษณานี้
last ไม่บังคับ บูลีนที่ระบุกลุ่มสุดท้ายในช่วงพักโฆษณา ค่าเริ่มต้นคือ "เท็จ"

ค่าพารามิเตอร์การค้นหาต้องเข้ารหัสอย่างถูกต้องเพื่อให้ URL ปลอดภัย ซึ่งสำคัญอย่างยิ่งสำหรับช่อง auth-token เนื่องจากอาจมีอักขระ /, + และ = ตัว

ตัวอย่างไฟล์ Manifest (หลังจากการแทนที่กลุ่ม)
#EXTM3U
#EXT-X-VERSION:6
#EXT-X-TARGETDURATION:6
#EXT-X-MEDIA-SEQUENCE:0

#EXTINF:5.005,
contentorigin.com/1.ts
#EXTINF:5.005,
contentorigin.com/2.ts
#EXT-X-DISCONTINUITY
#EXTINF:5.005,
https://dai.google.com/linear/pods/v1/seg/network/6062/custom_asset/iYdOkYZdQ1KFULXSN0Gi7g/pod/1/profile/devrel4628000/0.ts?sd=5005&so=0&pd=18015&auth-token=custom_asset_key%3DiYdOkYZdQ1KFULXSN0Gi7g~cust_params%3D~exp%3D1489680000~network_code%3D6062~pd%3D180000~pod_id%3D5~hmac%3D44bf78223c240cbc5bae3cdfd794bfc6971b6583cd296f44ef3a46944605cf9a&stream_id=fe6c9136-09a4-4ff6-862e-daee1dea0e1b:MRN2
#EXTINF:5.005,
https://dai.google.com/linear/pods/v1/seg/network/6062/custom_asset/iYdOkYZdQ1KFULXSN0Gi7g/pod/1/profile/devrel4628000/1.ts?sd=5005&so=5005&pd=18015&auth-token=custom_asset_key%3DiYdOkYZdQ1KFULXSN0Gi7g~cust_params%3D~exp%3D1489680000~network_code%3D6062~pd%3D180000~pod_id%3D5~hmac%3D44bf78223c240cbc5bae3cdfd794bfc6971b6583cd296f44ef3a46944605cf9a&stream_id=fe6c9136-09a4-4ff6-862e-daee1dea0e1b:MRN2
#EXTINF:5.005,
https://dai.google.com/linear/pods/v1/seg/network/6062/custom_asset/iYdOkYZdQ1KFULXSN0Gi7g/pod/1/profile/devrel4628000/2.ts?sd=5005&so=10010&pd=18015&auth-token=custom_asset_key%3DiYdOkYZdQ1KFULXSN0Gi7g~cust_params%3D~exp%3D1489680000~network_code%3D6062~pd%3D180000~pod_id%3D5~hmac%3D44bf78223c240cbc5bae3cdfd794bfc6971b6583cd296f44ef3a46944605cf9a&stream_id=fe6c9136-09a4-4ff6-862e-daee1dea0e1b:MRN2
#EXTINF:3.000,
https://dai.google.com/linear/pods/v1/seg/network/6062/custom_asset/iYdOkYZdQ1KFULXSN0Gi7g/pod/1/profile/devrel4628000/3.ts?sd=3000&so=15015&pd=18015&auth-token=custom_asset_key%3DiYdOkYZdQ1KFULXSN0Gi7g~cust_params%3D~exp%3D1489680000~network_code%3D6062~pd%3D180000~pod_id%3D5~hmac%3D44bf78223c240cbc5bae3cdfd794bfc6971b6583cd296f44ef3a46944605cf9a&stream_id=fe6c9136-09a4-4ff6-862e-daee1dea0e1b:MRN2&last=true
#EXT-X-DISCONTINUITY
#EXTINF:5.005,
contentorigin.com/7.mp4
#EXTINF:5.005,
contentorigin.com/8.mp4

ยินดีด้วย คุณกำลังจะแสดงสตรีมแบบสดด้วยกลุ่มโฆษณาที่มาจาก DAI Pod Serve API

สตรีม DASH

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

ขอเทมเพลตระยะเวลา

ขอเทมเพลตช่วงเวลาจาก Google Ad Manager เทมเพลตนี้จะกลายเป็นช่วงพักโฆษณา เมื่อมีการเติมค่ามาโครที่อยู่ในนั้น

คุณควรขอเทมเพลตนี้เพียง 1 ครั้งต่อเซสชันของสตรีมเท่านั้น และแคชเทมเพลตไว้ใช้ซ้ำในช่วงพักโฆษณาแต่ละครั้ง

อุปกรณ์ปลายทางคำขอเทมเพลตระยะเวลา
GET /linear/pods/v1/dash/network/{network_code}/custom_asset/{custom_asset}/pods.json
Host: dai.google.com
Content-Type: application/json
พารามิเตอร์เส้นทาง
network_code รหัสเครือข่าย Ad Manager 360 ของผู้เผยแพร่โฆษณา
custom_asset คีย์เนื้อหาที่กำหนดเองของเหตุการณ์สตรีมแบบสดใน Google Ad Manager
พารามิเตอร์การค้นหา
stream_id รหัสสตรีม Ad Manager จากโปรแกรมเล่นวิดีโอของไคลเอ็นต์
JSON ของการตอบกลับ
dash_period_template สตริง XML ของเทมเพลตระยะเวลา
segment_duration_ms ระยะเวลาของกลุ่มสื่อโฆษณาแต่ละกลุ่มในเทมเพลตช่วงเวลาขีดกลางเป็นมิลลิวินาที
ตัวอย่างคำขอ (cURL)
curl https://dai.google.com/linear/pods/v1/dash/network/21775744923/custom_asset/tears_of_steel/pods.json?stream-id=cc59197a-44c0-4be2-a8cc-9a6fdb80158f:DLS
ตัวอย่างการตอบกลับ
{"dash_period_template":"<Period id="adpod-$$pod-id$$" $$period-start$$ $$period-duration$$> <BaseURL>https://dai.google.com/linear/pods/v1/seg/event/{event_code}/pods/$$pod-id$$/profile/</BaseURL>
 <SegmentTemplate initialization="$RepresentationID$/init.mp4?stream_id={a-stream-id}&amp;sd=5000&pd=$$pod-duration$$&amp;cust_params=$$cust_params$$&amp;auth_token=$$token$$" media="$RepresentationID$/$Number$.mp4?stream_id={a-stream-id}&amp;sd=5000&pd=$$pod-duration$$&amp;cust_params=$$cust_params$$&amp;scte35=$$scte35$$&amp;auth_token=$$token$$" startNumber="1" presentationTimeOffset="0">
  <SegmentTimeline>
    <S t="0" d="5" r="$$number-of-repeated-segments$$"/>
  </SegmentTimeline>
  </SegmentTemplate>
  <AdaptationSet id="0" width="1280" height="720" frameRate="30" contentType="video" subsegmentAlignment="true" startWithSAP="1">
    <InbandEventStream schemeIdUri="https://developer.apple.com/streaming/emsg-id3"/>
    <Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"/>
    <Representation mimeType="video/mp4" codecs="avc1.640029" id="a943ff679a2f3e71d9181a21b7542122g" bandwidth="3200000"/>
    <Representation mimeType="video/mp4" codecs="avc1.640029" id="abbbd80q4w5ce2fs28308rd1f4g4bat0" bandwidth="1500000"/>
  </AdaptationSet>
  <AdaptationSet id="1" contentType="audio"> <Representation audioSamplingRate="48000" mimeType="audio/mp4" codecs="mp4a.40.2" id="a87ff679a2f3e71d9181a67b7542122c" bandwidth="95000"/>

    <Representation audioSamplingRate="48000" mimeType="audio/mp4" codecs="mp4a.40.2" id="eccbc87e4b5ce2fe28308fd9f2a7baf3" bandwidth="127000"/>
  </AdaptationSet>
</Period>",
"segment_duration_ms":5000}

ป้อนข้อมูลเทมเพลตระยะเวลา

เทมเพลตระยะเวลามีมาโครหลายรายการที่คุณต้องแทนที่สำหรับช่วงพักโฆษณาแต่ละครั้ง ต้องแทนที่มาโครทั้งหมด มาโครที่ไม่ได้ใช้งานควรถูกแทนที่ด้วยสตริงว่าง ("")

Macro คำอธิบาย ตัวอย่าง
$$pod-id$$ ดัชนีของพ็อดโฆษณาในช่วงเวลานี้ ค่านี้ต้องตรงกับพ็อดเดียวกันในเซสชันผู้ดูทั้งหมด 1
$$period-start$$ เวลาที่ช่วงเวลาเริ่มต้นใน MPD ปัจจุบัน แอตทริบิวต์ที่ไม่บังคับซึ่งควรแทนที่ด้วย start="###" โดย ### คือเวลานำเสนอที่ช่วงพักโฆษณาเริ่มต้น หากไม่ได้ระบุเวลาเริ่มต้นของระยะเวลา คุณควรแทนที่มาโครนี้ด้วยสตริงว่าง start="PT2H33M30S"
$$period-duration$$ ระยะเวลาของช่วงเวลาโฆษณาที่สมบูรณ์ แอตทริบิวต์ที่ไม่บังคับซึ่งควรแทนที่ด้วย duration="###" โดยที่ ### คือระยะเวลาของช่วงเวลาโฆษณาในรูปแบบระยะเวลา DASH มาตรฐาน หากไม่ได้ระบุระยะเวลาของช่วงเวลา คุณควรแทนที่มาโครนี้ด้วยสตริงที่ว่างเปล่า duration="PT15S"
$$pod-duration$$ ระยะเวลาที่คาดว่าจะได้รับของโฆษณาสำหรับพ็อดนี้ หน่วยเป็นมิลลิวินาที 15000
$$number-of-repeated-segments$$ ค่านี้จะคำนวณโดยการหารระยะเวลาโฆษณา (เป็นมิลลิวินาที) ด้วยค่าsegment_duration_ms และปัดเศษเป็นจำนวนเต็มที่ใกล้ที่สุด 3
$$cust_params$$ พารามิเตอร์การกำหนดเป้าหมายเองซึ่งจะใช้กับช่วงพักโฆษณาปัจจุบันโดยเฉพาะสามารถแทนที่มาโครนี้ได้ หากมี ค่าต้องจัดรูปแบบตามที่อธิบายไว้ในบทความในศูนย์ช่วยเหลือของ Ad Manager นี้ หากไม่จำเป็นต้องใช้พารามิเตอร์ที่กำหนดเอง คุณควรแทนที่มาโครนี้ด้วยสตริงที่ว่างเปล่า &cust_params=section%3Dblog%26anotherKey%3Dvalue1%2Cvalue2
$$scte35$$ มาโครนี้ต้องแทนที่ด้วยค่า scte35 เฉพาะสำหรับช่วงพักโฆษณานั้น หากมีการระบุ หากไม่จำเป็นต้องใช้ข้อมูล scte35 ควรแทนที่มาโครนี้ด้วยสตริงว่าง /DAqAAAAAAAA///wDwVAAAT2f0/+ecF1mQABC/8ACgAIQ1VFSQAAAAsuZVlR
$$token$$ โทเค็น HMAC ที่มีลายเซ็นและเข้ารหัส URL ต้องระบุโทเค็นนี้ custom_asset_key%3DiYdOkYZdQ1KFULXSN0Gi7g~exp%3D1489680000~network_code%3D6062~pd%3D180000~pod_id%3D5~hmac%3D6a8c44c72e4718ff63ad2284edf2a8b9e319600b430349d31195c99b505858c9
เทมเพลตระยะเวลา RAW ที่มีมาโคร
<Period id="adpod-$$pod-id$$" $$period-start$$ $$period-duration$$>
  <BaseURL>
    https://dai.google.com/linear/pods/v1/seg/event/{event_code}/pods/$$pod-id$$/profile/
  </BaseURL>
  <SegmentTemplate initialization="$RepresentationID$/init.mp4?stream_id=cc59197a-44c0-4be2-a8cc-9a6fdb80158f:DLS&amp;sd=5000&pd=$$pod-duration$$&amp;cust_params=$$cust_params$$&amp;auth_token=$$token$$" media="$RepresentationID$/$Number$.mp4?stream_id=ç√&amp;sd=5000&pd=$$pod-duration$$&amp;cust_params=$$cust_params$$&amp;scte35=$$scte35$$&amp;auth_token=$$token$$" startNumber="1" presentationTimeOffset="0">  
    <SegmentTimeline>
      <S t="0" d="5" r="$$number-of-repeated-segments$$"/>
    </SegmentTimeline>
  </SegmentTemplate>
  <AdaptationSet id="0" width="1280" height="720" frameRate="30" contentType="video" subsegmentAlignment="true" startWithSAP="1">
    <InbandEventStream schemeIdUri="https://developer.apple.com/streaming/emsg-id3"/>
    <Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"/>
    <Representation mimeType="video/mp4" codecs="avc1.640029" id="a943ff679a2f3e71d9181a21b7542122g" bandwidth="3200000"/>
    <Representation mimeType="video/mp4" codecs="avc1.640029" id="abbbd80q4w5ce2fs28308rd1f4g4bat0" bandwidth="1500000"/>
  </AdaptationSet>
  <AdaptationSet id="1" contentType="audio"> <Representation audioSamplingRate="48000" mimeType="audio/mp4" codecs="mp4a.40.2" id="a87ff679a2f3e71d9181a67b7542122c" bandwidth="95000"/>
    <Representation audioSamplingRate="48000" mimeType="audio/mp4" codecs="mp4a.40.2" id="eccbc87e4b5ce2fe28308fd9f2a7baf3" bandwidth="127000"/>
  </AdaptationSet>
</Period>
ช่วงเวลาที่จำนวนโฆษณา
<Period id="pod-0" start="PT5H50M12S">
  <BaseURL>
    https://dai.google.com/linear/pods/v1/seg/event/M-nTcApTRTi6CEGIt4GYMw/pod/0/profile/
  </BaseURL>
  <SegmentTemplate startNumber="0" media="1080p/0.mp4?stream_id=cc59197a-44c0-4be2-a8cc-9a6fdb80158f:DLS&amp;sd=5000&amp;pd=30000&amp;cust_params=&amp;auth-token=&amp;scte35=" initialization="$RepresentationID$/init.mp4?stream_id=cc59197a-44c0-4be2-a8cc-9a6fdb80158f:DLS&amp;pd=30000&amp;cust_params=&amp;auth-token=&amp;scte35=">
    <SegmentTimeline>
      <S d="5" r="1"/>
    </SegmentTimeline>
  </SegmentTemplate>
  <AdaptationSet mimeType="video/mp4" scanType="progressive" contentType="video">
    <Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"/>
    <Representation width="768" height="432" frameRate="30" codecs="avc1.42c01e" id="fmp4-video-1200k" bandwidth="1300000">
      <InbandEventStream schemeIdUri="https://developer.apple.com/streaming/emsg-id3"/>
    </Representation>
  </AdaptationSet>
  <AdaptationSet mimeType="audio/mp4" scanType="progressive" contentType="audio">
    <Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"/>
      <Representation audioSamplingRate="48000" codecs="mp4a.40.2" id="fmp4-audio-128kbps" bandwidth="128000">
      <AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
    </Representation>
  </AdaptationSet>
</Period>

แทรกช่วงเวลาที่ป้อนลงในไฟล์ Manifest DASH

สุดท้าย แทนที่ระยะเวลาที่เหมาะสมในไฟล์ Manifest ดิบด้วยระยะเวลาของโฆษณาที่เพิ่งป้อนใหม่ และส่งไฟล์ Manifest ที่ต่อเข้าด้วยกันสุดท้ายไปยังไคลเอ็นต์วิดีโอที่ส่งคำขอเพื่อเล่น

ตัวอย่างไฟล์ Manifest ของเนื้อหาดิบ
<?xml version="1.0"?>
  <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" profiles="urn:mpeg:dash:profile:isoff-main:2011" type="static" mediaPresentationDuration="PT0H9M56.46S">
    <BaseURL>
      http://example.com/tears_of_steel/
    </BaseURL>
    <Period start="PT0S">
      <AdaptationSet bitstreamSwitching="true">

        <Representation id="0" codecs="avc1" mimeType="video/mp4" width="1920" height="1080" startWithSAP="1" bandwidth="500000">
          <SegmentBase>
            <Initialization sourceURL="segments/1080/1.m4s" range="0-862"/>
          </SegmentBase>
          <SegmentList duration="15">
            <SegmentURL media="segments/1080p/2.m4s" mediaRange="863-7113"/>
            <SegmentURL media="segments/1080p/3.m4s" mediaRange="7114-14104"/>
            <SegmentURL media="segments/1080p/4.m4s" mediaRange="14105-17990"/>
            ...
          </SegmentList>
        </Representation>

        <Representation id="1" codecs="avc1" mimeType="video/mp4" width="1280" height="720" startWithSAP="1" bandwidth="250000">
          <SegmentBase>
            <Initialization sourceURL="segments/720p/1.m4s" range="0-864"/>
          </SegmentBase>
          <SegmentList duration="15">
            <SegmentURL media="segments/720p/2.m4s" mediaRange="865-11523"/>
            <SegmentURL media="segments/720p/3.m4s" mediaRange="11524-25621"/>
            <SegmentURL media="segments/720p/4.m4s" mediaRange="25622-33693"/>
            ...
          </SegmentList>
        </Representation>

        <Representation id="1" codecs="avc1" mimeType="video/mp4" width="640" height="480" startWithSAP="1" bandwidth="100000">
          <SegmentBase>
            <Initialization sourceURL="segment/480p/1.m4s" range="0-865"/>
          </SegmentBase>
          <SegmentList duration="15">
            <SegmentURL media="segment/480p/2.m4s" mediaRange="866-26970"/>
            <SegmentURL media="segment/480p/3.m4s" mediaRange="26971-72543"/>
            <SegmentURL media="segment/480p/4.m4s" mediaRange="72544-95972"/>
            ...
          </SegmentList>
        </Representation>
        ...
      </AdaptationSet>
    </Period end>
  </MPD>
ตัวอย่างไฟล์ Manifest ที่เชื่อมเข้าด้วยกัน
<?xml version="1.0"?>
  <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" profiles="urn:mpeg:dash:profile:isoff-main:2011" type="static" mediaPresentationDuration="PT0H9M56.46S">
    <BaseURL>
      http://example.com/tears_of_steel/
    </BaseURL>
    
    <Period id="pod-0" start="PT5H50M12S">
  <BaseURL>
    https://dai.google.com/linear/pods/v1/seg/event/M-nTcApTRTi6CEGIt4GYMw/pod/0/profile/
  </BaseURL>
  <SegmentTemplate startNumber="0" media="1080p/0.mp4?stream_id=cc59197a-44c0-4be2-a8cc-9a6fdb80158f:DLS&amp;sd=5000&amp;pd=30000&amp;cust_params=&amp;auth-token=&amp;scte35=$$scte35$$" initialization="$RepresentationID$/init.mp4?stream_id=cc59197a-44c0-4be2-a8cc-9a6fdb80158f:DLS&amp;pd=30000&amp;cust_params=&amp;auth-token=&amp;scte35=$$scte35$$">
    <SegmentTimeline>
      <S d="5" r="1"/>
    </SegmentTimeline>
  </SegmentTemplate>
  <AdaptationSet mimeType="video/mp4" scanType="progressive" contentType="video">
    <Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"/>
    <Representation width="768" height="432" frameRate="30" codecs="avc1.42c01e" id="fmp4-video-1200k" bandwidth="1300000">
      <InbandEventStream schemeIdUri="https://developer.apple.com/streaming/emsg-id3"/>
    </Representation>
  </AdaptationSet>
  <AdaptationSet mimeType="audio/mp4" scanType="progressive" contentType="audio">
    <Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"/>
      <Representation audioSamplingRate="48000" codecs="mp4a.40.2" id="fmp4-audio-128kbps" bandwidth="128000">
      <AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
    </Representation>
  </AdaptationSet>
</Period>
    
</MPD>

ยินดีด้วย คุณกำลังจะแสดงสตรีมแบบสดของ DASH ด้วยกลุ่มโฆษณาจาก DAI Pod Serve API

แหล่งข้อมูลเพิ่มเติม