First Look at the DVR in Live Channels

The Live Channels app has been updated yesterday to include a DVR activity and a user interface for recording. How do these things work? We take a deep dive into this new API and user experience using a hastily thrown together app. The app integrates YouTube videos into Live Channels to play them as you’d play a normal video file.

You won’t see any actual video content as I’m running the Live Channels app in an emulator as a system app. For some reason, YouTube videos in a WebView won’t show video, but you can hear it and see other components of the embedded video. Regardless, the app works well enough now for demonstrating the user experience.

Recording Session

From an already-existing app that supports the Tv Input Framework, a RecordingSession needs to be created that handles the lifecycle callbacks. You can read the official documentation for more information.

@RequiresApi(api = Build.VERSION_CODES.N)
private class RedditRecordingSession extends RecordingSession {


This class should be instantiated and returned within the method onCreateRecordingSession(String inputId) which can be overridden.

The app needs to implement onTune(Uri channelUri), onStartRecording(Uri programUri), onStopRecording(), and onRelease().

  • onTune – This tunes your app to the specified channel. notifyTuned(channelUri) should be called once the channel is ready.
  • onStartRecording – This tells your app that the user has created a recording. If the recording was scheduled ahead of time, the Uri of the program is passed.
  • onStopRecording – This tells your app that the recording has been stopped manually or at the end of the program. Here the metadata should be saved.
  • onRelease – The RecordingSession should be cleaned up and removed.

Notify Recording Ended

When the recording ends, the data must be saved in the RecordedPrograms database. It should have the same metadata as the original program, which is easy to obtain. It should also contain a few additional fields related specifically to the particular recording:

  • TvContract.RecordedPrograms.COLUMN_RECORDING_DATA_BYTES – How large the saved video file is
  • TvContract.RecordedPrograms.COLUMN_RECORDING_DATA_URI – The URI pointing to the saved video file
  • TvContract.RecordedPrograms.COLUMN_RECORDING_DURATION_MILLIS – The length of the video. If it was stopped manually, it may not be the difference between the start and end times
  • TvContract.RecordedPrograms.COLUMN_RECORDING_EXPIRE_TIME_UTC_MILLIS – The programs can be set to expire at a certain time, if a user has rented a video or has a trial period for a specific video service. It can be ignored in general.

For a lot of online-based media, a physical copy of the video doesn’t need to be saved locally and take up a lot of storage. The open-ended nature of the APIs mean any solution can be done. Perhaps the only thing saved could be a bookmark to the video later.

The recording should be saved and passed into notifyRecordingStopped to notify the system that the recording has ended and another can begin. If there is an issue, whether storage is full or the resource couldn’t be reached, notifyError can be called instead with a specific error code.

Starting a Recording

DVR Recording
With this new channel source, I can go up to the playback controls and see a new record button at the end. When I click on it, a recording starts. The button changes to a square which lets me stop it manaully. Once I create my first recording, a new option appears in the app. Next to the program guide is a new option to view my recordings and scheduled recordings.

DVR Activity
In this screenshot, we can see the DVR activity. My most recent recordings are in the top row. Below that is an option to view future scheduled programs. Then the recordings appear to be sorted by genre. As my recording has no genre, it is placed in the “Other” group. This should make it easy to find recordings when a lot of things are saved.

DVR Card
When I select the specific recording, I can see more details including when the recording occurred and a description of it. There are options to play and delete this recording. If I start playing, it opens up a new playback session just to play this video (calling onTimeShiftPlay(Uri recordedProgramUri)) and there are some timeshifting controls. When I stop playing, the actions are now “Continue Playing”, “Play from Beginning”, and “Delete”.

Selecting “Delete” will just delete the recording without confirmation or an undo option.

Scheduled Recordings

DVR scheduled recording
Recordings can also be set ahead of time. By opening the program guide and going ahead in time, pressing enter on a program will automatically schedule it to be recorded. Then it will appear in your list of scheduled recordings.

In this screen, we can see upcoming recordings and delete them with a single click
In this screen, we can see upcoming recordings and delete them with a single click

When the time comes, a new RecordingSession will be created and a program URI will be passed which can help populate the recording metadata.

DVR scheduling conflict

Scheduling conflicts may occur if your RecordingSession doesn’t have enough “tuners” to handle concurrent recordings. Users are able to pick which one they want to actually record.


Overall, it seems like this first version has covered the gamut with regards to functionality. There are some things I haven’t looked at, such as creating “season passes” to record all of a series, or having a collection of episodes based around a series. However, it does essentially everything one expects with a pretty sleek interface. Even in an emulator it’s pretty responsive.

The lack of confirmation in deleting is interesting. This DVR implementation may not be fool-proof and accidents may happen. However, since the interface is easier to comprehend compared to a standard cable box it shouldn’t be a big issue. Additionally, the Live Channels app is a reference TV app that can be implemented by Sony or other companies. These companies may choose to put a confirmation dialog in their apps, but it may not be part of the bare minimum required by the Android compatibility guidelines.

The biggest focus now is getting more Live Channel apps in general, and making sure these new apps can support the recording APIs.

I will be cleaning up the code in this example and posting it soon. However, by following the documentation and this quick guide, you should be able to implement quick DVR capability by yourself.

Nick Felker

Nick Felker

Nick Felker is a student Electrical & Computer Engineering student at Rowan University (C/O 2017) and the student IEEE webmaster. When he's not studying, he is a software developer for the web and Android (Felker Tech). He has several open source projects on GitHub ( Devices: Moto G-2013 Moto G-2015, Moto 360, Google ADT-1, Nexus 7-2013 (x2), Lenovo Laptop, Custom Desktop. Although he was an intern at Google, the content of this blog is entirely independent and his own thoughts.

More Posts - Website

Follow Me:
TwitterLinkedInGoogle PlusReddit