הפעלת שידורים חיים שנרשמו באמצעות Google Cloud Video Stitcher API
במדריך הזה מוסבר איך להשתמש ב-IMA DAI SDK עבור CAF Web Receivers כדי לבקש ולהפעיל שידור חי של אירוע שנרשם ב-Google Cloud Video Stitcher API, ולהוסיף הפסקה למודעה במהלך ההפעלה.
המדריך הזה מרחיב את הדוגמה הבסיסית מ-DAI עם שירות מלא, ומוסיף תמיכה בסטרימינג שנרשם ב-Google Cloud Video Stitcher API.
לפני שממשיכים, חשוב לוודא שפורמט הסטרימינג נתמך על ידי מקלטי אינטרנט של CAF.
למידע על שילוב עם פלטפורמות אחרות או על שימוש ב-IMA SDKs בצד הלקוח, אפשר לעיין במאמר בנושא Interactive Media Ads SDKs.
רקע
לפני שמשתמשים במדריך הזה, כדאי להכיר את הפרוטוקול של Web Receiver ב-Chromecast Application Framework.
המדריך הזה מיועד למי שיש לו ידע בסיסי במושגים של מקלטי CAF, כמו message interceptors, אובייקטים של MediaInformation ושימוש בכלי Cast Command and Control כדי לבצע אמולציה של שולח CAF.
רכיבים וארכיטקטורה של אפליקציות
הטמעה של הפעלת שידורים חיים באמצעות Google Cloud Video Stitcher API עם IMA CAF DAI SDK כוללת שני רכיבים עיקריים, כפי שמוסבר במדריך הזה:
-
VideoStitcherLiveStreamRequest: אובייקט שמגדיר בקשת סטרימינג לשרתים של Google. הבקשה מציינת מופע של Cloud Video Stitcher API, מזהה של הגדרה לשידור חי ופרמטרים אופציונליים אחרים. -
StreamManager: אובייקט שמטפל בתקשורת בין סטרימינג הווידאו לבין IMA DAI SDK, כמו הפעלת פינגים למעקב והעברת אירועים של סטרימינג אל בעל האתר.
דרישות מוקדמות
צריכים את המשתנים הבאים בשביל IMA SDK:
Live Config ID: מזהה ההגדרה לשידור חי שציינתם כשבניתם את ההגדרה לשידור חי ב-Video Stitcher API.
LIVE_CONFIG_IDמיקום: האזור ב-Google Cloud שבו נוצר Live Config.
LOCATIONמספר הפרויקט: מספר הפרויקט בענן של Google שבו נעשה שימוש ב-Video Stitcher API.
PROJECT_NUMBERאסימון OAuth: אסימון OAuth לטווח קצר של חשבון שירות עם תפקיד המשתמש Video Stitcher. מידע נוסף על יצירת פרטי כניסה לטווח קצר לחשבונות שירות
OAUTH_TOKENקוד הרשת: קוד הרשת של Google Ad Manager לשליחת בקשות להצגת מודעות.
NETWORK_CODEמפתח נכס בהתאמה אישית: מפתח נכס בהתאמה אישית ב-Google Ad Manager שנוצר במהלך יצירת הגדרה לאירוע שידור חי באמצעות Video Stitcher API.
CUSTOM_ASSET_KEY
כדי ליצור מכשיר Cast בהתאמה אישית, צריך:
חשבון ב-Cast Developer Console עם מכשירי בדיקה ברשימת ההיתרים.
אפליקציית מקלט אינטרנט מתארחת שרשומה ב-Cast Developer Console, שאפשר לשנות אותה כדי לארח את הקוד שמופיע במדריך הזה.
אפליקציה לשליחה שהוגדרה לשימוש באפליקציית המקלט באינטרנט. לצורך הדוגמה הזו, במדריך הזה נעשה שימוש בכלי Cast Command and Control בתור השולח.
הכנת השולח להעברת נתוני הזרם אל המקלט
קודם כול, צריך להגדיר את אפליקציית השולח כך שתשלח בקשת טעינה למקלט האינטרנט,
שתכלול את השדות הבאים באובייקט MediaInformation
של הפלטפורמה.
| שדה | תוכן עניינים | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
contentId
|
מזהה ייחודי של פריט המדיה הזה, כפי שמוגדר במסמכי העיון של Cast. אסור להשתמש באותו מזהה לכמה פריטים באותה רשימת השמעה של מדיה.
|
||||||||||||||
contentUrl
|
כתובת URL אופציונלית של שידור לגיבוי, שתופעל אם השידור של DAI לא ייטען.
|
||||||||||||||
contentType
|
Mimetype אופציונלי של כתובת ה-URL של הגיבוי של השידור להפעלה אם השידור של DAI
לא נטען.
|
||||||||||||||
streamType
|
המחרוזת המילולית או הקבוע שמשמשים לערך הזה משתנים בהתאם לפלטפורמת השולח.
|
||||||||||||||
customData
|
השדה
|
ריכזנו כאן כמה דוגמאות לקוד שיעזרו לכם להתחיל:
אינטרנט
כדי להגדיר את הערכים האלה בשולט Cast באינטרנט, קודם יוצרים אובייקט MediaInfo עם הנתונים הנדרשים, ואז שולחים בקשת טעינה למקלט האינטרנט.
// Create mediaInfo object
const mediaInfo = new chrome.cast.media.MediaInfo("CONTENT_ID");
mediaInfo.contentUrl = "BACKUP_STREAM_URL";
mediaInfo.contentType = "BACKUP_STREAM_MIMETYPE";
mediaInfo.streamType = chrome.cast.media.StreamType.LIVE;
mediaInfo.customData = {
liveConfigID: "LIVE_CONFIG_ID",
region: "LOCATION",
projectNumber: "PROJECT_NUMBER",
oAuthToken: "OAUTH_TOKEN",
networkCode: "NETWORK_CODE",
customAssetKey: "CUSTOM_ASSET_KEY"
};
// Make load request to cast web receiver
const castSession = cast.framework.CastContext.getInstance().getCurrentSession();
const request = new chrome.cast.media.LoadRequest(mediaInfo);
castSession.loadMedia(request).then(
() => { console.log('Load succeed'); },
(errorCode) => { console.log('Error code: ' + errorCode); });
Android
כדי להגדיר את הערכים האלה בשולח אינטרנט של Cast, קודם יוצרים אובייקט MediaInfo עם הנתונים הנדרשים, ואז שולחים בקשת טעינה למקלט האינטרנט.
JSONObject customData = new JSONObject()
.put("liveConfigID", "LIVE_CONFIG_ID")
.put("region", "LOCATION")
.put("projectNumber", "PROJECT_NUMBER")
.put("oAuthToken", "OAUTH_TOKEN")
.put("networkCode", "NETWORK_CODE")
.put("customAssetKey", "CUSTOM_ASSET_KEY");
MediaInfo mediaInfo = MediaInfo.Builder("CONTENT_ID")
.setContentUrl("BACKUP_STREAM_URL")
.setContentType("BACKUP_STREAM_MIMETYPE")
.setStreamType(MediaInfo.STREAM_TYPE_LIVE)
.setCustomData(customData)
.build();
RemoteMediaClient remoteMediaClient = mCastSession.getRemoteMediaClient();
remoteMediaClient.load(new MediaLoadRequestData.Builder().setMediaInfo(mediaInfo).build());
iOS (Obj-C)
כדי להגדיר את הערכים האלה בשולט Cast באינטרנט, קודם יוצרים אובייקט GCKMediaInformation עם הנתונים הנדרשים, ואז שולחים בקשת טעינה למקלט האינטרנט.
NSURL url = [NSURL URLWithString:@"BACKUP_STREAM_URL"];
NSDictionary *customData = @{
@"liveConfigID": @"LIVE_CONFIG_ID",
@"region": @"LOCATION",
@"projectNumber": @"PROJECT_NUMBER",
@"oAuthToken": @"OAUTH_TOKEN",
@"networkCode": @"NETWORK_CODE",
@"customAssetKey": @"CUSTOM_ASSET_KEY"
};
GCKMediaInformationBuilder *mediaInfoBuilder =
[[GCKMediaInformationBuilder alloc] initWithContentID: @"CONTENT_ID"];
mediaInfoBuilder.contentURL = url;
mediaInfoBuilder.contentType = @"BACKUP_STREAM_MIMETYPE";
mediaInfoBuilder.streamType = GCKMediaStreamTypeLive;
mediaInfoBuilder.customData = customData;
self.mediaInformation = [mediaInfoBuilder build];
GCKRequest *request = [self.sessionManager.currentSession.remoteMediaClient loadMedia:self.mediaInformation];
if (request != nil) {
request.delegate = self;
}
iOS (Swift)
כדי להגדיר את הערכים האלה בשולט Cast באינטרנט, קודם יוצרים אובייקט GCKMediaInformation עם הנתונים הנדרשים, ואז שולחים בקשת טעינה למקלט האינטרנט.
let url = URL.init(string: "BACKUP_STREAM_URL")
guard let mediaURL = url else {
print("invalid mediaURL")
return
}
let customData = [
"liveConfigID": "LIVE_CONFIG_ID",
"region": "LOCATION",
"projectNumber": "PROJECT_NUMBER",
"oAuthToken": "OAUTH_TOKEN",
"networkCode": "NETWORK_CODE",
"customAssetKey": "CUSTOM_ASSET_KEY"
]
let mediaInfoBuilder = GCKMediaInformationBuilder.init(contentId: "CONTENT_ID")
mediaInfoBuilder.contentURL = mediaUrl
mediaInfoBuilder.contentType = "BACKUP_STREAM_MIMETYPE"
mediaInfoBuilder.streamType = GCKMediaStreamType.Live
mediaInfoBuilder.customData = customData
mediaInformation = mediaInfoBuilder.build()
guard let mediaInfo = mediaInformation else {
print("invalid mediaInformation")
return
}
if let request = sessionManager.currentSession?.remoteMediaClient?.loadMedia(mediaInfo) {
request.delegate = self
}
כלי CAC
כדי להגדיר את הערכים האלה בכלי Cast Command and Control, לוחצים על הכרטיסייה Load Media (טעינת מדיה) ומגדירים את סוג בקשת הטעינה המותאמת אישית ל-LOAD. אחר כך מחליפים את נתוני ה-JSON באזור הטקסט ב-JSON הזה:
{
"media": {
"contentId": "CONTENT_ID",
"contentUrl": "BACKUP_STREAM_URL",
"contentType": "BACKUP_STREAM_MIMETYPE",
"streamType": "LIVE",
"customData": {
"liveConfigID": "LIVE_CONFIG_ID",
"region": "LOCATION",
"projectNumber": "PROJECT_NUMBER",
"oAuthToken": "OAUTH_TOKEN",
"networkCode": "NETWORK_CODE",
"customAssetKey": "CUSTOM_ASSET_KEY"
}
}
}
אפשר לשלוח את בקשת הטעינה המותאמת הזו למקבל כדי לבדוק את שאר השלבים.
יצירת מקלט אינטרנט CAF בהתאמה אישית
יוצרים מקלט אינטרנט בהתאמה אישית, כמו שמוסבר במדריך בנושא CAF SDK Custom Web Receiver.
הקוד של המקלט צריך להיראות כך:
<html>
<head>
<script
src="//www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js">
</script>
</head>
<body>
<cast-media-player></cast-media-player>
<script>
const castContext = cast.framework.CastReceiverContext.getInstance()
castContext.start();
</script>
</body>
</html>
ייבוא של IMA DAI SDK והשגת Player Manager
מוסיפים תג סקריפט כדי לייבא את IMA DAI SDK ל-CAF אל מקלט האינטרנט, מיד אחרי טעינת הסקריפט של CAF. לאחר מכן, בתג הסקריפט שמופיע אחריו, מאחסנים את ההקשר של המקלט ואת מנהל ההפעלה כקבועים לפני שמפעילים את המקלט.
<html>
<head>
<script
src="//www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js"></script>
<script src="//imasdk.googleapis.com/js/sdkloader/cast_dai.js"></script>
</head>
<body>
<cast-media-player></cast-media-player>
<script>
const castContext = cast.framework.CastReceiverContext.getInstance();
const playerManager = castContext.getPlayerManager();
castContext.start();
</script>
</body>
</html>
הפעלת IMA Stream Manager
מאתחלים את IMA Stream Manager.
<html>
<head>
<script type="text/javascript"
src="//www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js"></script>
<script src="//imasdk.googleapis.com/js/sdkloader/cast_dai.js"></script>
</head>
<body>
<cast-media-player></cast-media-player>
<script>
const castContext = cast.framework.CastReceiverContext.getInstance();
const playerManager = castContext.getPlayerManager();
const streamManager = new google.ima.cast.dai.api.StreamManager();
castContext.start();
</script>
</body>
</html>
יצירת Stream Manager Load Interceptor
לפני שהפריטים של המדיה מועברים ל-CAF, צריך ליצור את בקשת הסטרימינג ביירוט של הודעת LOAD.
const castContext = cast.framework.CastReceiverContext.getInstance();
const playerManager = castContext.getPlayerManager();
const streamManager = new google.ima.cast.dai.api.StreamManager();
/**
* Creates a livestream request object for the Video Stitcher API.
* @param {!LoadRequestData} castRequest The request object from the cast sender
* @return {StreamRequest} an IMA stream request
*/
const createStreamRequest = (castRequest) => { /* ... */};
/**
* Initates a DAI stream request for the final stream manifest.
* @param {!LoadRequestData} castRequest The request object from the cast sender
* @return {Promise<LoadRequestData>} a promise that resolves to an updated castRequest, containing the DAI stream manifest
*/
const createDAICastRequest = (castRequest) => {
return streamManager.requestStream(castRequest, createStreamRequest(castRequest))
.then((castRequestWithStreamData) => {
console.log('Successfully made DAI stream request.');
return castRequestWithStreamData;
})
.catch((error) => {
console.log('Failed to make DAI stream request.');
// CAF will automatically fallback to the content URL
// that it can read from the castRequest object.
return castRequest;
});
};
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.LOAD, createDAICastRequest);
castContext.start();
יצירת בקשת הזרמה
משלימים את הפונקציה createStreamRequest כדי ליצור בקשה לשידור חי של Video Stitcher API, על סמך בקשת הטעינה של CAF.
/**
* Creates a livestream request object for the Video Stitcher API.
* @param {!LoadRequestData} castRequest The request object from the cast sender
* @return {StreamRequest} an IMA stream request
*/
const createStreamRequest = (castRequest) => {
const streamRequest = new google.ima.cast.dai.api.VideoStitcherLiveStreamRequest();
const customData = castRequest.media.customData;
streamRequest.liveStreamEventId = customData.liveConfigID;
streamRequest.region = customData.region;
streamRequest.projectNumber = customData.projectNumber;
streamRequest.oAuthToken = customData.oAuthToken;
streamRequest.networkCode = customData.networkCode;
streamRequest.customAssetKey = customData.customAssetKey;
return streamRequest;
};
(אופציונלי) הוספת אפשרויות של סשן סטרימינג
אפשר להתאים אישית את בקשת הסטרימינג על ידי הוספת אפשרויות הפעלה כדי לשנות את הגדרת ברירת המחדל של Cloud Video Stitcher API באמצעות VideoStitcherLiveStreamRequest.videoStitcherSessionOptions.
אם תספקו אפשרות לא מזוהה, Cloud Video Stitcher API יגיב עם שגיאת HTTP 400. אפשר לקבל עזרה במדריך לפתרון בעיות.
לדוגמה, אפשר לשנות את אפשרויות המניפסט באמצעות קטע הקוד הבא, ששולח בקשה לשני מניפסטים של סטרימינג עם רכיבי עיבוד שמוזמנים משיעור העברת הנתונים הנמוך ביותר לגבוה ביותר.
...
// The following session options are examples. Use session options
// that are compatible with your video stream.
streamRequest.videoStitcherSessionOptions = {
"manifestOptions": {
"bitrateOrder": "ascending"
}
};
streamManager.requestStream(streamRequest);