Règles relatives aux annonces

Le SDK IMA HTML5 est compatible avec les playlists d'annonces entièrement automatisées. Cette fonctionnalité insère des coupures publicitaires dans le contenu, comme spécifié dans Google Ad Manager lors du trafficking de vos annonces. Il simplifie également considérablement le code du lecteur vidéo pour prendre en charge les coupures publicitaires, y compris les annonces vidéo pré-roll, mid-roll et post-roll.

  • Lors de la création de l'AdsManager, un objet contentPlayback est transmis via l'appel getAdsManager. Cet objet doit avoir une propriété currentTime qui renvoie la position actuelle de la tête de lecture de la vidéo. Si vous utilisez un élément video HTML5 pour afficher votre contenu, il vous suffit de le transmettre au SDK. Cet objet permet de suivre la progression de la lecture du contenu afin que les coupures publicitaires soient automatiquement insérées aux moments spécifiés dans Ad Manager. Vous devez également indiquer au SDK que vous souhaitez qu'il gère l'état du contenu en votre nom.
    var adsRenderingSettings = new google.ima.AdsRenderingSettings();
    adsRenderingSettings.restoreCustomPlaybackStateOnAdBreakComplete = true;
    adsManager = adsManagerLoadedEvent.getAdsManager(
        videoContent, adsRenderingSettings); // See API reference for
        
        contentPlayback.
    
  • Pour vous assurer que les annonces vidéo post-roll sont bien lues, vous devez informer le SDK lorsque votre contenu est terminé. C'est un peu délicat, car dans certains cas, le SDK utilise votre lecteur vidéo pour lire les annonces. Vous devez donc vous assurer de ne l'indiquer au SDK que lorsque votre contenu est terminé, et non lorsque l'annonce est terminée. Pour ce faire, utilisez le code ci-dessous :
    var videoContent = document.getElementById('contentElement');
    var contentEndedListener = function() {adsLoader.contentComplete();};
    
    videoContent.addEventListener('ended', contentEndedListener);
    
    function onContentPauseRequested() {
      contentElement.removeEventListener('ended', contentEndedListener);
      ...
    }
    
    function onContentResumeRequested() {
      contentElement.addEventListener('ended', contentEndedListener);
      ...
    }
  • Les événements CONTENT_PAUSE_REQUESTED et CONTENT_RESUME_REQUESTED permettent de mettre en pause et de reprendre le contenu lors de la lecture des coupures publicitaires.
  • Si votre lecteur vidéo prend en charge le glisser-déposer et que la propriété temporelle actuelle du lecteur vidéo est mise à jour pendant que l'utilisateur le fait glisser, le SDK ne peut pas faire la différence entre le contenu qui progresse normalement et celui que l'utilisateur recherche. Vous devez utiliser un objet contentPlayback comme paramètre pour getAdsManager. Pour obtenir un exemple de ce cas d'utilisation, consultez la section Problèmes liés à la recherche.

Remarque:Lorsque la lecture du contenu est terminée ou que l'utilisateur a arrêté la lecture, veillez à appeler AdsLoader.contentComplete afin de signaler au SDK que le contenu est terminé. Le SDK lit ensuite la coupure publicitaire post-roll, le cas échéant. L'événement ALL_ADS_COMPLETED est déclenché lorsque TOUTES les coupures publicitaires ont été lues. En outre, notez que le suivi du contenu commence lorsque init() est appelé et que vous devez toujours appeler init() avant de lire le contenu.

Désactiver la lecture automatique des coupures publicitaires

Dans certains cas, vous pouvez empêcher le SDK de lire les coupures publicitaires tant que vous n'êtes pas prêt. Dans ce scénario, vous pouvez désactiver la lecture automatique des coupures publicitaires afin d'informer le SDK lorsque vous êtes prêt à diffuser une coupure publicitaire. Avec cette configuration, une fois que le SDK a chargé une coupure publicitaire, il déclenche un événement AD_BREAK_READY. Lorsque le lecteur est prêt à lancer la coupure publicitaire, vous pouvez appeler adsManager.start():

function requestAds() {}
  ...
  adsLoader.getSettings().setAutoPlayAdBreaks(false);
  ...
}

function onAdsManagerLoaded() {
  ...
  // For non-auto ad breaks, listen for ad break ready
  adsManager.addEventListener(
      google.ima.AdEvent.Type.AD_BREAK_READY,
      adBreakReadyHandler);
  ...
}

function adBreakReadyHandler() {
  // Once we're ready to play ads. To skip this ad break, simply return
  // from this handler without calling adsManager.start().
  adsManager.start();
}

Essayer

Vous pouvez voir une implémentation fonctionnelle ci-dessous.

Le problème avec la recherche

Si vous utilisez les règles relatives aux annonces, vous risquez de rencontrer des problèmes avec la recherche par clic-glisser. Plus précisément, lorsqu'un utilisateur clique et fait glisser pour rechercher une vidéo après plusieurs séries d'annonces mid-roll, il peut voir que deux ou plusieurs de ces séries d'annonces s'affichent les unes après les autres avant la reprise du contenu. Cela est dû à la mise à jour de la durée de la tête de lecture de la vidéo lorsque l'utilisateur effectue une recherche. Si le SDK interroge le moment actuel alors que l'utilisateur recherche une annonce, il peut considérer que l'annonce doit être lue. Lorsque le contenu reprend, l'annonce en question est diffusée, puis l'annonce la plus récente depuis la recherche. Pour obtenir une représentation visuelle de ce problème, consultez le schéma ci-dessous:

La méthode la plus simple consiste à enregistrer l'heure actuelle lorsque l'utilisateur commence la recherche et à signaler cette heure lorsque le SDK la demande jusqu'à ce que l'utilisateur reprenne la lecture normale. Pour obtenir une représentation visuelle de cette solution, consultez le schéma ci-dessous:

Cette solution vous permet d'ignorer correctement l'annonce vidéo mid-roll de 0:10 et de ne lire que l'annonce vidéo mid-roll de 0:20. Pour ce faire, utilisez un outil de suivi de la tête de lecture personnalisé, comme illustré ci-dessous. Le code ci-dessous contient des modifications (en gras) de ads.js dans l'exemple HTML5 avancé disponible sur notre page de téléchargement.

var Ads = function(application, videoPlayer) {
  ...
  this.currentTime = 0;
  setInterval(this.updateCurrentTime, 1000);
};

Ads.prototype.updateCurrentTime = function() {
  if (!this.videoPlayer_.contentPlayer.seeking) {
    this.currentTime = this.videoPlayer_.contentPlayer.currentTime;
  }
};

Ads.prototype.onAdsManagerLoaded_ = function(adsManagerLoadedEvent) {
  this.application_.log('Ads loaded.');
  this.adsManager_ = adsManagerLoadedEvent.getAdsManager(this);
  this.processAdsManager_(this.adsManager_);
};

Problèmes connus avec Safari pour mobile

Cette méthode devrait fonctionner sur toutes les plates-formes, à l'exception de Safari pour mobile. Sur Safari pour mobile, la propriété de recherche du tag vidéo n'est pas correctement implémentée (elle renvoie toujours la valeur "false"). Pour contourner ce problème, vous devez vérifier vous-même si l'utilisateur recherche dans la vidéo. Voici un exemple de code pour cette méthode. Là encore, les lignes en gras ci-dessous correspondent aux modifications apportées au code existant.

var Ads = function(application, videoPlayer) {
  ...
  this.currentTime = 0;
  setInterval(this.updateCurrentTime, 1000);
  this.seeking = false;
  this.seekCheckInterval = 1000;
  // You may need to adjust this value, depending on your platform
  this.seekThreshold = 100;
  this.previousTime = 0;
  setInterval(
      Application.bind(this, this.checkForSeeking),
      this.seekCheckInterval);
};

Ads.prototype.updateCurrentTime = function() {
  if (!this.seeking) {
    this.currentTime = this.videoPlayer_.contentPlayer.currentTime;
  }
};

Ads.prototype.checkForSeeking = function() {
  var currentTime = this.videoPlayer_.contentPlayer.currentTime;
  // How much time has passed since you last ran this method, in milliseconds
  var diff = (currentTime - this.previousTime) * 1000;
  // If that difference is greater than the time since you last ran this method,
  // plus the threshold, the user was seeking
  if (Math.abs(diff)  > this.interval + this.threshold) {
    this.seeking = true;
  } else {
    this.seeking = false;
  }
  // Grab the current video time again to make up for time spent in this method
  previousTime = this.videoPlayer_.contentPlayer.currentTime;
};

Ads.prototype.onAdsManagerLoaded_ = function(adsManagerLoadedEvent) {
  this.application_.log('Ads loaded.');
  this.adsManager_ = adsManagerLoadedEvent.getAdsManager(this);
  this.processAdsManager_(this.adsManager_);
};

Avec ces modifications, le SDK utilise désormais la propriété currentTime de votre objet Ads pour déterminer quand lire les coupures publicitaires, et non la propriété currentTime du lecteur vidéo de contenu.