Registering the download

OTVDownloadManager and its listener

The OTVDownloadManager needs to be instantiated in the lifecycle of your application, for example in the onCreate() method of your main activity. Upon instantiation, the OTVDownloadManager recovers the persistent database of previous download operations and makes them accessible to the application. However, operations cannot be triggered unless the application implements a listener for download events.

Implement a listener class (either an internal class within your activity, or your class can implement the listener interface), instantiate it, and pass the object reference to your OTVDownloadManager instance.

import nagra.otv.sdk.OTVSDK;
import nagra.otv.sdk.OTVVideoView;
import nagra.otv.sdk.offline.OTVDownloadItem;
import nagra.otv.sdk.offline.OTVDownloadListener;
import nagra.otv.sdk.offline.OTVDownloadManager;

...
public class MainActivity extends Activity {

  private OTVDownloadManager mDlManager = null;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    OTVSDK.load(this);

    mDlManager = new OTVDownloadManager(new MyDownloadListener());

    ...
  }

  private class MyDownloadListener implements OTVDownloadListener {
    @Override
    public void onDownloadAdded(OTVDownloadItem dlItem) {
      // A download for a stream is added to the persistent database.
      // Not downloading yet.
      // The details of this entry are present in dlItem.
    }

    @Override
    public void onDownloadRemoved(String uuid) {
      // The entry, identified by its UUID, was removed from the persistent database
    }

    @Override
    public void onDownloadStateChange(OTVDownloadItem dlItem, OTVDownloadState state) {
      // The entry dlItem has changed its download state.
      switch (mDlState) {
      case STATE_PREPARING:
        // This is the initial state after an entry is added
        // OTVDownloadManager is processing the stream URL, and then
        // downloads and parses the manifest preparing the download process.
        break;
      case STATE_PREPARED:
        // The stream's manifest was processed, and OTVDownloadManager
        // is now ready to start a download
        break;
      case STATE_RUNNING:
        // Download is ongoing. Frequent progress reports are sent via onDownloadProgress().
        break;
      case STATE_PAUSED:
        // Download is paused, and can be resumed by calling dlItem.resumeDownload()
        break;
      case STATE_SUCCESSFUL:
        // Download of the stream is complete
        break;
      case STATE_FAILED:
        // Download progress was interrupted due to a failure (e.g. network loss).
        // The nature of the failure can be retrieved via dlItem.getError()
        // The downoload entry still persists. The application may attempt
        // to resume the download (e.g. afternetwork is recovered) by calling
        /// dlItem.pauseDownload() and then dlItem.resumeDownload().
        break;
      default:
        break;
      }
    }

    @Override
    public void onDownloadProgress(OTVDownloadItem dlItem, float progress) {
      // Progress report of a specific download entry.
      // The progress value is between 0 and 1.
    }
  }
}

Setting the storage location for downloaded content

The SDK will choose to store all persistent offline data inside the application's data path under the offline sub-directory by default . The application can change the path by calling setStorage(). However this is not recommended, and integrators should be aware that the application and the SDK must be granted write permissions to the new path, should the path change.

Finding existing download items

Especially at application start-up, it may be necessary to find out what downloads persist in the database. OTVDownloadManager provides a method for this:

OTVDownloadItem[] items = mDlManager.getDownloadItems();

All download items are indexed by their UUID, which is assigned when a download is added. Most download operations are actioned by calling the OTVDownloadManager instance API with the UUID as a parameter. For example:

mDlManager.removeDownload(uuid);

For some operations, it is necessary to access the OTVDownloadItem instance. A reference to such an instance is sometimes passed in the listener's event methods, but can also be fetched based on the UUID index:

OTVDownloadItem item = mDlManager.getDownloadByUUID(uuid);

The opposite can also be achieved - finding a download item's UUID:

String uuid = dlItem.getUUID();

Registering an asset for download

An application must first register an asset to the downloader before actually downloading it.

The registration step fetches the metadata related to the asset. The Download Manager fetches the stream manifest as soon as an application registers a URL.

  • When information contained in the playlist is available to the application for reading, the state of the download will change to STATE_PREPARED.
  • If the manifest cannot be acquired or parsed, the download state changes to STATE_FAILED.
  • For encrypted content, a callback class is passed on during the registation. This callback class is then used by the OTVDownloadManager instance to fetch the licence for the content and store it locally. The callback class can be the same as the callback class used for playing back Widevine protected content.

Assets that have been marked for download and are in the PREPARED state (bitrate not yet selected yet and actual download not started) will not persist - if the application terminates and restarts, the PREPARED downloads will be removed. Although from an integrators' point of view, preparing and starting downloads are separate steps, it is recommended that the application combines the two into a single step.

Clear content

Given a URL of an online stream you wish to download, register the stream for download operations.

String uuid = mDlManager.registerDownload("http://path/to/stream.mpd");

Encrypted content

The application must instantiate an OTVMediaDrmCallback callback class with server and content parameters and pass that callback as a second parameter to registerDownload()


// Set-up callback instance with specific headers for this licence server OTVHttpMediaDrmCallback callback = new OTVHttpMediaDrmCallback("https://path/to/licence/server/"); callback.setKeyRequestProperty("Accept", "application/octet-stream"); callback.setKeyRequestProperty("Content-Type", "application/octet-stream"); // Tenant ID is a specific implementation of an SSP licence server callback.setKeyRequestProperty("nv-tenant-id", "TENANT_ID"); // Content token is a specific implementation of an SSP licence server callback.setKeyRequestProperty("nv-authorizations", "STREAM_TOKEN"); // Register the donload asset with the callback object as second parameter String uuid = mDlManager.registerDownload("http://path/to/stream.mpd", callback);

The uuid string returned is a unique identification for this download entry. You would use it whenever you need to operate on this entry.

The download is not started at this stage. Only when the onDownloadAdded() is called and the download's state changes to STATE_PREPARED can the download actually start.

The licence keys have to be fetched and stored prior to the actual download. In the case of Widevine-protected content, OTVDownloadManager does it automatically during the preparation phase through the provided OTVHttpMediaDrmCallback instance.

Next step: Start the download