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 provider
OfflineManager.OfflineProvider.EXO
. So in order to use this feature createOfflineManager
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 onOfflineManager
.
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:
- OVP applications shouldn’t normally set it, unless using an on-prem installation of the backend. The default is the Kaltura SaaS.
- OTT applications must set it to an OTT REST URL, such as
https://rest-as.ott.kaltura.com
.
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
.
- HLS Audio Bitrate - Only applicable for DTG Offline provider.
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:
- Connecting to Kaltura backend to get the list of sources and DRM configuration
- Connecting to the asset’s server to download the manifest
- Selecting the appropriate tracks for download, based on the passed selection preferences and the available tracks.
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.
-
If this flag is
true
and application callsofflineManager.stop()
inonDestroy()
of its lifecycle then once the app quits then we remove all the prefetched assets. -
In case, if
onDestroy()
is not called during the app lifecycle and we were not able to remove the prefetched assets then when app callsofflineManager.getPrefetchManager(PrefetchConfig prefetchConfig)
with this configtrue
, we remove the assets at the time ofPrefetchManager
initialization.
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)