העברת תוכן ב-YouTube בשידור חי באמצעות DASH

במסמך הזה מפורטות הנחיות לשימוש בפורמט ההעברה Dynamic Adaptive Streaming over HTTP ‏ (DASH) כדי לשדר נתונים בשידור חי ב-YouTube ממקודד. המסמך הזה נועד לעזור לספקי מקודדים להוסיף תמיכה במשלוח DASH למוצרים שלהם.

הסבר על DASH

הרשימה הבאה כוללת כמה מהתכונות והמאפיינים העיקריים של DASH:

  • מבוסס על תקנים פתוחים.
  • מבוסס על HTTP. כתוצאה מכך, DASH מתאים לתשתית האינטרנט ויכול לעבור דרך חומות אש.
  • יש תמיכה בקצב העברת נתונים גבוה. ‫DASH תומך בכמה סשנים של HTTP בו-זמנית ובמסירת פלחים לא רציפה, ולכן הוא עמיד יותר מפרוטוקולים שמסתמכים על חיבור TCP יחיד.
  • מסירה מאובטחת באמצעות HTTPS.
  • העברה ללא אובדן נתונים דרך HTTP ו-HTTPS.
  • לא תלוי בקודק.
  • תומך ב-MP4 שמכיל H264 ו-AAC, וגם ב-WebM שמכיל VP8/VP9 ו-Vorbis/Opus.

מפרטים

דרישות

בקטעי המשנה הבאים מוסברות הדרישות לשימוש ב-DASH כדי להעביר שידורים חיים ל-YouTube.

תזמון

נקודת הקצה של YouTube DASH מתנהגת כמו שרת HTTP פסיבי, שמתעד קריאות לשיטת PUT שנשלחות על ידי מקודד.

  • נקודת הקצה של DASH תומכת בחיבורי TCP בו-זמניים. אפשר לעשות שימוש חוזר בחיבורים בהתאם ל-HTTP/1.1.
  • צריך להשתמש בשיטת ה-PUT כדי להעלות את קובץ ה-MPD ואת פלחי האתחול תוך 3 שניות מהעלאת פלח המדיה הראשון. (מומלץ לכלול את קטע ההפעלה ב-MPD).
  • כל פלח או MPD חייבים להשתמש בבקשת PUT נפרדת. אין תמיכה בהעלאה מרובת חלקים של כמה פלחים.
  • פעולות PUT עבור פלחים של מדיה עשויות לחפוף בזמן כדי לשפר את רוחב הפס של ההעלאה.
  • אפשר לספק פלחים בסדר לא רציף בתוך חלון זמן של כ-3 שניות.
  • צריך לעדכן את ה-MPD ואת קטעי האתחול כל 60 שניות לפחות עם availabilityStartTime ו-startNumber מעודכנים. (כפי שצוין למעלה, אפשר לכלול את פלח האתחול ב-MPD. במקרה כזה, בקשת PUT אחת יכולה לעדכן את שני הפלחים).

מבנה של כתובת אתר

המקודד צריך ליצור כתובות URL מסוג PUT על ידי הוספת מחרוזת לכתובת הבסיסית של נקודת הקצה ב-YouTube. צריך ליצור את נקודת הקצה להטמעת נתונים בפורמט DASH באמצעות YouTube Live Streaming API.

לאחר מכן, המקודד יכול לקבל את כתובת ה-URL הבסיסית של נקודת הקצה באופן פרוגרמטי באמצעות YouTube Live Streaming API. כתובת ה-URL הבסיסית מוצגת גם בממשק המשתמש של אירועים בשידור חי ב-YouTube, אם רוצים לספק את כתובת ה-URL למקודד באופן ידני.

המחרוזת שמצורפת לכתובת ה-URL הבסיסית יכולה להכיל את קבוצת התווים הבאה של ASCII:

  • אותיות קטנות: a-z
  • אותיות רישיות: A-Z
  • ספרות: 0-9
  • תווים מיוחדים: _ (קו תחתון), - (מקף), . (נקודה)

כתובות URL של MPD

בנוסף לדרישה שלמעלה, כתובת ה-URL של ה-MPD צריכה להסתיים ב-.mpd, כדי ששרת YouTube יוכל לזהות בקלות את ה-MPD. כתובות URL של פלחים אחרים לא יכולות להסתיים ב-.mpd.

כתובות URL של אתחול ושל פלחי מדיה

כתובת ה-URL של פלח ההפעלה וכל כתובות ה-URL של פלחי המדיה צריכות להסתיים ב-.mp4 אם הנתונים נמצאים במאגר ISO BMFF, או ב-.webm אם הנתונים נמצאים במאגר WebM.

תוכן MPD

קובץ ה-MPD צריך להיות מלא ותואם לתקן DASH. הוא חייב להכיל בדיוק אחד מכל אחד מהרכיבים הבאים. הרשימה הזו מזהה רכיבים שנדרשים באופן ספציפי על ידי YouTube, ויכול להיות שבתקן DASH יזוהו רכיבים נדרשים נוספים. הרכיבים מיוצגים באמצעות תחביר XPath, והם עומדים בתקן DASH.

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

חשוב לשים לב לדרישות הבאות לגבי ערכי הרכיבים:

  • הערך של המאפיין minimumUpdatePeriod של האלמנט <MPD> חייב להיות שווה ל-60 שניות (PT60S) או פחות.
  • במאפיין media של הרכיב <SegmentTemplate> צריך לציין שכתובות ה-URL של פלח המדיה נוצרות באמצעות $Number$. (המאפיין startNumber מזהה את המספר שיוקצה לקטע המדיה הראשון).

אורך פלח האתחול

אורך קטע האתחול לא יכול להיות יותר מ-100KB. (בדרך כלל, פלח ההפעלה קטן הרבה יותר). אם פלח ההפעלה כלול ב-MPD, כתובת ה-URL‏ data: שמכילה את הפלח לא יכולה להיות ארוכה מ-100kb.

פלט המקודד

פלח האתחול ופלח המדיה חייבים להיות זרם קבצים מרובה ערוצים בפורמט ISO BMFF או WebM עם GOP (קבוצות תמונות) סגורות.

  • גודל ה-GOP צריך להיות בערך 2 שניות, והוא חייב להיות קטן מ-8 שניות.
  • השידור המרובב חייב להכיל גם טראקים של אודיו וגם טראקים של וידאו.

שיטות מומלצות נוספות

הצפנה

פלטפורמת YouTube תומכת בהצפנת סטרימינג באמצעות HTTPS. מומלץ מאוד להשתמש בתכונה הזו.

פלחים של אתחול בקובץ MPD

אפשר לייצג את קטע האתחול ישירות ב-MPD באמצעות data: כתובת URL, בהתאם ל-RFC 2397. כך קל יותר להגדיר את הסטרימינג וקטן הסיכוי שפלח האתחול לא יתאים לשאר הסטרימינג.

ה-XPath של הרכיב הזה הוא:

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

משכי הזמן של פלחים מטורגטים

כדי להשיג ביצועים טובים של הטמעה ואיזון טוב בין קצב העברת הנתונים לבין זמן האחזור, משך קטעי המדיה צריך להיות בין שנייה אחת ל-5 שניות. מומלץ מאוד לציין את משך הזמן של הפלחים האלה בקובץ ה-MPD באמצעות שני הרכיבים האלה:

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

המשך המחושב מהמאפיינים האלה צריך להיות בטווח של פקטור 2 מכל משכי הפלחים בפועל, אחרת יכול להיות שתהיה פגיעה בביצועים של הסטרימינג.

שימו לב: משך היעד של ההטמעה לא שווה למשך המקטע של השידור החי שנוצר ב-YouTube. מערכת YouTube מבצעת טרנסקוד וחלוקה מחדש של הקלט, ומשך היעד של הפלט תלוי בכך שהסטרימינג מותאם לאיכות הסטרימינג או לזמן האחזור.

ניסיונות חוזרים והשהיה מעריכית לפני ניסיון חוזר (exponential backoff)

מומלץ להגדיר לכל בקשות ה-HTTP PUT זמן קצוב לתפוגה, שיהיה ארוך ב-500 אלפיות השנייה ממשך הפלח.

בקשת PUT של קטע מדיה שנכשלת, בין אם בגלל פסק זמן או שגיאות אחרות, מתאימה לפער בזרם הווידאו. לכן, צריך לנסות שוב לשלוח בקשות כאלה באמצעות השהיה מעריכית בינארית לפני ניסיון חוזר עם רכיב אקראי:

  1. אחרי כשל, צריך להמתין פרק זמן אקראי בין [0 ... 100] אלפיות השנייה ולנסות שוב את הבקשה.
  2. אם הבקשה נכשלת שוב, צריך להמתין פרק זמן אקראי בין [0 ... 200] אלפיות השנייה ולנסות שוב את הבקשה.
  3. אם הבקשה נכשלת שוב, צריך להמתין פרק זמן אקראי בין [0 ... 400] אלפיות השנייה ולנסות שוב את הבקשה.
  4. וכו'

שימו לב שאם יש כשלים חוזרים, צריך לדווח על כך למפעיל המקודד, כי הם מצביעים על שידור שנכשל.

קודי תגובת HTTP

בקטעים הבאים מוסבר על קודי התגובה ש-YouTube מחזיר בתגובה לפלחים שנשלחים באמצעות DASH.

‫200 (OK)

תגובה מסוג HTTP 200 (OK) מציינת שהשרת של YouTube קיבל פעולה צפויה וטיפל בה בהצלחה.

202 (התקבל)

תגובת HTTP 202 (Accepted) לכל פעולת PUT או POST מציינת שהפעולה הייתה לא צפויה והתקבלה לעיבוד מאוחר יותר. עם זאת, יכול להיות שהפעולה שנדחתה תצליח או תיכשל, ולכן התשובה לא מבטיחה ש-YouTube יוכל לעבד את הפעולה בהצלחה.

התשובה הזו מופיעה הכי הרבה כשפלח מועבר לא ברצף. בדרך כלל, מערכת YouTube יכולה לעבד בצורה נכונה את הפלח שאושר אחרי קבלת הפלחים הקודמים, ולא צריך לשלוח מחדש את הפלח.

לדוגמה, YouTube יכול להחזיר תגובה עם קוד 202 בכל אחד מהמקרים הבאים:

  • פלח אתחול מתקבל לפני קובץ ה-MPD.
  • פלחים של מדיה מתקבלים לפני פלחים של MPD ופלחים של אתחול.
  • פלח מדיה מתקבל לפני פלח קודם, למשל פלח 3 מתקבל לפני פלח 2.

עם זאת, תגובה עם קוד 202 יכולה גם להצביע על כך שמזהה הפריט שגוי אם מערכת YouTube לא מצליחה לאמת את המזהה באופן מלא עם קבלת בקשת ה-POST או ה-PUT. לדוגמה, זה יכול לקרות כשמערכת YouTube מקבלת ומאשרת פלח אתחול לפני שהיא מקבלת את ה-MPD, אבל מתברר שפלח האתחול לא תקין. במקרה כזה, המערכת של YouTube מקבלת את קטע האתחול ומחזירה 202, ואז קובעת אם הקטע תקף עם קבלת ה-MPD. כדי להימנע מהתרחיש הזה, צריך לכלול את קטע האתחול בקובץ ה-MPD.

‫‎400 (Bad Request)

תגובה מסוג HTTP 400 (בקשה שגויה) מציינת שאחת מהבעיות הבאות התרחשה:

  • כתובת ה-URL לא תקינה.
  • הפוסט גדול מדי (מעל 10MB).
  • אי אפשר לנתח את ה-MPD.
  • פלח האתחול בקובץ ה-MPD פגום.

‫401 (אין הרשאה)

תגובה מסוג HTTP 401 (לא מורשה) מציינת שכתובת ה-URL הבסיסית של נקודת הקצה של YouTube DASH פגומה או שתוקף שלה פג.

‫405 (השיטה אסורה)

תגובה מסוג HTTP 405 (Method Not Allowed) מציינת שנשלחה בקשה שאינה POST או PUT.

409 (התנגשות)

תגובה מסוג HTTP 409 (Conflict) לכל פעולת PUT או POST מציינת ש-YouTube לא יכול לעבד את הבקשה. לדוגמה, התגובה הזו עשויה להתרחש אם השולח של הבקשה שלח מספר רב של פלחי מדיה, אבל עדיין אין ל-YouTube את קובץ ה-MPD, את פלח האתחול או את שניהם. בדוגמה הזו, המקודד יצטרך לשדר מחדש את קובץ ה-MPD ואת פלחי האתחול לפני שינסה שוב לשלוח את הבקשה שנכשלה.

‫500 (שגיאת שרת פנימית)

תגובה מסוג HTTP 500 (שגיאת שרת פנימית) מציינת שהשרת לא הצליח לעבד את הבקשה. במקרה של השגיאה הזו, מומלץ לנסות שוב את הבקשה עם השהיה מעריכית לפני ניסיון חוזר (exponential backoff).

דוגמאות

רצף כתובות URL

רצף כתובות ה-URL שבהמשך מציג סדרה של בקשות PUT שיישלחו כדי להעביר תוכן באמצעות DASH. הרצף מניח שכתובת ה-URL הבסיסית של נקודת הקצה של YouTube DASH היא:

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

הרצף מראה את קובץ ה-MPD ואת פלחי ההפעלה שנשלחים בנפרד. עם זאת, אפשר לייצג את פלח האתחול ישירות ב-MPD, ומומלץ לעשות זאת. בנוסף, צריך לעדכן את קובץ ה-MPD ואת מקטעי ההפעלה כל 60 שניות לפחות. לכן, בסופו של דבר, כתובות ה-URL של הפלחים האלה יופיעו שוב ברצף הזה, ואחריהן יופיעו כתובות URL של עוד פלחים של מדיה.

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

פלחים של WebM

קובץ MPD עם פלח אתחול מוטמע

בדוגמה הבאה של MPD מוטמע קטע אתחול בכתובת URL של נתונים לפי RFC 2397. מומלץ להטמיע את קטע האתחול בצורה הזו במקום לשלוח אותו בנפרד.

הדוגמה הזו תואמת להעלאה של WebM (VP8 או VP9, ‏ Opus) ל-YouTube. רוב כתובת ה-URL של הנתונים הושמטה כדי לשפר את הקריאוּת:

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

MPD

דוגמה נוספת ל-MPD שתואם להטמעה של WebM (VP8 או VP9,‏ Opus) ב-YouTube, בלי קטע אתחול מוטמע:

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

אתחול

בהמשך מוצג הפריסה של קטע אתחול לדוגמה בפורמט WebM. הוא מורכב מהחלק של זרם WebM עד לאשכול הראשון, לא כולל האשכול הראשון.

מדיה

האיור הבא מציג פריסה של פלח מדיה לדוגמה בפורמט WebM. הוא מורכב מאשכול WebM יחיד. בדומה לסטרימינג בפורמט ISO BMFF, קטע האתחול שמוסף לפני סדרה של קלאסטרים אמור ליצור סטרימינג תקין בפורמט WebM.

פלחי ISO BMFF

קובץ MPD עם פלח אתחול מוטמע

בדוגמה הבאה של MPD מוטמע קטע אתחול בכתובת URL של נתונים לפי RFC 2397. מומלץ להטמיע את קטע האתחול בצורה הזו במקום לשלוח אותו בנפרד.

הדוגמה הזו תואמת להטמעה של ISO BMFF‏ (H.264, ‏ AAC) ב-YouTube. רוב כתובת ה-URL של הנתונים הושמטה כדי לשפר את הקריאוּת:

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

MPD

קובץ ה-MPD לדוגמה הבא, שלא כולל פלח אתחול מוטמע, תואם גם להטמעה של ISO BMFF ‏ (H.264, ‏ AAC) ב-YouTube:

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

אתחול

בתרשים הבא מוצג הפריסה של פלח אתחול לדוגמה של ISO BMFF עם ריבוב. ‫YouTube לא בהכרח משתמש באטומים, אבל זו דוגמה תואמת. בפרט, יש ייצוג לטראקים של אודיו ושל וידאו.

מדיה

בתרשים הבא מוצג הפריסה של פלח מדיה לדוגמה בפורמט ISO BMFF עם ריבוב. מערכת YouTube לא בהכרח משתמשת בכל האטומים, אבל זהו דוגמה תואמת. בפרט, יש ייצוג לטראקים של אודיו ושל וידאו. אפשר לצרף סדרה של פלחים כאלה לפלח אתחול כדי ליצור זרם ISO BMFF תקף ומלא של ריבוב.

מגבלות ידועות

העלאות בפורמטים RTMP ו-DASH

אי אפשר לשלב בין שידורים בפורמט RTMP לבין שידורים בפורמט DASH ב-YouTube. ההגדרה הזו חלה על מעבר בין שתי השיטות במהלך שידור, וגם על שימוש באחת מהן כשיטה ראשית להעלאת נתונים ובשנייה כשיטה להעלאת נתונים לגיבוי.