As a video publisher, you may want to prevent your viewers from seeking past your mid-roll ads. When a user seeks past an ad break, you can take them back to the start of that ad break, and then return them to their seek location after that ad break has completed. This feature is called "snapback."
As an example, see the diagram below. Your viewer is watching a video, and decides to seek from the 5-minute mark to the 15-minute mark. There is, however, an ad break at the 10-minute mark that you want them to watch before they can watch the content after it:
In order to show this ad break, take the following steps:
- Check if the user ran a seek that jumped past an unwatched ad break, and if so, take them back to the ad break.
- After the ad break completes, return them to their original seek.
In diagram form, that looks like this:
Here's how to implement this workflow in the Google Cast IMA SDK, as done in ReceiverSample.
Prevent a seek from leaving an ad break unwatched
Check if the user has run a seek that went past an unwatched ad break,
and if so, take them back to the ad break.
For Cast, use cast.receiver.MediaManager.onSeek
to detect when
the user seeks from the sender. This method is called after the seek
completes, so you can save the current video time as the desired
seek time. Then call your own snapback method to check if the previous
cuepoint has been played, and if not, jump back to its start to play it.
var Player = function(mediaElement) {
...
this.mediaManager_ = new cast.receiver.MediaManager(this.mediaElement_);
this.mediaManager_.onSeek = this.onSeek.bind(this);
...
}
Player.prototype.onSeek = function(event) {
var currentTime = event.data.currentTime;
this.snapback_(currentTime);
};
Player.prototype.snapback_ = function(time) {
var previousCuepoint =
this.streamManager_.previousCuePointForStreamTime(time);
var played = previousCuepoint.played;
if (played) {
this.seek_(time);
} else {
// Adding 0.1 to cuepoint start time because of bug where stream freezes
// when seeking to certain times in VOD streams.
this.seek_(previousCuepoint.start + 0.1);
this.seekToTimeAfterAdBreak_ = time;
}
};
Put the user back to their original seek
Now when the ad break completes, you can take the user to the time they initially tried to seek to:
Player.prototype.initStreamManager_ = function() {
...
this.streamManager_.addEventListener(
google.ima.dai.api.StreamEvent.Type.AD_BREAK_ENDED,
function(event) {
...
if (self.seekToTimeAfterAdBreak_ > 0) {
self.seek_(self.seekToTimeAfterAdBreak_);
self.seekToTimeAfterAdBreak_ = 0;
}
},
false);
...
}