Le SDK du récepteur Android TV est compatible de façon native avec les coupures publicitaires et les annonces associées dans un flux multimédia donné.
Pour en savoir plus sur leur fonctionnement, consultez la page Présentation des coupures publicitaires Web Receiver.
Gérer la charge avec les coupures publicitaires
Dans votre application Android TV, les coupures sont incluses dans MediaLoadRequestData
.
Les requêtes de chargement peuvent être traitées normalement, et les éléments AdBreakClipInfo
et 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 TaskonLoad(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; }); } }
Mise à jour des coupures publicitaires...
Lorsque des annonces commencent à être diffusées, mettez à jour le AdBreakStatus
sur le 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 les coupures publicitaires de manière dynamique 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'omission d'une annonce
Lorsqu'une coupure publicitaire est en cours de lecture, les expéditeurs voient s'afficher un bouton permettant d'ignorer l'extrait actuel de la coupure publicitaire s'il est désactivable. Pour permettre à un utilisateur d'ignorer un extrait de coupure 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{ // Skip your ad ... return Tasks.forResult (null) } } val mediaManager = CastReceiverContext.getInstance().mediaManager mediaManager.setMediaCommandCallback(MyMediaCommandCallback())
public class MyMediaCommandCallback extends MediaCommandCallback { @Override public TaskonSkipAd(RequestData requestData) { // Skip your ad ... return Tasks.forResult(null); } } MediaManager mediaManager = CastReceiverContext.getInstance().getMediaManager(); mediaManager.setMediaCommandCallback(new MyMediaCommandCallback());
Assemblage côté client
L'assemblage côté client consiste à ne pas intégrer d'annonces dans le flux. Pour Cast Connect, en plus de mettre à jour AdBreakStatus
sur MediaStatusModifier
, vous devez définir la vitesse de lecture sur 0 sur PlaybackStateCompat
afin que les expéditeurs sachent qu'il faut figer la progression de la chronologie 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, la vitesse de lecture précédente doit reprendre.
Assemblage côté serveur
Pour l'assemblage côté serveur, les annonces sont intégrées. Le serveur doit donc fournir un seul flux contenant à la fois le contenu et les annonces. Dans ce cas, la lecture peut continuer à progresser normalement, car la chronologie contient la durée de l'annonce en plus du contenu.