スナップバック

動画のパブリッシャーは、視聴者が ミッドロール広告をスキップできますユーザーがミッドロール挿入点を超えてシークすると、 その広告ブレークの先頭に戻って そのミッドロール挿入点が完了した後に、シークする位置にユーザーが移動します。この 「スナップバック」と呼ばれます。

たとえば、次の図をご覧ください。視聴者が動画を視聴している 5 分の時点から 15 分の時点までシークします。 ただし、希望する 10 分の時点でミッドロール挿入点を ユーザーが次のコンテンツを視聴する前に、次の動画を視聴するようユーザーに促すことができます。

このミッドロール挿入点を表示する方法は次のとおりです。

  1. ユーザーがシークを実行して、視聴していないミッドロール挿入点を通過したかどうかを確認します。 その場合はミッドロール挿入点に戻ります
  2. ミッドロール挿入点が完了したら、元の移動に戻ります。

図形式では、次のようになります。

AdvancedExample で説明されているように、IMA DAI SDK を使用してスナップバックを実装する方法は次のとおりです。

シークで広告ブレークが再生されないままにならないようにする

ユーザーが再生していない広告ブレークを通過したシークをユーザーが実行したかどうかを確認します。 その場合はミッドロール挿入点に戻ります tvOS の高度な例では、ユーザーがシークを実行したことを通知するデリゲート メソッドを持つ AVPlayerViewController を利用しています。シークの開始時間が前のミッドロール挿入点よりも前である場合(つまり、 その挿入点がまだ再生されていない場合、 広告ブレークの先頭までシークします。また、Cloud Storage バケットの 最初に ad-break-did-end ハンドラで後でチェックするシークをリクエストしました。

- (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];
    }
  }
}

ユーザーを元の検索モードに戻す

イベント デリゲートで AD_BREAK_ENDED ケースを変更して、 スナップバックの結果として前の広告ブレークが再生された。


- (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;
  }
}