Powrót do pominiętej przerwy na reklamę

Wybierz platformę: HTML5 Android iOS tvOS Roku

Jako wydawca filmów możesz chcieć uniemożliwić widzom przewijanie reklam w trakcie filmu. Gdy użytkownik przewinie przerwę na reklamę, możesz cofnąć odtwarzanie do początku tej przerwy, a następnie po jej zakończeniu przywrócić miejsce przewinięcia. Ta funkcja nazywa się „snapback”.

Przykład znajdziesz na diagramie poniżej. Widz ogląda film i postanawia przewinąć go z 5 minuty do 15 minuty. W 10 minucie filmu znajduje się jednak przerwa na reklamę, którą użytkownicy muszą obejrzeć, zanim będą mogli oglądać dalszą część treści:

Aby wyświetlić tę przerwę na reklamy, wykonaj te czynności:

  1. Sprawdź, czy użytkownik przewinął nieobejrzaną przerwę na reklamę, a jeśli tak, cofnij odtwarzanie do tej przerwy.
  2. Po zakończeniu przerwy na reklamę odtwarzanie jest wznawiane od miejsca przewinięcia.

W formie diagramu wygląda to tak:

Oto jak zaimplementować ten przepływ pracy w pakiecie IMA DAI SDK, tak jak w przypadku AdvancedExample.

Zapobieganie pomijaniu nieobejrzanych reklam

Jeśli użytkownik spróbuje pominąć przerwę na reklamę, odtwarzacz musi wykryć przeskok i wymusić odtwarzanie od początku tej przerwy. Aby uniemożliwić pomijanie nieobejrzanych reklam:

  1. Gdy użytkownik zacznie wchodzić w interakcję z paskiem przewijania, zapisz bieżący czas odtwarzania.
  2. Gdy użytkownik zakończy przewijanie do innego momentu w strumieniu, znajdź ostatnią przerwę na reklamy, która występuje przed tym momentem.
  3. Jeśli przerwa na reklamę rozpoczyna się po zarejestrowanym czasie rozpoczęcia, co oznacza pominięcie, i nie została jeszcze odtworzona, przewiń odtwarzacz do początku przerwy na reklamę.
  4. Włącz flagę snapbackMode, aby śledzić, czy ta przerwa na reklamę została wymuszona.

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))
    }
  }
}

Wznów oryginalne przewijanie

Po zakończeniu odtwarzania wymuszonej przerwy na reklamę odtwarzacz przenosi użytkownika do wybranego punktu treści.

Aby wznowić oryginalne przewijanie użytkownika, wykonaj te czynności:

  1. W menedżerze strumieni poszukaj zdarzenia AD_BREAK_ENDED.

  2. Sprawdź, czy flaga snapbackMode jest aktywna, aby upewnić się, że przejście nastąpi po wymuszonym wyświetleniu reklamy.

  3. Jeśli ta opcja jest aktywna, odtwarzacz zostanie przewinięty do zapisanego czasu docelowego, aby użytkownik mógł wrócić do zamierzonej sygnatury czasowej.

Poniższy przykład nasłuchuje zakończenia przerwy na reklamę i przywraca użytkownika do pierwotnego miejsca odtwarzania:

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)