Coupures publicitaires
Restez organisé à l'aide des collections
Enregistrez et classez les contenus selon vos préférences.
Le SDK Android TV Receiver est compatible en mode natif avec les pauses publicitaires et les annonces associées dans un flux multimédia donné.
Pour en savoir plus sur le fonctionnement des pauses publicitaires, consultez Présentation des pauses publicitaires Web Receiver.
Gérer la charge avec les coupures publicitaires
Dans l'application Android TV, les pauses sont incluses dans MediaLoadRequestData
.
Les demandes de chargement peuvent être traitées normalement, et les AdBreakClipInfo
et les AdBreakInfo
peuvent être récupérés à partir de 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;
});
}
}
Modifier les coupures publicitaires
Lorsque les annonces commencent à être diffusées, mettez à jour AdBreakStatus
sur MediaStatusModifier
pour indiquer que votre application a commencé à diffuser des annonces :
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);
Vous pouvez également modifier dynamiquement les pauses publicitaires après le chargement d'un élément :
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});
Activer et gérer l'option "Ignorer l'annonce"
Lorsqu'une série d'annonces est en cours de lecture, les émetteurs affichent un bouton permettant d'ignorer le clip de série d'annonces en cours s'il peut être ignoré. Pour permettre à un utilisateur d'ignorer un clip d'emplacement publicitaire, utilisez MediaStatusModifier
pour ajouter la commande multimédia COMMAND_SKIP_AD
:
mMediaManager.getMediaStatusModifier().setMediaCommandSupported(MediaStatus.COMMAND_SKIP_AD, true)
mMediaManager.getMediaStatusModifier().setMediaCommandSupported(MediaStatus.COMMAND_SKIP_AD, true);
Pour gérer la commande SKIP_AD
, implémentez le rappel onSkipAd
dans vos 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());
Assemblage côté client
Dans le cas de l'assemblage côté client, les annonces ne sont pas intégrées au flux. Pour Cast Connect, en plus de mettre à jour le AdBreakStatus
sur le MediaStatusModifier
, vous devez définir la vitesse de lecture sur 0 sur le PlaybackStateCompat
afin que les expéditeurs sachent qu'ils doivent figer la progression de la timeline du contenu.
// 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());
Une fois l'annonce terminée, vous devez rétablir la vitesse de lecture précédente.
Assemblage côté serveur
Pour l'assemblage côté serveur, les annonces sont intégrées. Le serveur est donc censé fournir un flux unique contenant à la fois le contenu et les annonces. Dans ce cas, la lecture peut se poursuivre normalement, car la timeline contient la durée de l'annonce en plus de celle du contenu.
Sauf indication contraire, le contenu de cette page est régi par une licence Creative Commons Attribution 4.0, et les échantillons de code sont régis par une licence Apache 2.0. Pour en savoir plus, consultez les Règles du site Google Developers. Java est une marque déposée d'Oracle et/ou de ses sociétés affiliées.
Dernière mise à jour le 2025/09/05 (UTC).
[[["Facile à comprendre","easyToUnderstand","thumb-up"],["J'ai pu résoudre mon problème","solvedMyProblem","thumb-up"],["Autre","otherUp","thumb-up"]],[["Il n'y a pas l'information dont j'ai besoin","missingTheInformationINeed","thumb-down"],["Trop compliqué/Trop d'étapes","tooComplicatedTooManySteps","thumb-down"],["Obsolète","outOfDate","thumb-down"],["Problème de traduction","translationIssue","thumb-down"],["Mauvais exemple/Erreur de code","samplesCodeIssue","thumb-down"],["Autre","otherDown","thumb-down"]],["Dernière mise à jour le 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."]]