بصفتك ناشر فيديوهات، قد تريد منع المشاهدين من تخطّي "الإعلانات أثناء التشغيل". عندما يتخطّى المستخدم فاصل إعلاني، يمكنك إعادته إلى بداية هذا الفاصل، ثم إعادته إلى موضع التقديم السريع بعد انتهاء الفاصل. تُعرف هذه الميزة باسم "الرجوع السريع".
اطّلِع على الرسم البياني أدناه كمثال. يشاهد المستخدم فيديو ويقرّر الانتقال من الدقيقة 5 إلى الدقيقة 15. ومع ذلك، هناك فاصل إعلاني عند الدقيقة 10 تريد أن يشاهده المستخدمون قبل أن يتمكّنوا من مشاهدة المحتوى بعده:

لعرض فاصل إعلاني، اتّبِع الخطوات التالية:
- تحقَّق مما إذا كان المستخدم قد نفّذ عملية بحث تجاوزت فاصل إعلاني لم تتم مشاهدته، وإذا كان الأمر كذلك، أعِد المستخدم إلى الفاصل الإعلاني.
- بعد انتهاء فاصل الإعلانات، أعِد المستخدمين إلى موضع البحث الأصلي.
في شكل رسم بياني، يبدو ذلك على النحو التالي:

إليك كيفية تنفيذ سير العمل هذا في حزمة تطوير البرامج (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)