Build a custom Video Player with Ads on tvOS

atul khatri
4 min readJul 12, 2021

--

(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 AVPlayerViewController.

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 startAssetPlayback() method:

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 AVPlayer.

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 viewDidLoad.

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 AssetModel.

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.

Inside 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().

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.

tvOS Player with Ads

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.

Image Credits: Adobe Stock

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.

--

--

atul khatri
atul khatri

Written by atul khatri

Software Engineer (iOS) @ Meta | Tech Enthusiast | Learner