The KreaTV DLNA feature allows serving media to other networked devices and playing media found on the local network. The feature has three parts that might be activated separately; media server (DMS), media player (DMP) and media renderer (DMR).
The DMS component announces the STB as a DLNA UPNP (universal plug and play) device on the local network and offers the local recordings for sharing to other STBs. The STB must have a hard drive to act as DMS.
There's no TOI interface to access DMS directly. Setting cfg.dlna.dms.enabled to TRUE or FALSE is all that is needed. An on-going distribution isn't cancelled automatically when disabling DMS.
The DMS is currently limited to serving a single stream at a time. Distributing a stream occupies one hardware demux resource. Since the application isn't in control of when a client tries to playback a DMS stream, the application doesn't know for sure how many demuxers are available for local playback, timeshift and recordings. If the application tries to start such an activity when all resources are occupied, the activity will immediately go to STATE_FAILED. The application can then choose to abort the distribution and restart the local activity.
For a JS code example, see below or the test portal toi2portals/DlnaDmsPortal.
// Called when onRecorderStatusChange(state=STATE_FAILED, reason=COMMAND_OPEN)
function retryRecording(asset)
{
// Clean up the failed recorder session
stopRecording(asset);
var distributors = [];
try {
distributors = toi.mediaService.enumerateDistributors();
}
catch (e) {
// No distributor info available -- nothing to do
return;
}
// Kill and retry if there is at least one (can only be one in our case).
if ((distributors.length > 0) && killDistributor(distributors[0])) {
// Disabled a media distribution session to free resources for the
// starting recorder.
// Retry recording
startRecording(asset.uri, title, 0);
}
// Rempove the asset created by the failed recorder session
assetManager.removeRecording(asset);
}
// Helper function for retryRecording to stop a distributor
function killDistributor(distributorInfo)
{
var session;
try {
session = toi.mediaService.openSession(distributorInfo.sessionId);
}
catch (e) {
// No session found -- nothing to do
return false;
}
try {
session.disableDistribution(distributorInfo.id);
}
catch (e) {
// Failed to stop ditributor -- nothing to do
return false;
}
// Stopped the distributor
return true;
}
The following lines are necessary in the config file to include DMS in the bootimage:
kreatv-option-dlna::device=dms kreatv-option-license::file=<directory>/kreatv_dlna_dms.license kreatv-option-dlnamediaserver-plugin
Besides including these components in the bootimage, the application must also enable DMS at run-time by setting the infoservice object cfg.dlna.dms.enabled to "TRUE". This can be set automatically by including this line in the config file when building the bootimage:
kreatv-option-is-default::cfg.dlna.dms.enabled=TRUE
The structure of the exposed assets and which assets are shared are specified with the XML file /etc/dms/cds_config.xml. The default file is platform/iips/options/dlna/default_cds_config.xml.
To use a custom CDS XML file, specify the 'config' parameter of
kreatv-option-dlna. For example, to copy another_cds_rules.xml to the
location of /etc/dms/cds_config.xml when building the bootimage,
specify:
kreatv-option-dlna:config=another_cds_rules.xml
A sample CDS config file is,
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<DmsConfig version="1">
<SharedContent id="recordings" type="IToiAssetManagerService/ASSET_PVR">
<PropertyMap name="dc:date" source="info.date" type="text"/>
<PropertyMap name="dc:description" source="info.description" type="text"/>
<ShareRule>
<Criteria test="equals" name="info.shared" value="true"/>
<Criteria test="equals" name="system.type" value="0"/>
</ShareRule>
<LocationRule location="/recordings"/>
</SharedContent>
</DmsConfig>
DmsConfig is the top element of the XML file. There can only be one DmsConfig element.
<DmsConfig version="1">
For the current home DVR solution there can only has one SharedContent element, and the type shall be ItoiAssetManagerService/ASSET_PVR. This means only recorded assets are exposed by the DMS. The id parameter can be chosen freely.
<SharedContent id="recordings" type="IToiAssetManagerService/ASSET_PVR">
Two kinds of properties are used in the config file -- general DLNA CDS properties and asset properties from the KreaTV Asset Manager service. General DLNA CDS properties have prefix "dc:" or "upnp:". These are specified in the UPNP CDS spec and are understood by common DLNA devices. The KreaTV asset properties are listed in the ToiAssetManagerService interface.
The PropertyMap tag maps DLNA CDS properties to asset properties. This means the customer can customize the name and use of asset properties.
<PropertyMap name="dc:date" source="info.date" type="text"/>This example maps the value of asset property "info.date" to DLNA CDS property "dc:date" for all assets in the current SharedContent.
An asset is only visible with the DMS if it fulfills all rules of the ShareRule element. If the list of criteras is empty, all assets are shared, as long as they have the type required by the SharedContent element. Notice how asset properties are used in this example ShareRule:
<ShareRule> <Criteria test="equals" name="info.shared" value="true"/> <Criteria test="equals" name="system.type" value="0"/> </ShareRule>The first criteria specifies the flag "info.shared" as required for a recording to be shared. The second criteria requires system.type to be 0 which in this context means ASSET_PVR. For details on the properties that can be used in ShareRule element, together with their type and possible value, please see the documentation of the ToiAssetManagerService interface.
The valid tests are "less", "equals" and "greater".
LocationRules determine how the content directory tree looks for other DLNA device in the UPNP network. A simple example is:
<LocationRule location="/recordings"/>This is a LocationRule that makes a content folder named 'recordings' visible from other DLNA device. Since the LocationRule doesn't contain any criterias, all assets that fulfill the SharedRule will be listed in the folder.
A more advanced example is:
<LocationRule location="/recordings/largevideo">
<Criteria test="greater" name="system.filesize" value="5000000"/>
</LocationRule>
The DLNA folder /recordings/largevideo will expose all files larger
than 5 GB, of the files that fulfill the SharedRule.
The Digital Media Renderer (DMR) component is contacted by a Digital Media Controller (DMC) to direct the STB to playback some media found on a third device, a DMS.
DMR differentiates itself from the DMP use case by the source of the initiative. Whereas the DMP itself browses a DMS and decides on an asset to play, the DMR must be ready for external playback requests and it's up to the application to carry out requests if consistent with the application's policy.
The following lines are necessary to include DMR in the bootimage:
kreatv-option-dlna::device=dmr kreatv-option-license::file=%BSG_SRC_ABS%/platform/iips/options/license/kreatv_dlna_dmr.license
The application registers with the IToiDlnaRendererManager to receive playback requests.
The Digital Media Player (DMP) part of the KreaTV DLNA service is used to access media files on Digital Media Servers (DMS) in the home network. The DMP implementation is compliant with the DLNA 1.5 Networked Device Interoperability Guidelines.
kreatv-option-dlna::device=dmp kreatv-option-license::file=%BSG_SRC_ABS%/platform/iips/options/license/kreatv_dlna_dmp.license
In order to play a media file from a media server the following steps need to be taken:
The DMP functionality is accessed through IToiDlnaService. The method IToiDlnaService::GetMediaServers() retrieves the current list of available servers. By subscribing to events, the application can be notified when servers appear and disappear from the network. The object returned by IToiDlnaService::CreateContentDirectoryInstance() lets the application communicate directly with the DLNA service at a remote server.
Since this service communicates with a remote server, and DLNA allows requests to take up to 30 seconds, many methods are executed asynchronously. In KreaTV a generic interface IToiOperationManager is used to handle asynchronous methods. Each service that utilize this kind of methods provide its own IToiOperationManager instance. In IToiContentDirectoryService this instance can be retrieved by calling GetCdsOperationManager().
To browse the root directory of a media server, the application first creates an asynchronous operation identifier by calling IToiOperationManager::CreateOperation() and subscribes to operation events. The next step is to call IToiDlnaContentDirectoryService::Browse() with that identifier as parameter to start the asynchronous operation. The method Browse() lists CDS objects in a specific container. The root container identifier can be retrieved from method IToiDlnaContentDirectoryService::GetRootContainerId(). The Browse() method also provides means to optimize the response time by defining how many object to get and an offset to use.
As soon as any object has been retrieved the application is notified by an event from the Operation Manager where the result parameter is set to IToiDlnaContentDirectoryService::OP_RESULT_OBJECT. This means that CDS objects can be read by calling IToiDlnaContentDirectoryService::GetOperationObjectResult(). The objects returned will have property values corresponding to the properties listed in the call to Browse(). If only playback is wanted the IToiDlnaContentDirectoryService::PROPERTY_RES is the property to use.
The PROPERTY_RES includes the URL that can be passed to IToiMediaPlayer::Open() or used to load an image. The DLNA services are not involved in any other way during playback or rendering.
See also: TOI DLNA Service Interface