

Here's how to implement this workflow in the tvOS IMA SDK, as done in AdvancedExample.
Prevent a seek from leaving an ad break unwatched
Check if the user has run a seek that went past an unwatched ad break,
and if so, take them back to the ad break.
The tvOS advanced example takes advantage of the AVPlayerViewController
,
which has a delegate method to tell you that the user has run a seek.
If the seek start time comes before the previous ad break (meaning
the user has jumped past it) and that break hasn't yet been played,
seek them back to the start of the ad break. Also, record the start time of the
initially requested seek to check later in your ad-break-did-end
handler:
- (void)playerViewController:(AVPlayerViewController *)playerViewController willResumePlaybackAfterUserNavigatedFromTime:(CMTime)oldTime toTime:(CMTime)targetTime { if (self.streamManager) { IMACuepoint *prevCuepoint = [self.streamManager previousCuepointForStreamTime:CMTimeGetSeconds(targetTime)]; if (prevCuepoint && !prevCuepoint.isPlayed && oldTime < prevCuepoint.startTime) { self.userSeekTime = CMTimeGetSeconds(targetTime); [self.playerViewController.player seekToTime:CMTimeMakeWithSeconds( prevCuepoint.startTime, NSEC_PER_SEC) toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero]; } } }
Put the user back to their original seek
In your event delegate, modify the AD_BREAK_ENDED
case to check if the
previous ad break was played as the result of snapback.
- (void)streamManager:(IMAStreamManager *)streamManager didReceiveAdEvent:(IMAAdEvent *)event { NSLog(@"StreamManager event (%@).", event.typeString); switch (event.type) { // Your other events go here as normal. case kIMAAdEvent_AD_BREAK_ENDED: { if (self.userSeekTime > 0) { self.playerViewController.player seekToTime:CMTimeMakeWithSeconds(self.userSeekTime, NSEC_PER_SEC) toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero]; self.userSeekTime = 0; // existing handling for AD_BREAK_ENDED goes here. break; } // And so on for other events. default: break; } }