Cómo volver a una pausa publicitaria omitida

Selecciona la plataforma: HTML5 Android iOS tvOS Roku

Como publicador de videos, es posible que quieras evitar que los usuarios adelanten tus anuncios durante el video. Cuando un usuario busca más allá de una pausa publicitaria, puedes llevarlo de regreso al inicio de esa pausa y, luego, regresarlo a su ubicación de búsqueda una vez que se haya completado la pausa. Esta función se llama “recuperación”.

Como ejemplo, consulta el siguiente diagrama. El usuario está mirando un video y decide adelantar desde el minuto 5 hasta el minuto 15. Sin embargo, hay una pausa publicitaria a los 10 minutos que quieres que miren antes de poder ver el contenido después de ella:

Para mostrar esta pausa publicitaria, sigue estos pasos:

  1. Comprueba si el usuario realizó una búsqueda que omitió una pausa publicitaria sin mirar y, si es así, llévalo de regreso a la pausa publicitaria.
  2. Una vez que finalice la pausa publicitaria, regrésalos a su búsqueda original.

En forma de diagrama, se ve de la siguiente manera:

A continuación, se explica cómo implementar este flujo de trabajo en el SDK de DAI de IMA, como se hace en AdvancedExample.

Evita que se omitan los anuncios que no se miraron

Si un usuario intenta omitir una pausa publicitaria, el reproductor debe detectar el salto y forzar la reproducción al inicio de esa pausa publicitaria específica. Para evitar que se omitan los anuncios que no se miraron, haz lo siguiente:

  1. Cuando el usuario comience a interactuar con la barra de búsqueda, registra su tiempo de reproducción actual.
  2. Después de que el usuario termine de buscar un momento diferente en la transmisión, identifica la pausa publicitaria más reciente que se encuentre antes de ese momento.
  3. Si la pausa publicitaria comienza después de la hora de inicio registrada, lo que indica que se omitió, y aún no se reprodujo, busca el reproductor hasta el inicio de la pausa publicitaria.
  4. Habilita una marca snapbackMode para hacer un seguimiento de que se forzó esta pausa publicitaria.

Objective-C

- (IBAction)videoControlsTouchStarted:(id)sender {
  [NSObject cancelPreviousPerformRequestsWithTarget:self
                                            selector:@selector(hideFullscreenControls)
                                              object:self];

  self.currentlySeeking = YES;
  self.seekStartTime = self.contentPlayer.currentTime;
}

- (IBAction)videoControlsTouchEnded:(id)sender {
  if (self.fullscreen) {
    [self startHideControlsTimer];
  }
  self.currentlySeeking = NO;
  if (!self.adPlaying) {
    self.seekEndTime = CMTimeMake(self.progressBar.value, 1);
    IMACuepoint *lastCuepoint =
        [self.streamManager previousCuepointForStreamTime:CMTimeGetSeconds(self.seekEndTime)];
    if (!lastCuepoint.played && (lastCuepoint.startTime > CMTimeGetSeconds(self.seekStartTime))) {
      self.snapbackMode = YES;
      // Add 1 to the seek time to get the keyframe at the start of the ad to be our landing
      // place.
      [self.contentPlayer
          seekToTime:CMTimeMakeWithSeconds(lastCuepoint.startTime + 1, NSEC_PER_SEC)];
    }
  }
}

Swift

@IBAction func progressBarTouchStarted(_ sender: UISlider) {
  guard !isAdPlaying else { return }
  currentlySeeking = true
  seekStartTime = contentPlayer.currentTime().seconds
}

// MARK: Snapback Logic
@IBAction func progressBarTouchEnded(_ sender: UISlider) {
  guard !isAdPlaying else { return }
  if isFullScreen {
    startHideControlsTimer()
  }
  currentlySeeking = false
  seekEndTime = Float64(sender.value)

  guard let streamManager else { return }

  if let lastCuepoint = streamManager.previousCuepoint(forStreamTime: seekEndTime) {
    if !lastCuepoint.isPlayed, lastCuepoint.startTime > seekStartTime {
      logMessage(
        "Snapback to \(String(format: "%.2f", lastCuepoint.startTime)) from \(String(format: "%.2f", seekEndTime))"
      )
      snapbackMode = true
      contentPlayer.seek(
        to: CMTime(seconds: Double(sender.value), preferredTimescale: 1000))
    }
  }
}

Reanuda la búsqueda original

Una vez que finaliza la reproducción de la pausa publicitaria obligatoria, el reproductor lleva al usuario al punto de contenido deseado.

Para reanudar la búsqueda original del usuario, haz lo siguiente:

  1. Escucha el evento AD_BREAK_ENDED en tu administrador de transmisiones.

  2. Verifica si la marca snapbackMode está activa para asegurarte de que este salto se produzca después de una visualización forzada del anuncio.

  3. Si está activo, busca el reproductor en el tiempo de destino guardado para que el usuario vuelva a la marca de tiempo deseada.

En el siguiente ejemplo, se espera a que finalice una pausa publicitaria y se regresa al usuario a la búsqueda original:

Objective-C

case kIMAAdEvent_AD_BREAK_ENDED: {
  [self logMessage:@"Ad break ended"];
  self.adPlaying = NO;
  if (self.snapbackMode) {
    self.snapbackMode = NO;
    if (CMTimeCompare(self.seekEndTime, self.contentPlayer.currentTime)) {
      [self.contentPlayer seekToTime:self.seekEndTime];
    }
  }
  break;
}

Swift

case .AD_BREAK_ENDED:
  logMessage("Ad break ended")
  isAdPlaying = false
  progressBar.isUserInteractionEnabled = true
  if snapbackMode {
    snapbackMode = false
    if contentPlayer.currentTime().seconds < seekEndTime {
      contentPlayer.seek(to: CMTime(seconds: Double(seekEndTime), preferredTimescale: 1000))
    }
  } else if pendingBookmarkSeek, let time = bookmarkStreamTime {
    logMessage(String(format: "AD_BREAK_ENDED: Seeking to bookmark streamTime: %.2f", time))
    imaVideoDisplay.seekStream(toTime: time)
    pendingBookmarkSeek = false
    bookmarkStreamTime = nil
  }
  updatePlayHeadState(isPlaying: self.isContentPlaying)