Przerwy na reklamy
Zadbaj o dobrą organizację dzięki kolekcji
Zapisuj i kategoryzuj treści zgodnie ze swoimi preferencjami.
Pakiet SDK odbiornika Android TV natywnie obsługuje przerwy na reklamy i reklamy towarzyszące w danym strumieniu multimediów.
Więcej informacji o działaniu przerw na reklamy znajdziesz w tym artykule.
Obsługa obciążenia za pomocą przerw na reklamy
W aplikacji Android TV przerwy są uwzględnione w MediaLoadRequestData
.
Żądania wczytania mogą być przetwarzane normalnie, a wartości AdBreakClipInfo
i AdBreakInfo
można pobrać z 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;
});
}
}
Aktualizowanie przerw na reklamy
Gdy reklamy zaczną się odtwarzać, zaktualizuj parametr
AdBreakStatus
w parametrze
MediaStatusModifier
, aby poinformować, że aplikacja rozpoczęła odtwarzanie reklam:
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);
Możesz też dynamicznie modyfikować przerwy na reklamy po załadowaniu elementu:
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});
Włączanie i obsługa pomijania reklam
Gdy odtwarzana jest przerwa na reklamy, nadawcy wyświetlają przycisk pomijania bieżącego klipu z przerwą na reklamy, jeśli można go pominąć. Aby umożliwić użytkownikowi pomijanie klipu z przerwą na reklamy, użyj elementu MediaStatusModifier
, aby dodać polecenie multimedialne COMMAND_SKIP_AD
:
mMediaManager.getMediaStatusModifier().setMediaCommandSupported(MediaStatus.COMMAND_SKIP_AD, true)
mMediaManager.getMediaStatusModifier().setMediaCommandSupported(MediaStatus.COMMAND_SKIP_AD, true);
Aby obsłużyć polecenie SKIP_AD
, zaimplementuj wywołanie zwrotne onSkipAd
w 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());
Łączenie po stronie klienta
Łączenie po stronie klienta polega na tym, że reklamy nie są osadzone w strumieniu. W przypadku Cast Connect oprócz zaktualizowania
AdBreakStatus
w MediaStatusModifier
musisz ustawić szybkość odtwarzania na 0 w PlaybackStateCompat
, aby nadawcy wiedzieli, że należy zatrzymać postęp osi czasu treści.
// 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());
Po zakończeniu reklamy należy przywrócić poprzednią szybkość odtwarzania.
Łączenie po stronie serwera
W przypadku łączenia po stronie serwera reklamy są osadzane w taki sposób, że serwer ma dostarczać jeden strumień zawierający zarówno treści, jak i reklamy. W takim przypadku odtwarzanie może przebiegać normalnie, ponieważ oś czasu zawiera czas trwania reklamy oraz treści.
O ile nie stwierdzono inaczej, treść tej strony jest objęta licencją Creative Commons – uznanie autorstwa 4.0, a fragmenty kodu są dostępne na licencji Apache 2.0. Szczegółowe informacje na ten temat zawierają zasady dotyczące witryny Google Developers. Java jest zastrzeżonym znakiem towarowym firmy Oracle i jej podmiotów stowarzyszonych.
Ostatnia aktualizacja: 2025-09-05 UTC.
[[["Łatwo zrozumieć","easyToUnderstand","thumb-up"],["Rozwiązało to mój problem","solvedMyProblem","thumb-up"],["Inne","otherUp","thumb-up"]],[["Brak potrzebnych mi informacji","missingTheInformationINeed","thumb-down"],["Zbyt skomplikowane / zbyt wiele czynności do wykonania","tooComplicatedTooManySteps","thumb-down"],["Nieaktualne treści","outOfDate","thumb-down"],["Problem z tłumaczeniem","translationIssue","thumb-down"],["Problem z przykładami/kodem","samplesCodeIssue","thumb-down"],["Inne","otherDown","thumb-down"]],["Ostatnia aktualizacja: 2025-09-05 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."]]