אפשר להשתמש ב-ExoPlayer להוספת מודעות גם בצד הלקוח וגם בצד השרת.
הוספת מודעות בצד הלקוח
בהוספת מודעות בצד הלקוח, הנגן עובר בין טעינת מדיה מכתובות URL שונות במהלך המעבר בין תוכן למודעות. המידע על המודעות נטען בנפרד מהמדיה, למשל מתג מודעה מסוג VAST או VMAP בפורמט XML. המידע הזה יכול לכלול את מיקומי האותות להצגת מודעות ביחס להתחלת התוכן, את מזהי ה-URI של המדיה בפועל של המודעה ואת המטא-נתונים, כמו האפשרות לדלג על מודעה מסוימת.
כשמשתמשים ב-AdsMediaSource
של ExoPlayer להוספת מודעות בצד הלקוח, הנגן מכיל מידע על המודעות שיוצגו. יש לכך כמה יתרונות:
- הנגן יכול לחשוף מטא-נתונים ופונקציות שקשורות למודעות באמצעות ה-API שלו.
- רכיבי ממשק המשתמש של ExoPlayer יכולים להציג סמנים למיקומי המודעות באופן אוטומטי ולשנות את ההתנהגות שלהם בהתאם לכך שהמודעה פועלת או לא.
- באופן פנימי, הנגן יכול לשמור על מאגר עקבי במהלך מעברים בין מודעות לתוכן.
בהגדרה הזו, הנגן מטפל במעבר בין מודעות לתוכן, כלומר האפליקציות לא צריכות לנהל כמה נגנים נפרדים למודעות ולתוכן ברקע או בחזית.
כשאתם מכינים סרטוני תוכן ותגי מודעות לשימוש בהוספת מודעות בצד הלקוח, מומלץ למקם את המודעות בדוגמאות לסנכרון (פריימים מרכזיים) בסרטון התוכן, כדי שהנגן יוכל להמשיך את הפעלת התוכן בצורה חלקה.
תמיכה במודעות דקלרטיביות
אפשר לציין URI של תג מודעה כשיוצרים MediaItem
:
Kotlin
val mediaItem = MediaItem.Builder() .setUri(videoUri) .setAdsConfiguration(MediaItem.AdsConfiguration.Builder(adTagUri).build()) .build()
Java
MediaItem mediaItem = new MediaItem.Builder() .setUri(videoUri) .setAdsConfiguration( new MediaItem.AdsConfiguration.Builder(adTagUri).build()) .build();
כדי לאפשר תמיכה בנגן בפריטי מדיה שצוינו בהם תגי מודעות, צריך ליצור ולהחדיר DefaultMediaSourceFactory
שמוגדר עם AdsLoader.Provider
ו-AdViewProvider
כשיוצרים את הנגן:
Kotlin
val mediaSourceFactory: MediaSource.Factory = DefaultMediaSourceFactory(context).setLocalAdInsertionComponents(adsLoaderProvider, playerView) val player = ExoPlayer.Builder(context).setMediaSourceFactory(mediaSourceFactory).build()
Java
MediaSource.Factory mediaSourceFactory = new DefaultMediaSourceFactory(context) .setLocalAdInsertionComponents(adsLoaderProvider, /* adViewProvider= */ playerView); ExoPlayer player = new ExoPlayer.Builder(context).setMediaSourceFactory(mediaSourceFactory).build();
באופן פנימי, DefaultMediaSourceFactory
יכיל את מקור המדיה של התוכן ב-AdsMediaSource
. ה-AdsMediaSource
יקבל AdsLoader
מה-AdsLoader.Provider
וישתמש בו כדי להוסיף מודעות כפי שהוגדר בתג המודעות של פריט המדיה.
PlayerView
של ExoPlayer מטמיע את AdViewProvider
. ספריית ExoPlayer IMA מספקת AdsLoader
קל לשימוש, כפי שמתואר בהמשך.
פלייליסטים עם מודעות
כשמפעילים פלייליסט עם כמה פריטי מדיה, ברירת המחדל היא לבקש את תג המודעות ולאחסן את מצב ההפעלה של המודעה פעם אחת לכל שילוב של מזהה מדיה, URI של תוכן ו-URI של תג מודעות. כלומר, המשתמשים יראו מודעות לכל פריט מדיה עם מודעות שיש לו מזהה מדיה או URI תוכן ייחודי, גם אם מזהי ה-URI של תגי המודעות תואמים. אם פריט מדיה חוזר על עצמו, המשתמש יראה את המודעות התואמות רק פעם אחת (מצב ההפעלה של המודעות שומר אם המודעות הופעלו, כך שהן ידלגגו אחרי ההופעה הראשונה שלהן).
אפשר להתאים אישית את ההתנהגות הזו על ידי העברת מזהה מודעות אטום שמקושר למצב ההפעלה של המודעה בפריט מדיה נתון, על סמך שוויון בין אובייקטים. בדוגמה הבאה, מצב ההפעלה של המודעה מקושר ל-URI של תג המודעה בלבד, ולא לשילוב של מזהה המדיה ו-URI של תג המודעה, על ידי העברת ה-URI של תג המודעה כמזהה המודעות. התוצאה היא שהמודעות ייטענו רק פעם אחת והמשתמש לא יראה מודעות בפריט השני כשהפלייליסט יופעל מתחילתו ועד סופו.
Kotlin
// Build the media items, passing the same ads identifier for both items, // which means they share ad playback state so ads play only once. val firstItem = MediaItem.Builder() .setUri(firstVideoUri) .setAdsConfiguration(MediaItem.AdsConfiguration.Builder(adTagUri).setAdsId(adTagUri).build()) .build() val secondItem = MediaItem.Builder() .setUri(secondVideoUri) .setAdsConfiguration(MediaItem.AdsConfiguration.Builder(adTagUri).setAdsId(adTagUri).build()) .build() player.addMediaItem(firstItem) player.addMediaItem(secondItem)
Java
// Build the media items, passing the same ads identifier for both items, // which means they share ad playback state so ads play only once. MediaItem firstItem = new MediaItem.Builder() .setUri(firstVideoUri) .setAdsConfiguration( new MediaItem.AdsConfiguration.Builder(adTagUri).setAdsId(adTagUri).build()) .build(); MediaItem secondItem = new MediaItem.Builder() .setUri(secondVideoUri) .setAdsConfiguration( new MediaItem.AdsConfiguration.Builder(adTagUri).setAdsId(adTagUri).build()) .build(); player.addMediaItem(firstItem); player.addMediaItem(secondItem);
הוספת מודעות בצד הלקוח בהנחיית שרת
ExoPlayer מגיע עם HlsInterstitialsAdsLoader
שתומך בהוספה אוטומטית של מודעות בצד הלקוח, כפי שהוגדרו בפלייליסט ה-HLS. אפשר לעיין בקטע בנושא HlsInterstitialsAdsLoader
בדף HLS.
ספריית ExoPlayer IMA
ספריית IMA של ExoPlayer מספקת את ImaAdsLoader
, ומאפשרת לשלב בקלות הטמעת מודעות בצד הלקוח באפליקציה. היא עוטפת את הפונקציונליות של IMA SDK בצד הלקוח כדי לתמוך בהטמעת מודעות VAST/VMAP. הוראות לשימוש בספרייה, כולל הוראות לטיפול בהעברה לרקע ובהמשך ההפעלה, מפורטות בקובץ ה-README.
אפליקציית הדגמה משתמשת בספריית IMA, וכוללת כמה תגי מודעות VAST/VMAP לדוגמה ברשימת הדוגמאות.
שיקולים לגבי ממשק המשתמש
כברירת מחדל, PlayerView
מסתיר את אמצעי הבקרה על התעבורה במהלך ההפעלה של המודעות, אבל אפליקציות יכולות להחליף את ההתנהגות הזו באמצעות קריאה ל-setControllerHideDuringAds
. IMA SDK יציג תצוגות נוספות מעל הנגן בזמן שהמודעה פועלת (לדוגמה, קישור ל'מידע נוסף' ולחצן דילוג, אם רלוונטי).
מערכת IMA SDK עשויה לדווח אם מודעות מוסתרות על ידי תצוגות שסופקו על ידי האפליקציה ורנדרו מעל הנגן. באפליקציות שצריכות להציג שכבות-על של תצוגות שחשובות לשליטה בהפעלה, צריך לרשום אותן ב-IMA SDK כדי שאפשר יהיה להשמיט אותן מהחישובים של ניראות. כשמשתמשים ב-PlayerView
בתור AdViewProvider
, הוא ירשום באופן אוטומטי את שכבות הבקרה שלו. באפליקציות שמשתמשות בממשק משתמש מותאם אישית של נגן, צריך לרשום תצוגות שכבת-על על ידי החזרת אותן מ-AdViewProvider.getAdOverlayInfos
.
מידע נוסף על תצוגות שכבת-על זמין במאמר Open Measurement ב-IMA SDK.
מודעות נלוות
תגי מודעות מסוימים מכילים מודעות נלוויות נוספות שאפשר להציג ב 'משבצות' בממשק המשתמש של האפליקציה. אפשר להעביר את הסמנים האלה באמצעות ImaAdsLoader.Builder.setCompanionAdSlots(slots)
. מידע נוסף זמין במאמר הוספת מודעות נלוויות.
מודעות עצמאיות
IMA SDK מיועד להוספת מודעות לתוכן מדיה, ולא להפעלת מודעות עצמאיות. לכן, אין תמיכה בהפעלה של מודעות עצמאיות בספריית IMA. במקרה כזה, מומלץ להשתמש ב-Google Mobile Ads SDK במקום ב-Google Analytics SDK.
שימוש ב-SDK של מודעות של צד שלישי
אם אתם צריכים לטעון מודעות דרך SDK של מודעות של צד שלישי, כדאי לבדוק אם הוא כבר כולל שילוב של ExoPlayer. אם לא, מומלץ להטמיע AdsLoader
בהתאמה אישית שמקיפה את ה-SDK של מודעות הצד השלישי, כי היא מספקת את היתרונות של AdsMediaSource
שמפורטים למעלה.
ImaAdsLoader
משמש כהטמעה לדוגמה.
לחלופין, אפשר להשתמש בתמיכה בפלייליסטים של ExoPlayer כדי ליצור רצף של מודעות וקליפים של תוכן:
Kotlin
// A pre-roll ad. val preRollAd = MediaItem.fromUri(preRollAdUri) // The start of the content. val contentStart = MediaItem.Builder() .setUri(contentUri) .setClippingConfiguration(ClippingConfiguration.Builder().setEndPositionMs(120000).build()) .build() // A mid-roll ad. val midRollAd = MediaItem.fromUri(midRollAdUri) // The rest of the content val contentEnd = MediaItem.Builder() .setUri(contentUri) .setClippingConfiguration(ClippingConfiguration.Builder().setStartPositionMs(120000).build()) .build() // Build the playlist. player.addMediaItem(preRollAd) player.addMediaItem(contentStart) player.addMediaItem(midRollAd) player.addMediaItem(contentEnd)
Java
// A pre-roll ad. MediaItem preRollAd = MediaItem.fromUri(preRollAdUri); // The start of the content. MediaItem contentStart = new MediaItem.Builder() .setUri(contentUri) .setClippingConfiguration( new ClippingConfiguration.Builder().setEndPositionMs(120_000).build()) .build(); // A mid-roll ad. MediaItem midRollAd = MediaItem.fromUri(midRollAdUri); // The rest of the content MediaItem contentEnd = new MediaItem.Builder() .setUri(contentUri) .setClippingConfiguration( new ClippingConfiguration.Builder().setStartPositionMs(120_000).build()) .build(); // Build the playlist. player.addMediaItem(preRollAd); player.addMediaItem(contentStart); player.addMediaItem(midRollAd); player.addMediaItem(contentEnd);
הטמעת מודעות בצד השרת
בהטמעת מודעות בצד השרת (שנקראת גם הטמעת מודעות דינמיות, או DAI), מקור המדיה מכיל גם מודעות וגם תוכן. מניפסט DASH עשוי להפנות גם לפלחי תוכן וגם לפלחי מודעות, אולי בתקופות נפרדות. לגבי HLS, אפשר לעיין במסמכי העזרה של Apple בנושא שילוב מודעות בפלייליסט.
כשמשתמשים בהוספת מודעות בצד השרת, יכול להיות שהלקוח יצטרך לפתור את כתובת ה-URL של המדיה באופן דינמי כדי לקבל את הסטרימינג המחובר, להציג שכבות-על של מודעות בממשק המשתמש או לדווח על אירועים ל-SDK של מודעות או לשרת מודעות.
ה-DefaultMediaSourceFactory
של ExoPlayer יכול להעביר את כל המשימות האלה ל-MediaSource
להוספת מודעות בצד השרת עבור URI באמצעות הסכימה ssai://
:
Kotlin
val player = ExoPlayer.Builder(context) .setMediaSourceFactory( DefaultMediaSourceFactory(context).setServerSideAdInsertionMediaSourceFactory(ssaiFactory) ) .build()
Java
Player player = new ExoPlayer.Builder(context) .setMediaSourceFactory( new DefaultMediaSourceFactory(context) .setServerSideAdInsertionMediaSourceFactory(ssaiFactory)) .build();
ספריית ExoPlayer IMA
ספריית IMA של ExoPlayer מספקת את ImaServerSideAdInsertionMediaSource
, שמאפשר לשלב בקלות את המודעות שמוטמעות בצד השרת של IMA באפליקציה. הספרייה עוטפת את הפונקציונליות של IMA DAI SDK ל-Android ומטמיעה באופן מלא את המטא-נתונים של המודעות בנגן. לדוגמה, כך תוכלו להשתמש בשיטות כמו Player.isPlayingAd()
, להאזין למעברים בין תוכן למודעה ולאפשר לנגן לטפל בלוגיקה של הצגת המודעות, כמו דילוג על מודעות שכבר הוצגו.
כדי להשתמש בכיתה הזו, צריך להגדיר את ImaServerSideAdInsertionMediaSource.AdsLoader
ואת ImaServerSideAdInsertionMediaSource.Factory
ולקשר אותם לנגן:
Kotlin
// MediaSource.Factory to load the actual media stream. val defaultMediaSourceFactory = DefaultMediaSourceFactory(context) // AdsLoader that can be reused for multiple playbacks. val adsLoader = ImaServerSideAdInsertionMediaSource.AdsLoader.Builder(context, adViewProvider).build() // MediaSource.Factory to create the ad sources for the current player. val adsMediaSourceFactory = ImaServerSideAdInsertionMediaSource.Factory(adsLoader, defaultMediaSourceFactory) // Configure DefaultMediaSourceFactory to create both IMA DAI sources and // regular media sources. If you just play IMA DAI streams, you can also use // adsMediaSourceFactory directly. defaultMediaSourceFactory.setServerSideAdInsertionMediaSourceFactory(adsMediaSourceFactory) // Set the MediaSource.Factory on the Player. val player = ExoPlayer.Builder(context).setMediaSourceFactory(defaultMediaSourceFactory).build() // Set the player on the AdsLoader adsLoader.setPlayer(player)
Java
// MediaSource.Factory to load the actual media stream. DefaultMediaSourceFactory defaultMediaSourceFactory = new DefaultMediaSourceFactory(context); // AdsLoader that can be reused for multiple playbacks. ImaServerSideAdInsertionMediaSource.AdsLoader adsLoader = new ImaServerSideAdInsertionMediaSource.AdsLoader.Builder(context, adViewProvider).build(); // MediaSource.Factory to create the ad sources for the current player. ImaServerSideAdInsertionMediaSource.Factory adsMediaSourceFactory = new ImaServerSideAdInsertionMediaSource.Factory(adsLoader, defaultMediaSourceFactory); // Configure DefaultMediaSourceFactory to create both IMA DAI sources and // regular media sources. If you just play IMA DAI streams, you can also use // adsMediaSourceFactory directly. defaultMediaSourceFactory.setServerSideAdInsertionMediaSourceFactory(adsMediaSourceFactory); // Set the MediaSource.Factory on the Player. Player player = new ExoPlayer.Builder(context).setMediaSourceFactory(defaultMediaSourceFactory).build(); // Set the player on the AdsLoader adsLoader.setPlayer(player);
כדי לטעון את מפתח הנכס ב-IMA, או את מזהה מקור התוכן ומזהה הסרטון, יוצרים כתובת URL עם ImaServerSideAdInsertionUriBuilder
:
Kotlin
val ssaiUri = ImaServerSideAdInsertionUriBuilder() .setAssetKey(assetKey) .setFormat(C.CONTENT_TYPE_HLS) .build() player.setMediaItem(MediaItem.fromUri(ssaiUri))
Java
Uri ssaiUri = new ImaServerSideAdInsertionUriBuilder() .setAssetKey(assetKey) .setFormat(C.CONTENT_TYPE_HLS) .build(); player.setMediaItem(MediaItem.fromUri(ssaiUri));
לבסוף, משחררים את מערך הטעינה של המודעות כשלא משתמשים בו יותר:
Kotlin
adsLoader.release()
Java
adsLoader.release();
שיקולים לגבי ממשק המשתמש
השיקולים לגבי ממשק המשתמש שצריך לקחת בחשבון בהוספת מודעות בצד הלקוח רלוונטיים גם להוספת מודעות בצד השרת.
מודעות נלוות
תגי מודעות מסוימים מכילים מודעות נלוויות נוספות שאפשר להציג ב 'משבצות' בממשק המשתמש של האפליקציה. אפשר להעביר את הסמנים האלה באמצעות ImaServerSideAdInsertionMediaSource.AdsLoader.Builder.setCompanionAdSlots(slots)
.
מידע נוסף זמין במאמר הוספת מודעות נלווה.
שימוש ב-SDK של מודעות של צד שלישי
אם אתם צריכים לטעון מודעות באמצעות SDK של מודעות של צד שלישי, כדאי לבדוק אם הוא כבר מספק שילוב של ExoPlayer. אם לא, מומלץ לספק MediaSource
מותאם אישית שמקבל URI עם הסכימה ssai://
, בדומה ל-ImaServerSideAdInsertionMediaSource
.
אפשר להקצות את הלוגיקה בפועל של יצירת מבנה המודעה למטרה הכללית ServerSideAdInsertionMediaSource
, שמקיפה את הסטרימינג MediaSource
ומאפשרת למשתמש להגדיר ולעדכן את AdPlaybackState
שמייצג את המטא-נתונים של המודעה.
לעיתים קרובות, שידורי מודעות שמוטמעים בצד השרת מכילים אירועים מתוזמנים כדי להודיע לנגן על המטא-נתונים של המודעות. במאמר פורמטים נתמכים מפורט מידע על הפורמטים של מטא-נתונים מתוזמנים שנתמכים ב-ExoPlayer. הטמעות מותאמות אישית של MediaSource
SDK להצגת מודעות יכולות להאזין לאירועי מטא-נתונים מתוזמנים מהנגן באמצעות
Player.Listener.onMetadata
.