Build a custom Video Player with Ads on tvOS
(Part 8 of 8)
This is the eighth and final part of our tvOS Bootcamp. Please check out the previous pages to know more about this series.
In this part, we will learn how to customize the player a bit in order to have more granular control and to add new features to it. Some of these features could be Ad integration in the stream, ability to play a list of items in a queue to play all the episode of a show, observe playback finish event to close player when a video finished playing etc.
Let’s start by creating a new class
PlayerViewController by subclassing
The most basic implementation looks like this. Here we are simply using
viewDidAppear method as a starting point for playback. Reason being, it ensures that the view hierarchy is correctly initialized before playback starts.
We maintain a boolean to know whether player is initialized or not since
viewDidAppear may be called more than once.
Once we have this class ready. We can go ahead and put a helper method in
DetailViewController to play any video:
Play list of items in a queue (for Series):
Now that we are able to play the video. Next part is to modify this player to support a queue of videos when we are playing a Series. Let’s assume the
rail property contains all the episodes of a series.
To achieve this, we need to modify our
In this code, we are using a switch to determine the type of asset, if it is a movie, we create an instance of
AVPlayer, if it is a series, we create an instance of
AVQueuePlayer which is also a subclass of
One thing we are making sure is that the first video should always be the one user clicked and rest of the videos should be played after it.
We now have a video player which can play all the videos one after another if
asset.type == .series.
Dismiss player when video ends:
Next feature we would like to target is to have an ability to dismiss playback when player finished playing all the items.
For this, we need to create an observer on the player. We do this in
setupPlayer() method which is called from
This observer will notify whenever an instance of
AVPlayerItem stops playing. The important thing to note here is that for Series, we should always check if the item which finished playing was the last item in the list.
Now we have successfully added capability to finish playback whenever an item finished playing.
Play ads after some intervals:
In order to play ads in the player. We first need to add ability in our
PlayerViewController to play a URL instead of
Relevant code would look something like this:
Here we have created a property named
url, which could be used to specify a video url of the advert.
viewDidAppear, we have added a check if asset exits, if yes, we proceed with the normal flow using
startAssetPlayback(), if not, we consider this player to play an advert and start playback using method
startAdvertPlayback() method simply creates an instance of
AVPlayerItem using the url and plays it.
Since we are going to create another instance of
PlayerViewController and present on top of the current player, the next step is to simply override
viewWillDisappear to pause playback when advert starts and resume playback when advert finishes using
viewWillAppear. It looks like this:
Final part of ads playback is to add markers on the seek bar to show where a user can expect some ads.
To do this, we need to modify
createPlayerItem method and add some time ranges into
interstitialTimeRanges property of player item.
In above example, we are adding 10 ad slots in the seek bar after every 60 seconds skipping first one.
Whenever player reaches the specified time range. It is going to notify us using a delegate method we need to implement.
Here we are simply creating an instance of
PlayerViewController, specifying the advertisement url and presenting on top of the current player.
kAdvertUrl is simply added on top of the file like this:
Now that we have completed all the steps, we should see some markers on the seek bar like shown below.
Whenever user reaches any of the markers, we are going to be notified in our delegate methods and we can then start the playback.
Some customization could be done for example, when the advert is playing, we can show a timer in reverse showing users how much of the advert is remaining.
We can also lock the controls to make the ad non-skippable if desired.
Congratulations! This concludes our short tvOS bootcamp. I hope you enjoyed it as much as I did while creating this.
Once again the git repository is available on this link: https://github.com/atulkhatri/tvos-bootcamp
For any query, please feel free to comment on this blog post.