動画パブリッシャーは、視聴者がミッドロール広告をスキップできないようにしたい場合があります。ユーザーが広告ブレークをシークして通り過ぎた場合、その広告ブレークの開始時点に戻って、その広告ブレークの再生が完了した後にシーク位置まで移動できます。この機能は「スナップバック」と呼ばれます。
たとえば、下の図をご覧ください。視聴者が動画を視聴していて、5 分のマークから 15 分のマークまでシークすることにしたとします。ただし、10 分のマークに広告ブレークがあり、その後のコンテンツを視聴するには、この広告ブレークを視聴する必要があります。
この広告ブレークを表示するには、次の手順を行います。
- ユーザーが未視聴の広告ブレークをスキップするシークを実行したかどうかを確認し、実行した場合は広告ブレークに戻します。
- 広告ブレークが完了したら、元のシーク位置に戻します。
図で表すと次のようになります。
AdvancedExample で行われているように、IMA DAI SDK でこのワークフローを実装する方法は次のとおりです。
シークによって広告ブレークが未視聴のままになるのを防ぐ
ユーザーが未視聴の広告ブレークを過ぎてシークしたかどうかを確認し、シークした場合は広告ブレークに戻します。Android SDK では、PlayerControl
オブジェクトを使用してシークを検出します。ユーザーがシークしたときに、SampleAdsWrapper
によって実装された SampleHlsVideoPlayerCallback
の onSeek()
メソッドをトリガーします。以下のメソッドは、ユーザーのシーク時間より前のキューポイントをチェックします。再生されていない場合は、最初のシークポイントではなく、その広告ブレークの先頭にシークし、そのシークポイントを snapBackTime
に保存します。
@Override
public void onSeek(int timeMillis) {
double timeToSeek = timeMillis;
if (streamManager != null) {
CuePoint cuePoint =
streamManager.getPreviousCuePointForStreamTime(timeMillis / 1000);
if (cuePoint != null && !cuePoint.isPlayed()) {
snapBackTime = timeToSeek / 1000.0; // Update snapback time.
// Missed cue point, so snap back to the beginning of cue point.
timeToSeek = cuePoint.getStartTime() * 1000;
videoPlayer.seek(Math.round(timeToSeek));
videoPlayer.setCanSeek(false);
return;
}
}
videoPlayer.seek(Math.round(timeToSeek));
}
ユーザーを元のシーク位置に戻す
onAdBreakEnded
イベントを受け取ったら、snapBackTime
が設定されているかどうかを確認します。その場合は、ストリームのその時点にユーザーを移動させます。これは、ユーザーが視聴したばかりの広告ブレークがスナップバックの結果であるためです。
@Override
public void onAdBreakEnded() {
// Re-enable player controls.
videoPlayer.setCanSeek(true);
videoPlayer.enableControls(true);
if (snapBackTime > 0) {
videoPlayer.seek(Math.round(snapBackTime * 1000));
}
snapBackTime = 0;
}