Skip to the content.

Docs | Android

Offline Manager / Prefetch Manager

Offline Manager is a part of the Kaltura Player suite. It combines a download manager and a player, along with connectivity to the Kaltura backend and DRM actions.

Note to users of DTG: Offline Manager takes care of some of the responsibilities of apps that previously used PlayKit with the Download-to-Go (DTG) library. When migrating from DTG to Offline Manager, please remove DTG from the build scripts and don’t access its API directly.

What is Prefetch Manager

If devlopers want to build a feature where they want to download the initial part of media or bunch of media so that when the user tries to play the content, it becomes a seemless viewing experience then PrefetchManager is the best which can be opted.

Use PrefetchManager to prefetch 1 or more media assets and use PrefetchConfig to configure the behaviour of it. There app can choose when the clear the prefetched assets or how much asset app wants to prefetch(in Size) or how many assets.

And Many More…

Note to users of Prefetch: PrefetchManager only works with ExoPlayer offline providerOfflineManager.OfflineProvider.EXO. So in order to use this feature create OfflineManager as defined below,

OfflineManager.getInstance(this, OfflineManager.OfflineProvider.EXO)

Still if you want to use both Prefetch(EXO) and DTG with OfflineManager then you can keep two OfflineProviders and can maintain the download lifecycle.

Compare to the FULL download case where app could do track selection based on bitrate/height/width/pixel OR video/audio/text; here in PrefetchManager, it is not supported.

Prefetch does not support Live Media.

When the Prefetch/Full download(only with Exo Provider) is going on then a status bar notification is required as it uses a foreground service. Once user quits the application, still the download will be in progress. In case, if application does not want to continue the download on application quit then app can use pauseDownloads() API on OfflineManager.

On this page:

Setup

Creation

There are two offline providers. App can create OfflineManager by using any one of them

1. DTG Offline Provider (DTGOfflineManager)

OfflineManager.getInstance(this, OfflineManager.OfflineProvider.DTG)

2. Exo Offline Provider (ExoOfflineManager)

OfflineManager.getInstance(this, OfflineManager.OfflineProvider.EXO)

Start

An important step, OfflineManager will be started using #####void start(@Nullable ManagerStartCallback callback)

Asset State Listener

Offline Manager provides a global AssetStateListener that allows the app to respond to asset download events:

public interface AssetStateListener {
    void onStateChanged(@NonNull String assetId, @NonNull DownloadType downloadType, @NonNull AssetInfo assetInfo) {}
    void onAssetRemoved(@NonNull String assetId, @NonNull DownloadType downloadType) {}
    void onAssetRemoveError(@NonNull String assetId, @NonNull DownloadType downloadType, @NonNull Exception error) {}
    void onAssetDownloadFailed(@NonNull String assetId, @NonNull DownloadType downloadType, @NonNull Exception error) {}
    void onAssetDownloadComplete(@NonNull String assetId, @NonNull DownloadType downloadType) {}
    void onAssetPrefetchComplete(@NonNull String assetId, @NonNull DownloadType downloadType) {}
    void onAssetDownloadPending(@NonNull String assetId, @NonNull DownloadType downloadType) {}
    void onAssetDownloadPaused(@NonNull String assetId, @NonNull DownloadType downloadType) {}
    void onRegistered(@NonNull String assetId, @NonNull DrmStatus drmStatus) {}
    void onRegisterError(@NonNull String assetId, @NonNull DownloadType downloadType, @NonNull Exception error) {}
}

The application must implement this listener and pass it to the offline manager:

manager = OfflineManager.getInstance(context, OfflineManager.OfflineProvider.DTG);
manager.setAssetStateListener(this /* implements AssetStateListener */);

#####onStateChanged(@NonNull String assetId, @NonNull DownloadType downloadType, @NonNull AssetInfo assetInfo)

This method is called when an asset has moved from one state to another. When it’s called, the app should inspect the properties of the passed assetInfo object.

Note: AssetInfo.getEstimatedSize() is just an estimation. Offline Manager does not have the actual asset size. However, this value can be used to show info to the user before download has started.

#####onAssetRemoved(@NonNull String assetId, @NonNull DownloadType downloadType)

Called when an asset has been successfully removed, normally after the app has called OfflineManager.removeAsset().

#####onAssetRemoveError(@NonNull String assetId, @NonNull DownloadType downloadType, @NonNull Exception error)

Called when there is an error while deleting the asset.

#####onAssetDownloadFailed(@NonNull String assetId, @NonNull DownloadType downloadType, @NonNull Exception error)

Called when an asset has failed to download – could be as a result of network/server error or some kind of misconfiguration. The error parameter will have move info on the error.

#####onAssetDownloadComplete(@NonNull String assetId, @NonNull DownloadType downloadType)

This method is called to signal that the asset has finished downloading and is ready for viewing.

#####onAssetPrefetchComplete(@NonNull String assetId, @NonNull DownloadType downloadType)

This method is called to signal that the asset is prefetched.

#####onAssetDownloadPending(@NonNull String assetId, @NonNull DownloadType downloadType)

When the asset is in QUEUED State. Applicable only for ExoOfflineManager

#####onAssetDownloadPaused(@NonNull String assetId, @NonNull DownloadType downloadType)

The mentioned asset is paused.

#####onRegistered(@NonNull String assetId, @NonNull DrmStatus drmStatus)

DRM registration (AKA license acquisition) is done. drmStatus will contain the timing restrictions that apply.

#####onRegisterError(@NonNull String assetId, @NonNull DownloadType downloadType, @NonNull Exception error)

DRM registration has failed, and error will have more info.

Download Progress Listener

In addition to the state listener, there’s also a download progress listener. This listener contains one method that is called whenever the download progresses.

public interface DownloadProgressListener {
    void onDownloadProgress(@NonNull String assetId, long bytesDownloaded, long totalBytesEstimated, float percentDownloaded);
}

Properties and OfflineManagerSettings

Kaltura

These settings are only applicable if the app uses Offline Manager’s Kaltura bindings.

Kaltura Params
void setKalturaParams(KalturaPlayer.Type type, int partnerId)

type can be either KalturaPlayer.Type.ovp or KalturaPlayer.Type.ott, depending on the application type partnerId is the Kaltura Partner ID.

Kaltura Server URL
void setKalturaServerUrl(String url)

url should be set as follows:

Note: if Kaltura Player was loaded properly, it should be enough to call setKalturaParams(). Offline Manager will get the server URL from the cached response.

KS
void setKs(@Nullable String ks)

If the application requires login for download or playback, it must supply a KS which will be used to authenticate to Kaltura backend.

Preferred Media Format

void setPreferredMediaFormat(@Nullable PKMediaFormat preferredMediaFormat)

Offline Manager can download both HLS and DASH assets, automatically selected depending on availability. By default, DASH is preferred. The valid values for preferredMediaFormat are PKMediaFormat.dash and PKMediaFormat.hls. PKMediaFormat contains other types, but Offline Manager does not support them.

OfflineManagerSettings

App can pass this using setOfflineManagerSettings on OfflineManager.

void setEstimatedHlsAudioBitrate(int bitrate)

Alternative audio tracks in HLS don’t have bitrates specified; as a result, when estimating the download size, it’s not possible to estimate the audio size. If the application has out-of-band information on audio bitrate, it should call this method, passing the bitrate. This bitrate is only used for estimating the size of audio tracks that don’t have a specified bitrate.

Note: The value passed to this setter does not change the actual bitrate; it just helps Offline Manager to give a better estimate.

We have other settings as well,

int maxDownloadRetries - Default value is 5.

int httpTimeoutMillis - Default value is 15 seconds.

int maxConcurrentDownloads - Default value is 4.

long freeDiskSpaceRequiredBytes - Default value is 400 MB, valid only for DTG Offline provider.

boolean createNoMediaFileInDownloadsDir - Default value is true.

boolean crossProtocolRedirectEnabled - Default value is true.

Application can pass custom request params for the following network calls.

DownloadRequestParams.Adapter downloadRequestAdapter - Allows adapting the request parameters before sending the request to the server.

DownloadRequestParams.Adapter chunksUrlAdapter - Allows adapting the chunk request parameters before sending the request to the server. This is only being supported in DTG Offline provider.

PKRequestParams.Adapter licenseRequestAdapter - Allows adapting the license request parameters before sending the request to the license server.

Download

Prepare

Call one of the overloads of OfflineManager.prepareAsset() to prepare an asset for download. This includes:

When done, Offline Manager calls the passed prepareCallback with the results of preparation; after PrepareCallback.onPrepared() is called, the download can be started.

Example
offlineManager?.prepareAsset(
                    item.mediaOptions(),
                    item.selectionPrefs ?: defaultPrefs,
                    prepareCallback
            )

Start

Call OfflineManager.startAssetDownload() to start the download. This method can only be called after a successful preparation.

Pause and Resume

Call pauseAssetDownload() and resumeAssetDownload() to pause and resume downloading an asset, respectively.

Remove

When the user wants to remove an asset from the device, call OfflineManager.removeAsset(). It will remove all of the assets and info related to the asset.

Get All Assets

App can get all the assets using getAllAssets(DownloadType... downloadType). DownloadType can be FULL here.

Prefetch

This feature let the app to download the initial part of the asset. It will help to start the playback without any initial loading because the initial part of the asset is already downloaded. Once the prefetched part of the asset completes the offline playback then it does the transition to the online playback seemlessly.

Prefetch Manager

PrefetchManager is wrapped around OfflineManager, it can be setup using the OfflineManager API.

PrefetchManager prefetchManager = offlineManager.getPrefetchManager(PrefetchConfig prefetchConfig);

App can take benefit of PrefetchConfig to customize the prefetch properties,

Prefetch Configuration

maxItemCountInCache - Maximum number of assets for prefetching in cache. Default is 20.

assetPrefetchSize - In Megabytes, Default is 2. Initial 2 MB chunks of the asset will be downloaded.

cleanPrefetchedAssets - Default is true. Remove all the prefetched assets.

It will be used in two scenarios.

PrefetchManager APIs

void setPrefetchConfig(PrefetchConfig prefetchConfig)

Set the Prefetch config for PrefetchManager apart from passing the same in PrefetchManager constructor.

boolean isPrefetched(@NonNull String assetId)

Checks if the asset is already prefetched.

List<OfflineManager.AssetInfo> getAllAssets(DownloadType... downloadType)

Get all the assets which are already prefetched. DownloadType can be PREFETCH here.

OfflineManager.AssetInfo getAssetInfoByAssetId(@NonNull String assetId)

Get the asset info as per assetId.

void removeAsset(@NonNull String assetId)

Remove the specific asset. Applicable for both prefetch state and downloading state asset.

void removeAllAssets()

Remove all the assets. Applicable for both prefetch state and downloading state assets.

void cancelAsset(@NonNull String assetId)

Cancel a specific asset. Applicable only if the asset is being downloaded.

void cancelAllAssets()

Cancel all the assets. Applicable only for those assets which are being downloaded.

void prefetchAsset(@NonNull PKMediaEntry mediaEntry, @NonNull OfflineManager.SelectionPrefs selectionPrefs, @NonNull OfflineManager.PrepareCallback prefetchCallback)

Prefetch an asset. Select the best source from the entry, load the source metadata, select tracks based on the prefetchConfig, call the listener. Throws IllegalStateException.

void prefetchAsset(@NonNull MediaOptions mediaOptions, @NonNull OfflineManager.SelectionPrefs selectionPrefs, @NonNull OfflineManager.PrepareCallback prefetchCallback)

Prefetch an asset. Connect to Kaltura Backend to load entry metadata, select the best source from the entry, load the source metadata, select tracks based on the prefetchConfig, call the listener. If the asset requires KS, make sure to set MediaOptions. Before calling this method, the partner id and the server URL must be set by setKalturaParams(KalturaPlayer.Type, int) and setKalturaServerUrl(String), respectively. Throws IllegalStateException.

void prefetchByMediaOptionsList(@NonNull List<MediaOptions> mediaOptions, @NonNull OfflineManager.SelectionPrefs selectionPrefs, @NonNull OfflineManager.PrepareCallback prefetchCallback)

Prefetch the list of assets. It connects to Kaltura Backend to load entry metadata.

void prefetchByMediaEntryList(@NonNull List<PKMediaEntry> mediaEntryList, @NonNull OfflineManager.SelectionPrefs selectionPrefs, @NonNull OfflineManager.PrepareCallback prefetchCallback)

Prefetch the list of assets.

Getting Prefetch Callback

App can listen to the callbacks. Callback parameter is required for prefetchAsset API. It is the same as OfflineManager callback.

void onPrepared(@NonNull String assetId, @NonNull AssetInfo assetInfo, @Nullable Map<TrackType, List<Track>> selected);

Called when the asset is prefetched.

void onPrepareError(@NonNull String assetId, OfflineManager.DownloadType downloadType, Exception error);

Called when asset has failed for some reason. App can check DownloadType.PREFETCH.

Example

Prefetch callback creation,

val prepareCallback = object : OfflineManager.PrepareCallback {
            override fun onPrepared(
                    assetId: String,
                    assetInfo: OfflineManager.AssetInfo,
                    selected: MutableMap<OfflineManager.TrackType, MutableList<OfflineManager.Track>>?
            ) {}

            override fun onPrepareError(
                    assetId: String,
                    downloadType: OfflineManager.DownloadType,
                    error: Exception
            ) {}

            override fun onMediaEntryLoadError(
                    downloadType: OfflineManager.DownloadType,
                    error: Exception
            ) {}

            override fun onMediaEntryLoaded(
                    assetId: String,
                    downloadType: OfflineManager.DownloadType,
                    mediaEntry: PKMediaEntry
            ) {}

            override fun onSourceSelected(
                    assetId: String,
                    source: PKMediaSource,
                    drmParams: PKDrmParams?
            ) {}
        }

prefetchManager.prefetchAsset(item.mediaOptions(), new PrefetchConfig(), prefetchCallback)

App can pass the SelectionPrefs via PrefetchConfig.

prefetchManager.prefetchAsset(entry, PrefetchConfig().setSelectionPrefs(defaultPrefs), prefetchCallback)

Status bar Notification

Create single notification when the download is in progress. When EXO offline download provider is used. This is a must because we are using a foreground service for prefetch. App can either take this single notification and show the progress with the accumulated progress on one notification. OR else app can show one notification using this callback and for other download’s notifications; app can use offline provider’s call back to create other notification. Use setForegroundNotification(ExoOfflineNotificationHelper notification) api on OfflineManager to set notification.

Notication is not required for DTG OfflineProvider apps.

Playback

After a successful download, the asset can be played in Kaltura Player. The player requires a PKMediaEntry object - call OfflineManager.getLocalPlaybackEntry() to get a Media Entry ready to play. This object can be passed directly to KalturaPlayer.setMedia(). In case of Prefetch, if app tries to play the asset online and the asset is prefetched and it starts the playback from downloaded media then it gets seemlessly transitioned to the online playback.

DRM

During the initial download, Offline Manager takes care of acquiring a DRM license, if required. However, the license may expire before the user is done with it. If the application allows the license to be renewed, it must call one of the overloads of OfflineManager.renewDrmAssetLicense() and monitor the result of AssetStateListener.onRegistered() and AssetStateListener.onRegisterError().

In case of Prefetch, once the prefetch is complete then PrefetchManager takes of aquiring the DRM license, if required. On removal of the assets, it takes care of drm license removal as well.

Sample Code

[OfflineManager Sample] (https://github.com/kaltura/kaltura-player-android-samples/tree/master/OfflineDemo)

[PrefetchManager Sample] (https://github.com/kaltura/kaltura-player-android-samples/tree/master/AdvancedSamples)