Jako wydawca treści wideo możesz chcieć uniemożliwić widzom przewijanie reklam w trakcie filmu. Gdy użytkownik przewinie przerwę na reklamę, możesz cofnąć go do początku tej przerwy, a następnie po jej zakończeniu przywrócić do miejsca przewinięcia. Ta funkcja nazywa się „cofnięcie do przerwy na reklamę”.
Przykład znajdziesz na diagramie poniżej. Widz ogląda film i postanawia przewinąć go z 5. minuty do 15. W 10. minucie jest jednak przerwa na reklamę, którą chcesz, aby obejrzał, zanim będzie mógł oglądać dalszą część filmu:

Aby wyświetlić tę przerwę na reklamę, wykonaj następujące czynności:
- Sprawdź, czy użytkownik przewinął nieobejrzaną przerwę na reklamę, a jeśli tak, cofnij go do tej przerwy.
- Po zakończeniu przerwy na reklamę przywróć użytkownika do miejsca przewinięcia.
Na diagramie wygląda to tak:

Oto jak zaimplementować ten proces w pakiecie IMA DAI SDK, tak jak w AdvancedExample.
Blokowanie pomijania nieobejrzanych reklam
Jeśli użytkownik spróbuje pominąć przerwę na reklamę, odtwarzacz musi wykryć przewinięcie i wymusić odtwarzanie od początku tej przerwy. Aby zablokować pomijanie nieobejrzanych reklam:
- Gdy użytkownik zacznie korzystać z paska przewijania, zapisz bieżący czas odtwarzania.
- Gdy użytkownik skończy przewijać do innego momentu w strumieniu, znajdź ostatnią przerwę na reklamę przed tym momentem.
- Jeśli przerwa na reklamę zaczyna się po zapisanym czasie rozpoczęcia, co oznacza pominięcie, i nie została jeszcze odtworzona, przewiń odtwarzacz do początku przerwy na reklamę.
- 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))
}
}
}
Wznawianie pierwotnego przewijania
Po zakończeniu wymuszonej przerwy na reklamę odtwarzacz przenosi użytkownika do wybranego momentu treści.
Aby wznowić pierwotne przewijanie użytkownika:
Nasłuchuj zdarzenia
AD_BREAK_ENDEDw menedżerze strumienia.Sprawdź, czy flaga
snapbackModejest aktywna, aby upewnić się, że to przewinięcie nastąpiło po wymuszonym wyświetleniu reklamy.Jeśli flaga jest aktywna, przewiń odtwarzacz do zapisanego czasu docelowego, aby przywrócić użytkownika do wybranej sygnatury czasowej.
Poniższy przykład nasłuchuje zakończenia przerwy na reklamę i przywraca użytkownika do pierwotnego przewijania:
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)