Example: Schedule a recording

This example demonstrates two things:

The first part of the example looks at the Scheduler Service. This makes it easy for you to book events at a particular time. You can request an event for next Tuesday at 18:00 or a series (every Monday at 20:00). The main purpose of the Scheduler Service is to make it easy for you to implement video recording functionality, but you can use it for other event scheduling if you want.

The Scheduler Service is also aware that bookings can consume resources (ie recording a stream to disk) and so it allows limits to be placed. If you then try to schedule too many things (wanting recording too many channels simultaneously, for example) it will notify you of this. Scheduled bookings are sorted into Categories and Activities which indicate the resource usage. See the documentation for Scheduler Service config for more details.

You will need to have the kreatv-option-scheduler IIP in your boot image configuration to be able to use the Scheduler Service.

Setting up listeners

The example begins by setting up some listeners. Events ON_SCHEDULED_START and ON_SCHEDULED_STOP are of interest (see the documentation for other available events). These events are raised when a booking begins, and when it ends (bookings have a duration). The setCategorySubscription() function call sets the category filter to '*', meaning we receive events for all categories. Without this, the portal will not receive any events.

var ss = toi.schedulerService;
ss.addEventListener(ss.ON_SCHEDULED_START, onScheduledStart);
ss.addEventListener(ss.ON_SCHEDULED_STOP, onScheduledStop);
ss.setCategorySubscription(onScheduledStart, "*");
ss.setCategorySubscription(onScheduledStop, "*");

The rest of the portal code deals with setting up the current time display, and the spinner used to enter in a time for the scheduling.

Creating a booking

When the user presses the RED key on their remote control, the portal saves the selected time into the startTime object. This is then passed to the Scheduler Service:

bookingId = toi.schedulerService.schedule("activity_1",
                                          "record_hd_from_ip",
                                          startTime.getTime()/1000,
                                          60);

Here, the activity is set ("activity_1") and the category ("record_hd_from_ip"). Categories and activities are specified in an XML configuration file supplied when building the boot image, along with the resources and amounts that they consume. See the Scheduler Service config page for further info.

The startTime is specified in seconds from the Unix epoch, Jan 1, 1970.

The duration is also specified, in seconds. The example requests a 60 second long booking.

Events

When the time for the booking is reached, the onScheduledStart() function will be called, and passed an event parameter. This is of type ToiSchedulerServiceBooking (look it up!). It is now time for the portal to begin recording the TV channel (see next section below). When the booking duration expires (after 60 seconds), the onScheduledStop() event is called, and the recording is stopped, and then played back.

Note that it is ok to reload the portal, kill the portal application, and even restart the IP-STB once the booking has been made. Restart the box and get the portal back up on-screen, and when the booking time comes around, the onScheduledSart() callback will be called.

Recording the Video

Recording video involves creating a media Recorder instance, rather like a media player instance is created:

mediaRecorder = toi.mediaService.createRecorderInstance();
var assetId = toi.assetManagerService.createAsset(toi.assetManagerService.ASSET_PVR);

mediaRecorder.open(channel, assetId);

An asset is also created, which is used to hold the recorded information. Assets are created, managed, and removed by the assetManagerService. Here, an asset of type ASSET_PVR is created. The createAsset() returns the ID for the newly created asset. This is used when opening the asset.

The following code examines the assets properties to determine the URI to the asset. This is similar to the Id, but is a full URI, for example, the ID might be "asset_xyz123" but the URI is "dvr:///pvr/storage/asset_xyz123". URI's are passed to the media Player when opening the asset. Here, the URI is stored as a custom property for the booking with the schedulerService.setParameter() function call:

var propList = new Array(toi.assetManagerService.PROPERTY_SYSTEM_PLAYBACKURI);
var properties = toi.assetManagerService.getProperties(assetId, propList);
var assetURI = properties[0].value;

// save the assetId in the booking
toi.schedulerService.setParameter(event.booking.id, "assetURI", assetURI);

This is done to simplify matters later. When the booking end time is reached, the onScheduledStop function will be called, and an event parameter passed into it. This parameter contains the booking Id, which can be used to look up custom properties, in this case, the URI stored earlier. This is then used to play the asset with mediaPlayer.open() and mediaPlayer.play().

// determine which booking (in case of multiple bookings) just ended...
var assetURI = toi.schedulerService.getParameter(event.booking.id, "assetURI");
mediaPlayer.open(assetURI);
mediaPlayer.play(1000);

When the recorded asset has been played, and the end reached, a media Player onStateChanged event occurs. The example looks at the reason and state to determine what has happened (PostionEnd, since playback reached the end of the asset). When this has occured, it is time to go back to watching live TV again, so the media player is closed and re-opened with the TV channel URI once again. The asset remains on disk.

Further Ideas

The example does not remove assets from the hard disk once finished with them. Implement a function to remove assets when they have been played back, or via a button press.

Modify the example to support multiple bookings.