Improve Engagement on Watch Next for Movie/TV Episodes on Android TV

1. Introduction

Watch Next

The Watch Next channel is the row that appears in the Android TV home screen with videos for users to watch next. Depending on the system version, the Watch Next row might be called "Play Next" or "Continue watching".

b0ca4ea7c72ba8f6.png

The system creates and maintains this channel. Each item in this channel is called a program. Your app can add/update/remove programs to the Watch Next channel such as content that the user stopped watching in the middle, or content that the user has interacted with (like the next episode in a series or next season of a show).

Concepts

The Watch Next channel provides a way for your app to drive re- engagement with the user.

You can add/update/remove content to the Watch Next channel, which the user has already interacted with. Either an unfinished video or suggest the next episode/series etc.

Apps can also remove the episode once it's watched and add the next episode of the new season of the series.

There are four types of use cases for the Watch Next channel:

  • Continue watching a video that the user has not finished.
  • Suggest the next video to watch. For example, if the user finished watching episode 1, then you can suggest episode 2.
  • Surface new episodes of a series the user has been watching.
  • Maintain a watchlist of interesting videos added by the user.

This codelab shows how to include a video in the Watch Next channel when the user pauses it. It also covers removing a video from Watch Next when it plays to the end and how to add the next episode when available.

This codelab doesn't cover the Watch Next use cases for new released episodes and watchlist.

Watch Next for Movies and TV Episodes

The Watch Next channel is a very important feature on Android TV home screen, it helps users to catch up on unfinished movies and TV shows. It is especially important for users watching TV episodes, since a TV series usually has many episodes and the user will continue watching where they left off many times.

Imagine when the user comes back and sits in front of their TV deciding what to watch. With Watch Next, your app allows them to resume TV episodes from where they have left off directly from the home screen. This increases user reengagement, which benefits both your app and the user.

This codelab will walk you through the TV reference app, show you how to deal with different cases for the Watch Next channel, and explain Google's quality guideline on the Watch Next feature. This codelab focuses on handling TV episodes specifically, but you can apply similar rules for movies.

Availability

The code in this codelab works on Android TV devices, including those that run the Google TV experience..

What you'll build

In this codelab, you're going to add, remove and update a Watch Next channel for TV movies/episodes. Your app will:

  • Implement different use cases for handling movies
  • Implement different use cases for handling TV episodes

What you'll learn

  • Google's quality guidelines for Watch Next

What you'll need

  • Basic knowledge of Android application development
  • Android Studio 4.1+, you can download here

2. Getting set up

Clone the starter project

You can download the source code from the GitHub repository:

git clone https://github.com/googlecodelabs/watchnext-for-movie-tv-episodes.git

Or you can download directly from the link below.

Download source code

Open Android Studio and click File > Open from the menu bar or Open an Existing Android Studio Project from the welcome screen and select the recently cloned folder.

8271a7b581390845.png

Understanding the starter project

34641bc2c9f71f0f.png

There are four steps in the project. In each step, you'll add code based on the instructions in the applicable section. Once you complete a section, you can compare your code with the code in step_x_completed.

For simplicity, we have added some basic code for list of videos and exoplayer to watch content inside the app. This will create a basic skeleton of a tv app, which is outside the scope of this codelab.

Our aim here is to learn to add/remove/update the unfinished and finished videos to the Watch Next channel and generate re-engagement for our app.

These are the main components in the app:

  • FileVideoRepository is the class to load and query video metadata.
  • PlaybackFragment is the video playback fragment.
  • WatchNextPlaybackStateListener is a playback state change listener; it listens to playback events and triggers related operations.
  • WatchNextWorker is a worker that is responsible for updating the Watch Next channel.
  • WatchNextHelper is a helper class that simplifies working with the Watch Next channel.

This codelab uses media data in res/raw/api.json to populate Watch Next entries.

Run the starter project

Run step_1. If you have issues, see the documentation on how to get started.

  1. Connect your Android TV or start the emulator.
  1. Select the step_1 configuration, select your Android device and press the run button in the menu bar. 249ea91a556fbd61.png
  2. You should see a simple TV app outline with four collections of videos similar to the screenshot below.
  3. Navigate through the app's main screen, get yourself familiar with the TV reference app. There are four video categories:
  4. Supercharged Clips
  5. Misc Clips
  6. Beverly Hillbillies: a few TV episodes from two different TV seasons;
  7. Charlie Chaplin Movies.
  8. Click one of the TV episodes in Beverly Hillbillies category and watch it. This codelab will tell you how to add Watch Next programs for these TV episodes

d7b51de54f4a1199.png

What you've learned

In this introduction, you've learned about:

  • Code structure and major classes used in this codelab.
  • How to setup and run the sample app.

What's next?

The Watch Next quality guidelines

3. Understand the Watch Next quality guidelines

To provide a better home screen experience, all apps that add content to Watch Next need to behave consistently.

Specifically, there are scenarios developers need to cover for TV episodes. Google has summarized a list of quality guidelines for Watch Next that must be followed to ensure the quality of the Watch Next channel.

How to build your Watch Next feature to meet Google's quality standards

When Google evaluates the Watch Next feature, the following points will be verified

  1. The program is added to Watch Next when paused/stopped
  2. The app is able to resume playback from Watch Next entry
  3. The app updates playback position in Watch Next in a timely manner
  4. The program is removed from Watch Next when playback completes
  5. The next episode is added when the current episode completes
  6. The app does not add content the user hasn't interacted with to Watch Next
  7. Push all unfinished content to Watch Next
  8. The app sets correct and complete metadata, e.g. season/episode numbers
  9. The app doesn't add multiple episodes for same TV series

Here are explanations of each quality requirement

  1. The program is added to Watch Next when paused/stopped.
  • Apps should add traditional movies and TV shows to the Watch Next row when playback is not completed
  1. The app is able to resume playback from Watch Next entry.
  • Content added to the Watch Next channel resumes playback from the last playback position; the video should start playback immediately after the content is loaded
  1. The app updates the playback position in Watch Next in a timely manner.
  • The app needs to keep track of playback progress and update Watch Next program to the latest playback position after a user has left the video
  1. The program is removed from Watch Next when playback completes.
  • An app should be a good citizen and clean up after itself. The Watch Next row is a shared row for all apps and we want to make sure content in the row is accurate to retain the user's trust
  1. The next episode is added when the current episode completes.
  • When users watch a TV series, the app should make it easier for the user to continue watching by adding the next episode of the series to the Watch Next row
  1. The app does not add content the user hasn't interacted with to Watch Next.
  • According to the Watch Next guidelines, the app should only add a movie or TV episode to the Watch Next channel if a user ‘started' watching
  • It's not recommended to add trailers, short video clips to Watch next channel. Since there is very little re-engagement there
  1. Push all unfinished content to Watch Next.
  • Providers should not artificially limit the number of cards they push to Watch Next. If a user has a piece of unfinished content, they should push it to the Watch Next row
  1. The app sets correct and complete metadata.
  • Make sure the metadata associated with the episode is correct
  • The episode number, season number, and title have to be accurate
  • The progress bar has to be proportional to the amount watched
  • The episode or series image should be present in the tile
  1. The app should avoid adding multiple episodes for the same TV series.
  • The app should keep at most one Watch Next entry for each TV series; if a user watches half of two different episodes, Watch Next should only show the most recently watched episode

These quality requirements will help your app provide a great user experience on Watch Next.

OK, let's jump in and start to build Watch Next features with these quality guides in mind.

What you've learned

In this section, you've learned about:

  • The Watch Next quality requirements

What's next?

Add an unfinished episode to the Watch Next channel

4. Add unfinished content to Watch Next

We'll start from the basic functionality: Adding an unfinished episode to Watch Next.

The codelab will walk you through how to create a WatchNextProgram, fill in correct metadata for the episode, like episode number, season number and video type etc. The Watch Next entry is updatable, making sure it catches up with the user's latest playback position so users are able to resume playback by clicking the program.

The following will be covered in this section:

  • The program is added to Watch Next when paused/stopped.
  • The app is able to resume playback from Watch Next entry.
  • The app updates playback position in Watch Next in a timely manner.
  • The app sets correct and complete metadata.

Add an unfinished video - the difference between movies and episodes

The procedure for adding a movie and episode to the Watch Next channel is very similar. The only difference is the metadata is different for each.

For example, for episodes we have specific metadata methods in the WatchNextProgram.Builder like setEpisodeNumber, setSeasonNumber(), setSeasonTitle() and setEpisodeTitle()

Add an unfinished video (movie/episode) to Watch Next Channel

To add an unfinished video to the Watch Next channel, developers can use WatchNextProgram.Builder to build a WatchNextProgram instance and call PreviewChannelHelper.publishWatchNextProgram to publish it to the Watch Next channel.

First, create a Builder instance of WatchNextProgram and set all metadata to describe the video.

Searching for setBuilderMetadata method in PlayNextHelper.kt in step_1, copy and paste the following code between "Step 1.1 - Set video metadata for WatchNextProgram." comments.

WatchNextHelper.kt

builder.setType(type)
   .setWatchNextType(watchNextType)
   .setLastPlaybackPositionMillis(watchPosition)
   .setLastEngagementTimeUtcMillis(System.currentTimeMillis())
   .setTitle(video.name)
   .setDurationMillis(duration.toMillis().toInt())
   .setPreviewVideoUri(Uri.parse(video.videoUri))
   .setDescription(video.description)
   .setPosterArtUri(Uri.parse(video.thumbnailUri))
   // Intent uri used to deep link video when the user clicks on watch next item.
   .setIntentUri(Uri.parse(video.uri))
   .setInternalProviderId(video.id)
   // Use the contentId to recognize the same content across different channels.
   .setContentId(video.id)

if (type == TYPE_TV_EPISODE) {
   builder.setEpisodeNumber(video.episodeNumber.toInt())
       .setSeasonNumber(video.seasonNumber.toInt())
       // User TV series name and season number to generate a fake season name.
       .setSeasonTitle(context.getString(
           R.string.season, video.category, video.seasonNumber))
       // Use the name of the video as the episode name.
       .setEpisodeTitle(video.name)
       // Use TV series name as the tile, in this sample,
       // we use category as a fake TV series.
       .setTitle(video.category)
}

Read through the code in step 1.1, try to understand why we are setting these metadata.

  1. setLastPlaybackPositionMillis() and setDurationMillis() helps to show the correct playback progress and update it when the user interacts with the video.
  2. setLastEngagementTimeUtcMillis() sets the timestamp when the user watched this video, which helps the Watch Next channel to prioritize entries.

Add an unfinished movie to Watch Next

We can use WATCH_NEXT_TYPE_NEXT for adding an unfinished movie to Watch Next Channel.

Set movie metadata: title and description

For movies, set the title and description as well as other attributes, so users know they are watching the correct content without clicking through to the video.

builder.setType(type)
   .setWatchNextType(watchNextType)
   .setLastPlaybackPositionMillis(watchPosition)
   .setLastEngagementTimeUtcMillis(System.currentTimeMillis())
   .setTitle(video.name)
   .setDurationMillis(duration.toMillis().toInt())
   .setPreviewVideoUri(Uri.parse(video.videoUri))
   .setDescription(video.description)
   .setPosterArtUri(Uri.parse(video.thumbnailUri))
...

Sample screenshot for a movie.

99a21ecd22268f2d.png

Add an unfinished episode to Watch Next

There are four types you can use for setWatchNextType(), use WATCH_NEXT_TYPE_CONTINUE for unfinished TV episodes, WATCH_NEXT_TYPE_NEXT for the next episode.

Set episode metadata : episode and season number/title

For TV episodes, set the episode number and the season number, so users know they are watching the correct episode without clicking through to the video.

if (type == TYPE_TV_EPISODE) {
   Builder.setType(PreviewPrograms.TYPE_EPISODE)
       .setEpisodeNumber(video.episodeNumber.toInt())
       .setSeasonNumber(video.seasonNumber.toInt())
       // Use TV series name and season number to generate a fake season name.
       .setSeasonTitle(context.getString(
           R.string.season, video.category, video.seasonNumber))
       // Use the name of the video as the episode name.
       .setEpisodeTitle(video.name)
       // Use TV series name as the tile, in this sample,
       // we use category as a fake TV series.
       .setTitle(video.category)
}

SeasonTitle, EpisodeTitle and Title have to be set correctly. Each episode has its own title to describe the content in the episode, we can use it for the EpisodeTitle. Use the TV series title for the title attribute of the TV show, so users know what the episodes are for. If you have a season title, use it for SeasonTitle, instead, you can use a combination of the series name and season numbers, e.g. <TV Series name> season <season number>.

Sample screenshot for an episode.

658c430b13bcb3a6.png

Resume Playback

setLastPlaybackPositionMillis(watchPosition) is used to pass in the time where the user left the movie/episode; this progress will display on the Watch Next card. In the TV reference app, the code uses WatchProgressDatabase to track playback progress of each video. This allows users to resume watching from the previous point no matter how they navigate to the video.

According to the Watch Action playback guidelines, the episode should start playback immediately after the video content is loaded. There's no need to show the TV series information again since users have already begun watching it.

Next, call PreviewChannelHelper.publishWatchNextProgram to publish it to the Watch Next channel. Search for "Step 1.2" in the same file and paste the following code:

WatchNextHelper.kt

try {
   programId = PreviewChannelHelper(context)
       .publishWatchNextProgram(updatedProgram)
   Timber.v("Added New program to Watch Next row: ${updatedProgram.title}")
} catch (exc: IllegalArgumentException) {
   Timber.e(
       exc, "Unable to add program to Watch Next row. ${exc.localizedMessage}"
   )
   exc.printStackTrace()
}

Refresh Playback Progress

If a Watch Next card already exists in the Watch Next channel, the app needs to keep it updated if the user watches more of the video so that it reflects the latest watch progress.

When updating a WatchNextProgram, use the same builder class to build a WatchNextProgram and call updateWatchNextProgram of PreviewChannelHelper to update an existing entry. Paste the following code into "Step 1.3" in WatchNextHelper.kt.

WatchNextHelper.kt

programId = existingProgram.id
PreviewChannelHelper(context).updateWatchNextProgram(updatedProgram, programId)

Sample screenshot

Check your result

Go through the code, compare your changes with the source in step_1_completed, run step_1_completed and watch part of an episode, verify if it has been added to the Watch Next channel.

Validations

  • ✅ PASSED: The program is added to Watch Next when paused/stopped
  • ✅ PASSED: The app is able to resume playback from Watch Next entry
  • ✅ PASSED: The app updates playback position in Watch Next in a timely manner
  • ✅ PASSED: The app sets correct and complete metadata
  • ✅ PASSED: Push all unfinished content to Watch Next
  • ❗ FAILED: The program is removed from Watch Next when playback completes
  • ❗ FAILED: The next episode is added when the current episode completes
  • ❗ FAILED: The app does not add content the user hasn't interacted with to Watch Next
  • ❗ FAILED: The app doesn't add multiple episodes for same TV series

What you've learned

In this section, you've learned how to:

  • Create a WatchNextProgram
  • Insert or update WatchNextProgram in the Watch Next channel
  • Update playback progress
  • Resume playback
  • Set correct metadata for a TV episode

What's next?

Add an unfinished episode to the Watch Next channel

5. Remove content (Movies/Episodes) from Watch Next when playback completed

The cards in Watch Next channel are ordered by last engagement time, the latest engaged video is placed at the front of the channel. The app should remove the program from the Watch Next channel after a user finishes watching it and promote more relevant content to users.

Developers need to monitor the playback progress of a video. Once a user has finished watching a video, the app needs to remove it from the Watch Next channel.

Note: The same logic can be used to remove a movie or an episode from the Watch Next channel.

Remove WatchNextProgram

To delete an entry from the Watch Next channel, developers need to find the correct WatchNextProgram and use the program URI to delete it from the content provider. To do this, developers need to match the WatchNextProgram with the video entities in their own database. We can leverage the internalProviderId field, set a unique video identifier and link it with one of the entities in the developer's own database.

Firstly, find the correct WatchNextProgram by looking up the video id. You can either access internalProviderId from WatchNextProgram. getInternalProviderId or access it through WatchNextProgram content provider, then remove it from Watch Next channel with the URI.

Search for "Step 2.1" copy and paste the following:

WatchNextHelper.kt

val foundProgram = getWatchNextProgramByVideoId(video.id, context)
if (foundProgram == null) {
   Timber.e(
       "Unable to delete. No program found with videoID ${video.id}"
   )
   return null
}

// Use the found program's URI to delete it from the content resolver
return foundProgram.let {
   val programUri = TvContractCompat.buildWatchNextProgramUri(it.id)
   // delete returns the number of rows deleted.
   val deleteCount = context.contentResolver.delete(
       programUri, null, null
   )

   if (deleteCount == 1) {
       Timber.v("Content successfully removed from Watch Next")
       programUri
   } else {
       Timber.e("Content failed to be removed from Watch Next, delete count $deleteCount")
       null
   }
}

If you want to remove multiple WatchNextProgram at once, it's always good to request a batch operation to optimize visits to TV's content provider. Search for "Step 2.2", copy and paste the following code snippet into WatchNextHelper.kt.

WatchNextHelper.kt

val foundPrograms = getWatchNextProgramByVideoIds(videos.map { it.id }, context)
val operations = foundPrograms.map {
   val programUri = TvContractCompat.buildWatchNextProgramUri(it.id)
   ContentProviderOperation.newDelete(programUri).build()
} as ArrayList<ContentProviderOperation>

val results = context.contentResolver.applyBatch(TvContractCompat.AUTHORITY, operations)

results.forEach { result ->
   if (result.count != 1) {
       Timber.e("Content failed to be removed from Watch Next: ${result.uri}")
   }
}

According to Watch Next guidelines, an episode should be removed if a user finished it. The user has "finished" an episode if the end credits start. In this case, do not add it to the Watch Next channel (or remove it if it has already been added). You can determine this state using a technology to auto-detect end credits, or use an approximation based on the content length (for example, less than 3 minutes remaining in an episode).

Looking at handleWatchNextForEpisodes() method in WatchNextHelper.kt, you can find the following snippet:

WatchNextHelper.kt

video.isAfterEndCreditsPosition(watchPosition.toLong()) -> {
   removeVideoFromWatchNext(context, video)

   ...
}

In this codelab, we use VIDEO_COMPLETED_DURATION_MAX_PERCENTAGE to simulate the credit scene position, you can replace the code in isAfterEndCreditsPosition() with your own logic.

Check your result

Go through the code, compare your changes with the source in step_2_completed, run step_2_completed and watch an episode, verify if it has been removed from Watch Next channel after you finished watching.

Validation

  • ✅ PASSED: The program is added to Watch Next when paused/stopped
  • ✅ PASSED: The app is able to resume playback from Watch Next entry
  • ✅ PASSED: The app updates playback position in Watch Next in a timely manner
  • ✅ PASSED: The app sets correct and complete metadata
  • ✅ PASSED: Push all unfinished content to Watch Next
  • ✅ PASSED: The program is removed from Watch Next when playback completes
  • ❗ FAILED: The next episode is added when the current episode completes
  • ❗ FAILED: The app does not add content the user hasn't interacted with to Watch Next
  • ❗ FAILED: The app doesn't add multiple episodes for same TV series

What you've learned

In this introduction, you've learned about:

  • Identify credit scene of TV episodes
  • Find WatchNextProgram by video id
  • Delete a single WatchNextProgram
  • Delete multiple WatchNextProgram

What's next?

Add next episode to Watch Next channel

6. Add Next Episode

Unlike movies, TV shows have more than 1 season and many episodes in each season. If a user completes watching an episode, instead of just removing it from Watch Next channel, it's a good practice to replace it with the next episode. The next episode can be either an episode right after the watched one in the same season, or the first episode in the next season if the finished episode is the last episode of the current season.

When adding the next episode to the Watch Next channel, set Watch Next type to WATCH_NEXT_TYPE_NEXT, it indicates this episode is not a previously watched program but a completely new episode user could follow. Apps should allow the user to watch the next episode from the beginning. Search for "TODO: Step 3.1 - Add next episode from TV series.", copy and paste the following code into step 3.1:

WatchNextHelper.kt

videoRepository.getNextEpisodeInSeries(video)?.let {
       insertOrUpdateVideoToWatchNext(
           it,
           0,
           WATCH_NEXT_TYPE_NEXT,
           context
       )
       newWatchNextVideo = it
   }

Next episode is captured by the getNextEpisodeInSeries() method.

Next episode of the same season

If the current season still has more episodes, apps should pick up the next available episode and set it as the next episode.

First episode of next season

If the user has finished watching the current season, but there's a newer season available, apps should pick up the first episode of the next season as the next episode.

New episode released

If there's no more episodes, apps don't need to add a next episode. However, when a new episode is available, it's great to push it to the client side, and add it to the Watch Next channel. New episodes should use WATCH_NEXT_TYPE_NEW as the WatchNextProgram type. This solution needs server push notifications, this codelab doesn't cover it.

Check your result

Go through the code, compare your changes with the source in step_3_completed, run step_3_completed and watch an episode, verify if the next episode has been added to the Watch Next channel after you finished watching.

Validation

  • ✅ PASSED: The program is added to Watch Next when paused/stopped
  • ✅ PASSED: The app is able to resume playback from Watch Next entry
  • ✅ PASSED: The app updates playback position in Watch Next in a timely manner
  • ✅ PASSED: The app sets correct and complete metadata
  • ✅ PASSED: Push all unfinished content to Watch Next
  • ✅ PASSED: The program is removed from Watch Next when playback completes
  • ✅ PASSED: The next episode is added when the current episode completes
  • ❗ FAILED: The app does not add content the user hasn't interacted with to Watch Next
  • ❗ FAILED: The app doesn't add multiple episodes for same TV series

What you've learned

In this section, you've learned about:

  • How to select next episode
  • Adding next episode for TV Series

What's next?

Understand the user's interest.

7. Understand the user's interest

To keep users focusing on the most relevant content in Watch Next channel, when adding a TV episode to Watch Next channel or removing it from the channel, there are extra considerations the app needs to take into account.

Multiple episodes from the same series

There are multiple reasons that a user may have more than 1 unfinished episode at a specific time. For example:

  1. The TV Series is available in multiple apps or on air;
  2. The user wants to speed up and skip some content;

Watch Next channel has very limited entries on the home screen, Google suggests apps to keep at maximum one episode from each TV series in the Watch Next channel. And the one left should be the episode the user last watched.

In the WatchNextHelper class, we handle it in handlePlayNextForEpisode(). Search for "Step 4.1", copy and paste the following code into the blank area of step 4.1.

WatchNextHelper.kt

newWatchNextVideo?.let { videoToKeep ->
   videoRepository.getAllVideosFromSeries(videoToKeep.seriesUri)?.let { allEpisodes ->
           filterWatchNextVideos(allEpisodes, context)
               ?.let { watchedEpisodes ->
                   removeVideosFromWatchNext(
                       context, watchedEpisodes.filter { it.id != videoToKeep.id })
               }
       }
}

In step 4.1, we keep tracking the latest episode a user watched, removing all other episodes from the same TV series. Since the step removes multiple episodes at once, we created a new method removeVideosFromWatchNext() to leverage the batch operation of Android content provider.

Less interacted content

According to Watch Next guidelines, an episode should be only added to the Watch Next channel if a user has started watching, and the user has "started" an episode if they've watched more than 2 minutes. Search for "Step 4.2", copy and paste the following code into the area of step 4.2.

WatchNextHelper.kt

val durationInMilliSeconds = duration.toMillis().toInt()
// Return true if either X minutes or Y % have passed
// Following formatting spans over multiple lines to accommodate max 100 limit
val watchNextMinStartedMillis = TimeUnit.MINUTES.toMillis(WATCH_NEXT_STARTED_MIN_MINUTES)
// Check if either X minutes or Y% has passed
val hasVideoStarted =
   (currentPosition >= (durationInMilliSeconds * WATCH_NEXT_STARTED_MIN_PERCENTAGE)) or
           (currentPosition >= watchNextMinStartedMillis)
val hasVideoStartedWithValidPosition =
   ((currentPosition <= durationInMilliSeconds) and hasVideoStarted)
Timber.v(
   "Has video started: %s, duration: %s, watchPosition: %s",
   hasVideoStartedWithValidPosition,
   duration,
   currentPosition
)
return hasVideoStartedWithValidPosition

Check your result

Go through the code, compare your changes with the source in step_4_completed, run step_4_completed and watch an episode, verify if:

  1. The code removes additional episode from TV series
  2. Only add to Watch Next channel if a user has started watching

Validation

  • ✅ PASSED: The program is added to Watch Next when paused/stopped
  • ✅ PASSED: The app is able to resume playback from Watch Next entry
  • ✅ PASSED: The app updates playback position in Watch Next in a timely manner
  • ✅ PASSED: The app sets correct and complete metadata
  • ✅ PASSED: Push all unfinished content to Watch Next
  • ✅ PASSED: The program is removed from Watch Next when playback completes
  • ✅ PASSED: The next episode is added when the current episode completes
  • ✅ PASSED: The app does not add content the user hasn't interacted with to Watch Next
  • ✅ PASSED: The app doesn't add multiple episodes for same TV series

What you've learned

In this section, you've learned about:

  • Avoid adding multiple episode of same TV series
  • Avoid adding less interacted content

What's next?

Congratulations

8. Congratulations

Congratulations, you've successfully built Watch Next for your TV episode and learned all the quality requirements on Watch Next.

Great job!

Further reading

Reference docs