動画パブリッシャーは、視聴者がミッドロール広告をスキップできないようにしたい場合があります。ユーザーが広告ブレークをシークして通り過ぎた場合、その広告ブレークの開始時点に戻って、その広告ブレークの再生が完了した後にシーク位置まで移動できます。この機能は「スナップバック」と呼ばれます。
たとえば、下の図をご覧ください。視聴者が動画を視聴していて、5 分のマークから 15 分のマークまでシークすることにしたとします。ただし、10 分のマークに広告ブレークがあり、その後のコンテンツを視聴するには、この広告ブレークを視聴する必要があります。
この広告ブレークを表示するには、次の手順を行います。
- ユーザーが未視聴の広告ブレークをスキップするシークを実行したかどうかを確認し、実行した場合は広告ブレークに戻します。
- 広告ブレークが完了したら、元のシーク位置に戻します。
図で表すと次のようになります。
AdvancedExample で行われているように、IMA DAI SDK でこのワークフローを実装する方法は次のとおりです。
シークによって広告ブレークが未視聴のままになるのを防ぐ
ユーザーが未視聴の広告ブレークを過ぎてシークしたかどうかを確認し、シークした場合は広告ブレークに戻します。iOS の高度な例では、ユーザーが UI を操作したときにシークを実行したことを検出します。シークの開始時間を保持して、シークで未再生の広告ブレークをスキップしたかどうかを確認します。ユーザーが動画コントロールを離したときに、現在の時間と最新の広告ブレークの時間を比較します。広告ブレークがシークの開始時間より後(ユーザーがスキップしたことを意味します)にあり、まだ再生されていない場合は、広告ブレークの開始時間までシークします。また、スナップバック フラグを設定して、広告ブレーク完了ハンドラで後で確認します。
- (IBAction)videoControlsTouchStarted:(id)sender {
self.seekStartTime = self.contentPlayer.currentTime;
}
- (IBAction)videoControlsTouchEnded:(id)sender {
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 your landing place.
[self.contentPlayer seekToTime:CMTimeMakeWithSeconds(lastCuepoint.startTime + 1, NSEC_PER_SEC)];
}
}
ユーザーを元のシーク位置に戻す
広告ブレーク終了ハンドラで、前のブレークがスナップバックの結果として再生されたかどうかを確認します。そうであれば、ユーザーが最初にシークしようとした場所に戻します(直前に再生された広告ブレークの途中ではない場合に限ります)。
- (void)streamManager:(IMAStreamManager *)streamManager didReceiveAdEvent:(IMAAdEvent *)event {
switch (event.type) {
case kIMAAdEvent_AD_BREAK_ENDED: {
if (self.snapbackMode) {
self.snapbackMode = NO;
if (CMTimeCompare(self.seekEndTime, self.contentPlayer.currentTime)) {
[self.contentPlayer seekToTime:self.seekEndTime];
}
}
break;
}
}
}