הפסקות למודעות
קל לארגן דפים בעזרת אוספים
אפשר לשמור ולסווג תוכן על סמך ההעדפות שלך.
ב-Android TV Receiver SDK יש תמיכה מובנית בהפסקות למודעות ובמודעות נלוויות בסטרימינג של מדיה נתון.
למידע נוסף על אופן הפעולה של הפסקות למודעות, אפשר לעיין במאמר סקירה כללית על הפסקות למודעות במכשירי קצה לאינטרנט.
ניהול עומס באמצעות הפסקות למודעות
באפליקציה ל-Android TV, ההפסקות כלולות בMediaLoadRequestData
.
אפשר לעבד בקשות טעינה באופן רגיל, ואפשר לאחזר את הערכים של AdBreakClipInfo
ושל AdBreakInfo
מ-MediaInfo
:
class MyMediaLoadCommandCallback : MediaLoadCommandCallback() {
override fun onLoad( senderId: String?, loadRequestData: MediaLoadRequestData
): Task {
return Tasks.call {
// Resolve the entity into your data structure and load media.
val mediaInfo = loadRequestData.mediaInfo
...
myPrepareAdBreaks(mediaInfo.adBreakClips, mediaInfo.adBreaks)
// Update media metadata and state (this clears all previous status
// overrides).
castReceiverContext.getMediaStatusModifier()
.setDataFromLoad(mediaInfo) // Ad breaks are set on the modifier.
castReceiverContext.getMediaManager().broadcastMediaStatus()
// Return the resolved MediaLoadRequestData to indicate load success.
return loadRequestData
}
}
}
public class MyMediaLoadCommandCallback extends MediaLoadCommandCallback {
@Override
public Task onLoad(String senderId, MediaLoadRequestData loadRequestData) {
return Tasks.call(() -> {
// Resolve the entity into your data structure and load media.
MediaInfo mediaInfo = loadRequestData.getMediaInfo();
...
myPrepareAdBreaks(mediaInfo.getAdBreakClips(), mediaInfo.getAdBreaks());
// Update media metadata and state (this clears all previous status
// overrides).
castReceiverContext.getMediaStatusModifier()
.setDataFromLoad(mediaInfo); // Ad breaks are set on the modifier.
castReceiverContext.getMediaManager().broadcastMediaStatus();
// Return the resolved MediaLoadRequestData to indicate load success.
return loadRequestData;
});
}
}
עדכון ההפסקות למודעות
כשהמודעות מתחילות לפעול, מעדכנים את הערך של AdBreakStatus
ב-MediaStatusModifier
כדי להעביר את ההודעה שהאפליקציה התחילה להציג מודעות:
val breakStatus = AdBreakStatus.Builder()
.setBreakId("b1")
.setBreakClipId("bc1")
.setCurrentBreakClipTimeInMs(breakClipProgress)
.setCurrentBreakTimeInMs(breakProgress)
.setWhenSkippableInMs(5000) // Set this field so that the ad break clip is skippable
.build()
castReceiverContext.getMediaStatusModifier()
.setAdBreakStatus(breakStatus)
AdBreakStatus breakStatus =
new AdBreakStatus.Builder()
.setBreakId("b1")
.setBreakClipId("bc1")
.setCurrentBreakClipTimeInMs(breakClipProgress)
.setCurrentBreakTimeInMs(breakProgress)
.setWhenSkippableInMs(5000) // Set this field so that the ad break clip is skippable
.build();
castReceiverContext.getMediaStatusModifier()
.setAdBreakStatus(breakStatus);
אפשר גם לשנות באופן דינמי את ההפסקות למודעות אחרי טעינת פריט:
var breakClip1: AdBreakClipInfo = ...
var breakClip2: AdBreakClipInfo = ...
var breakClip3: AdBreakClipInfo = ...
var break1: AdBreakInfo = ...
var break2: AdBreakInfo = ...
mediaManager.getMediaStatusModifier().getMediaInfoModifier()
.setAdBreakClips({breakClip1, breakClip2, breakClip3})
.setAdBreaks({break1, break2})
AdBreakClipInfo breakClip1 = ...
AdBreakClipInfo breakClip2 = ...
AdBreakClipInfo breakClip3 = ...
AdBreakInfo break1 = ...
AdBreakInfo break2 = ...
mediaManager.getMediaStatusModifier().getMediaInfoModifier()
.setAdBreakClips({breakClip1, breakClip2, breakClip3})
.setAdBreaks({break1, break2});
הפעלה וטיפול בדילוג על מודעות
כשהפסקה למודעה מתחילה לפעול, לשולחים יוצג לחצן לדילוג על קטע ההפסקה הנוכחי למודעה, אם אפשר לדלג עליו. כדי לאפשר למשתמש לדלג על קטע של הפסקה למודעה, משתמשים ב-MediaStatusModifier
כדי להוסיף את פקודת המדיה COMMAND_SKIP_AD
:
mMediaManager.getMediaStatusModifier().setMediaCommandSupported(MediaStatus.COMMAND_SKIP_AD, true)
mMediaManager.getMediaStatusModifier().setMediaCommandSupported(MediaStatus.COMMAND_SKIP_AD, true);
כדי לטפל בפקודה SKIP_AD
, מטמיעים את הפונקציה החוזרת (callback) onSkipAd
ב-MediaCommandCallback
:
class MyMediaCommandCallback : MediaCommandCallback() {
override fun onSkipAd(requestData: RequestData?): Task<Void?> {
// Skip your ad
...
return Tasks.forResult<Any?>(null)
}
}
val mediaManager = CastReceiverContext.getInstance().mediaManager
mediaManager.setMediaCommandCallback(MyMediaCommandCallback())
public class MyMediaCommandCallback extends MediaCommandCallback {
@Override
public Task onSkipAd(RequestData requestData) {
// Skip your ad
...
return Tasks.forResult(null);
}
}
MediaManager mediaManager =
CastReceiverContext.getInstance().getMediaManager();
mediaManager.setMediaCommandCallback(new MyMediaCommandCallback());
חיבור בצד הלקוח
חיבור בצד הלקוח: המודעות לא מוטמעות בסטרימינג. ב-Cast Connect, בנוסף לעדכון הערך של AdBreakStatus
ב-MediaStatusModifier
, צריך להגדיר את מהירות ההפעלה ל-0 ב-PlaybackStateCompat
כדי שהשולחים ידעו להקפיא את התקדמות ציר הזמן של התוכן.
// Playback speed should be 0 if content is not playing.
if (adIsPlaying) {
playbackSpeed = 0.0f
}
val stateBuilder = PlaybackStateCompat.Builder()
.setActions(AVAILABLE_MEDIA_ACTIONS)
stateBuilder.setState(playbackStateCompat, position, playbackSpeed)
mediaSession.setPlaybackState(stateBuilder.build())
// Playback speed should be 0 if content is not playing.
if (adIsPlaying) {
playbackSpeed = 0.0f;
}
PlaybackStateCompat.Builder stateBuilder = new PlaybackStateCompat.Builder()
.setActions(AVAILABLE_MEDIA_ACTIONS);
stateBuilder.setState(playbackStateCompat, position, playbackSpeed);
mediaSession.setPlaybackState(stateBuilder.build());
אחרי שהמודעה תסתיים, צריך להמשיך במהירות ההפעלה הקודמת.
חיבור בצד השרת
בהצמדה בצד השרת, המודעות מוטמעות כך שהשרת אמור לספק שידור יחיד שמכיל גם את התוכן וגם את המודעות. במקרה כזה, ההפעלה יכולה להמשיך להתקדם כרגיל כי ציר הזמן מכיל את משך המודעה בנוסף לתוכן.
אלא אם צוין אחרת, התוכן של דף זה הוא ברישיון Creative Commons Attribution 4.0 ודוגמאות הקוד הן ברישיון Apache 2.0. לפרטים, ניתן לעיין במדיניות האתר Google Developers. Java הוא סימן מסחרי רשום של חברת Oracle ו/או של השותפים העצמאיים שלה.
עדכון אחרון: 2025-08-31 (שעון UTC).
[null,null,["עדכון אחרון: 2025-08-31 (שעון UTC)."],[[["\u003cp\u003eThe Android TV Receiver SDK natively supports ad breaks and companion ads, allowing developers to integrate ads into their media streams.\u003c/p\u003e\n"],["\u003cp\u003eDevelopers can handle ad breaks by including them in \u003ccode\u003eMediaLoadRequestData\u003c/code\u003e and retrieving information about them from \u003ccode\u003eMediaInfo\u003c/code\u003e.\u003c/p\u003e\n"],["\u003cp\u003eWhen ads start playing, developers need to update the \u003ccode\u003eAdBreakStatus\u003c/code\u003e to inform the sender app and enable ad skipping by setting \u003ccode\u003eCOMMAND_SKIP_AD\u003c/code\u003e as supported.\u003c/p\u003e\n"],["\u003cp\u003eFor client-side stitching where ads are not embedded, developers must freeze the content timeline progress by setting the playback speed to 0 during ad playback.\u003c/p\u003e\n"],["\u003cp\u003eServer-side stitching embeds ads within the stream, allowing playback to progress normally as the timeline includes ad duration.\u003c/p\u003e\n"]]],["The Android TV Receiver SDK supports ad breaks and companion ads. During media loading, `AdBreakClipInfo` and `AdBreakInfo` are retrievable from `MediaInfo`. When ads begin, `AdBreakStatus` updates are broadcast via `MediaStatusModifier`. Ad breaks can be dynamically modified with `setAdBreakClips` and `setAdBreaks`. To enable ad skipping, set the `COMMAND_SKIP_AD` media command. For client-side ad stitching, playback speed must be set to 0 when ads play, resuming normal speed afterward. For server-side stitching, playback progresses normally.\n"],null,["# Ad Breaks\n\nThe Android TV Receiver SDK features native support for Ad Breaks and companion\nads within a given media stream.\n\nSee the [Web Receiver Ad Breaks Overview](/cast/docs/web_receiver/ad_breaks)\nfor more information on how Ad Breaks work.\n\nHandling load with ad breaks\n----------------------------\n\nOn your Android TV app, the breaks are included in\n[`MediaLoadRequestData`](/android/reference/com/google/android/gms/cast/MediaLoadRequestData).\nLoad requests can be processed normally and the\n[`AdBreakClipInfo`](/android/reference/com/google/android/gms/cast/AdBreakClipInfo)s\nand\n[`AdBreakInfo`](/android/reference/com/google/android/gms/cast/AdBreakInfo)s\ncan be retrieved from the\n[`MediaInfo`](/android/reference/com/google/android/gms/cast/MediaInfo):\nKotlin \n\n```kotlin\nclass MyMediaLoadCommandCallback : MediaLoadCommandCallback() {\n override fun onLoad( senderId: String?, loadRequestData: MediaLoadRequestData\n ): Task {\n return Tasks.call {\n // Resolve the entity into your data structure and load media.\n val mediaInfo = loadRequestData.mediaInfo\n ...\n myPrepareAdBreaks(mediaInfo.adBreakClips, mediaInfo.adBreaks)\n // Update media metadata and state (this clears all previous status\n // overrides).\n castReceiverContext.getMediaStatusModifier()\n .setDataFromLoad(mediaInfo) // Ad breaks are set on the modifier.\n castReceiverContext.getMediaManager().broadcastMediaStatus()\n // Return the resolved MediaLoadRequestData to indicate load success.\n return loadRequestData\n }\n }\n}\n```\nJava \n\n```gdscript\npublic class MyMediaLoadCommandCallback extends MediaLoadCommandCallback {\n @Override\n public Task onLoad(String senderId, MediaLoadRequestData loadRequestData) {\n return Tasks.call(() -\u003e {\n // Resolve the entity into your data structure and load media.\n MediaInfo mediaInfo = loadRequestData.getMediaInfo();\n ...\n myPrepareAdBreaks(mediaInfo.getAdBreakClips(), mediaInfo.getAdBreaks());\n // Update media metadata and state (this clears all previous status\n // overrides).\n castReceiverContext.getMediaStatusModifier()\n .setDataFromLoad(mediaInfo); // Ad breaks are set on the modifier.\n castReceiverContext.getMediaManager().broadcastMediaStatus();\n // Return the resolved MediaLoadRequestData to indicate load success.\n return loadRequestData;\n });\n }\n}\n```\n\nUpdating ad breaks\n------------------\n\nWhen ads start playing, update the\n[`AdBreakStatus`](/android/reference/com/google/android/gms/cast/AdBreakStatus)\non the\n[`MediaStatusModifier`](/android/reference/com/google/android/gms/cast/tv/media/MediaStatusModifier)\nto broadcast that your app has started playing ads:\nKotlin \n\n```kotlin\nval breakStatus = AdBreakStatus.Builder()\n .setBreakId(\"b1\")\n .setBreakClipId(\"bc1\")\n .setCurrentBreakClipTimeInMs(breakClipProgress)\n .setCurrentBreakTimeInMs(breakProgress)\n .setWhenSkippableInMs(5000) // Set this field so that the ad break clip is skippable\n .build()\n\ncastReceiverContext.getMediaStatusModifier()\n .setAdBreakStatus(breakStatus)\n```\nJava \n\n```java\nAdBreakStatus breakStatus =\n new AdBreakStatus.Builder()\n .setBreakId(\"b1\")\n .setBreakClipId(\"bc1\")\n .setCurrentBreakClipTimeInMs(breakClipProgress)\n .setCurrentBreakTimeInMs(breakProgress)\n .setWhenSkippableInMs(5000) // Set this field so that the ad break clip is skippable\n .build();\n\ncastReceiverContext.getMediaStatusModifier()\n .setAdBreakStatus(breakStatus);\n```\n\nYou can also dynamically modify the ad breaks after an item is loaded:\nKotlin \n\n```kotlin\nvar breakClip1: AdBreakClipInfo = ...\nvar breakClip2: AdBreakClipInfo = ...\nvar breakClip3: AdBreakClipInfo = ...\n\nvar break1: AdBreakInfo = ...\nvar break2: AdBreakInfo = ...\n\nmediaManager.getMediaStatusModifier().getMediaInfoModifier()\n .setAdBreakClips({breakClip1, breakClip2, breakClip3})\n .setAdBreaks({break1, break2})\n```\nJava \n\n```text\nAdBreakClipInfo breakClip1 = ...\nAdBreakClipInfo breakClip2 = ...\nAdBreakClipInfo breakClip3 = ...\n\nAdBreakInfo break1 = ...\nAdBreakInfo break2 = ...\n\nmediaManager.getMediaStatusModifier().getMediaInfoModifier()\n .setAdBreakClips({breakClip1, breakClip2, breakClip3})\n .setAdBreaks({break1, break2});\n```\n\nEnable and handle ad skipping\n-----------------------------\n\nWhen an ad break is playing, the senders will show a button to skip the current\nad break clip if it is skippable. To enable the ability for a user to skip an ad\nbreak clip, use the\n[`MediaStatusModifier`](/android/reference/com/google/android/gms/cast/tv/media/MediaStatusModifier)\nto add the\n[`COMMAND_SKIP_AD`](/android/reference/com/google/android/gms/cast/MediaStatus#public-static-final-long-command_skip_ad)\nmedia command:\nKotlin \n\n```kotlin\nmMediaManager.getMediaStatusModifier().setMediaCommandSupported(MediaStatus.COMMAND_SKIP_AD, true)\n```\nJava \n\n```scdoc\nmMediaManager.getMediaStatusModifier().setMediaCommandSupported(MediaStatus.COMMAND_SKIP_AD, true);\n```\n\nTo handle the `SKIP_AD` command, implement the\n[`onSkipAd`](/android/reference/com/google/android/gms/cast/tv/media/MediaCommandCallback#onSkipAd(java.lang.String,%20com.google.android.gms.cast.RequestData))\ncallback in your\n[`MediaCommandCallback`](/android/reference/com/google/android/gms/cast/tv/media/MediaCommandCallback)s:\nKotlin \n\n```kotlin\nclass MyMediaCommandCallback : MediaCommandCallback() {\n override fun onSkipAd(requestData: RequestData?): Task\u003cVoid?\u003e {\n // Skip your ad\n ...\n return Tasks.forResult\u003cAny?\u003e(null)\n }\n}\n\nval mediaManager = CastReceiverContext.getInstance().mediaManager\nmediaManager.setMediaCommandCallback(MyMediaCommandCallback())\n```\nJava \n\n```gdscript\npublic class MyMediaCommandCallback extends MediaCommandCallback {\n @Override\n public Task onSkipAd(RequestData requestData) {\n // Skip your ad\n ...\n return Tasks.forResult(null);\n }\n}\n\nMediaManager mediaManager =\n CastReceiverContext.getInstance().getMediaManager();\nmediaManager.setMediaCommandCallback(new MyMediaCommandCallback());\n```\n\nClient-side stitching\n---------------------\n\n[Client-side stitching](/cast/docs/caf_receiver/ad_breaks#client-side_ad_stitching)\nis where ads are not embedded in the stream. For Cast Connect, in addition to\nupdating the\n[`AdBreakStatus`](/android/reference/com/google/android/gms/cast/AdBreakStatus)\non the\n[`MediaStatusModifier`](/android/reference/com/google/android/gms/cast/tv/media/MediaStatusModifier)\nyou mustset the playback speed to 0 on the\n[`PlaybackStateCompat`](https://developer.android.com/reference/kotlin/android/support/v4/media/session/PlaybackStateCompat.Builder)\nso the senders know to freeze the content timeline progress.\nKotlin \n\n```kotlin\n// Playback speed should be 0 if content is not playing.\nif (adIsPlaying) {\n playbackSpeed = 0.0f\n}\nval stateBuilder = PlaybackStateCompat.Builder()\n .setActions(AVAILABLE_MEDIA_ACTIONS)\nstateBuilder.setState(playbackStateCompat, position, playbackSpeed)\nmediaSession.setPlaybackState(stateBuilder.build())\n```\nJava \n\n```scilab\n// Playback speed should be 0 if content is not playing.\nif (adIsPlaying) {\n playbackSpeed = 0.0f;\n}\nPlaybackStateCompat.Builder stateBuilder = new PlaybackStateCompat.Builder()\n .setActions(AVAILABLE_MEDIA_ACTIONS);\nstateBuilder.setState(playbackStateCompat, position, playbackSpeed);\nmediaSession.setPlaybackState(stateBuilder.build());\n```\n\nOnce the ad finishes, you should resume the previous playback speed.\n\nServer-side stitching\n---------------------\n\nFor\n[server-side stitching](/cast/docs/caf_receiver/ad_breaks#server-side_ad_stitching),\nthe ads are embedded so the server is expected to provide a single stream that\ncontains both the content and ads. In this case, playback can continue\nprogressing normally as the timeline contains the duration of the ad in addition\nto the content."]]