מוציאים לאור של סרטונים יכולים לרצות למנוע מהצופים לדלג על מודעות באמצע הסרטון. כשמשתמש מדלג על הפסקה למודעה, אפשר להחזיר אותו לתחילת ההפסקה למודעה הזו, ואז להחזיר אותו למיקום הדילוג אחרי שההפסקה למודעה מסתיימת. התכונה הזו נקראת 'חזרה מהירה'.
לדוגמה, ראו את התרשים הבא. הצופה צופה בסרטון ומחליט לדלג מנקודת הזמן של 5 דקות לנקודת הזמן של 15 דקות. עם זאת, יש הפסקה למודעה אחרי 10 דקות צפייה, ואתם רוצים שהצופים יצפו בה לפני שהם יוכלו לצפות בתוכן שאחריה:

כדי להציג את ההפסקה למודעה הזו, פועלים לפי השלבים הבאים:
- בודקים אם המשתמש דילג על הפסקה למודעה שלא צפה בה, ואם כן, מחזירים אותו להפסקה למודעה.
- אחרי שהפסקה למודעה מסתיימת, מחזירים אותם למיקום המקורי בסרטון.
בתרשים, זה נראה כך:

כך מטמיעים את תהליך העבודה הזה ב-IMA DAI SDK, כמו שנעשה ב-AdvancedExample.
מניעת דילוג על מודעות שלא נצפו
אם משתמש מנסה לדלג על הפסקה למודעה, נגן המדיה צריך לזהות את הדילוג ולהכריח את הפעלת הסרטון מתחילת ההפסקה למודעה הספציפית הזו. כדי למנוע דילוג על מודעות שלא נצפו:
- כשמשתמש מתחיל אינטראקציה עם סרגל הניווט, צריך לתעד את זמן ההפעלה הנוכחי שלו.
- אחרי שהמשתמש מסיים את ההזזה לזמן אחר בשידור, צריך לזהות את ההפסקה למודעה האחרונה שהייתה לפני הזמן הזה.
- אם ההפסקה לפרסומות מתחילה אחרי שעת ההתחלה המתועדת, מה שמצביע על דילוג, ועדיין לא הופעלה, צריך להעביר את נגן הווידאו לתחילת ההפסקה לפרסומות.
- מפעילים את הדגל
snapbackModeכדי לעקוב אחרי ההפסקה למודעה שנכפתה.
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))
}
}
}
המשך החיפוש המקורי
אחרי שהפסקה למודעה שמוצגת בכפייה מסתיימת, הנגן מעביר את המשתמש לנקודה הרצויה בתוכן.
כדי להמשיך את החיפוש המקורי של המשתמש:
מחפשים את האירוע
AD_BREAK_ENDEDבכלי לניהול השידור.בודקים אם הדגל
snapbackModeפעיל כדי לוודא שהמעבר הזה יקרה אחרי צפייה במודעה שנכפתה על המשתמש.אם ההגדרה פעילה, המערכת תעביר את המשתמש למיקום שבו הוא הפסיק לצפות בסרטון, כדי להחזיר אותו לחותמת הזמן הרצויה.
בדוגמה הבאה, המערכת מאזינה לסיום הפסקת המודעה ומחזירה את המשתמש למיקום המקורי בסרטון:
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)