Offline Playback
This tutorial will walk you through the facilities that the Bitmovin Player React Native SDK offers for working with offline content and offline playback.
Manage Offline Content For Playback
One of the challenges of enabling offline playback is downloading and managing assets. The Bitmovin SDK provides the ability to download content, as well as to pause, resume and cancel downloads. It also enables downloaded content to be deleted. These operations are provided via the OfflineContentManager
API, which is responsible for managing the state of the assets.
Setup
Android
In order to use offline functionality, the following dependency must be added manually to the build.gradle
file:
implementation("androidx.localbroadcastmanager:localbroadcastmanager:1.1.0")
Additionally, the permission for checking the network state is required in the Android Manifest:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Depending on the location the offline data is saved, it may also be required to add the STORAGE permission to the Android Manifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
iOS
In order to enable the Offline Feature in an iOS application, the following changes has to be made on the native side of the React Native application.
Note
The Offline Feature is not available in iOS simulators due to missing support from Apple for downloading content in the simulator environments.
Initialize the OfflineManager
You first need to initialize the singleton class OfflineManager
in your AppDelegate
class. To do so, you add the following code snippet in the application(_:didFinishLaunchingWithOptions:)
method:
OfflineManager.initializeOfflineManager()
App Lifecycle Support
In order to appropriately handle application lifecycle events, such as the application going into background, add the following code into application(_:handleEventsForBackgroundURLSession:completionHandler:)
in your AppDelegate
:
OfflineManager.sharedInstance().add(completionHandler: completionHandler, for: identifier)
API Usage
The core component responsible for handling offline content is the OfflineContentManager
. It allows fetching the current offline state, managing offline content and requesting state changes.
OfflineContentManager
One OfflineContentManager
is linked with one SourceConfig
. When instantiating an OfflineContentManager
, it is required to provide a unique ID for the content and the SourceConfig
.
const offlineContentManager = new OfflineContentManager({
identifier: '<UNIQUE-CONTENT-ID>',
sourceConfig: sourceConfig,
});
OfflineContentManager
has to be initialized before first interaction, using:
offlineContentManager
.initialize()
.then(() => console.log('Offline Content Manager is ready to use'));
OfflineContentManagerListener
Listeners can be added to OfflineContentManager
via addListener
API, which returns a function that removes this listener from the OfflineContentManager
that registered it when called.
const removeOfflineContentManagerListener = offlineContentManager.addListener({
onOptionsAvailable: (e) => console.log('Options available'),
onProgress: (e) => console.log(`Progress: ${e.progress}`),
onCompleted: (e) => console.log('Download has finished'),
onError: (e) => console.log(`Error happened: ${e.message}`),
onDrmLicenseUpdated: (e) => console.log('DRM license updated'),
onDrmLicenseExpired: (e) => console.log('DRM license expired'),
onResumed: (e) => console.log('Download resumed'),
onSuspended: (e) => console.log('Download suspended'),
onCanceled: (e) => console.log('Download canceled'),
});
// Call this to remove the listener:
removeOfflineContentManagerListener();
The OfflineContentManagerListener
provides seven callbacks:
- onOptionsAvailable is called after a
getOptions
call. - onProgress is called when the progress for an ongoing operation has changed, e.g. the download progress.
- onCompleted is called when downloading has completed.
- onError is called when an error occurs.
- onDrmLicenseUpdated is called when the stored DRM license was updated.
- onDrmLicenseExpired is called when the stored DRM license was updated. This is only supported on iOS.
- onSuspended is called when download has been suspended.
- onResumed is called when download has been resumed.
- onCanceled is called when download has been canceled.
OfflineContentOptions
OfflineContentOptions
can be received by calling getOptions
on the OfflineContentManager
. OfflineContentOptions
represent the downloadable tracks for a stream with the available tracks for audio and captions/subtitles.
Downloading Content
Once an OfflineContentManger
is created, downloading of content can be started. To gain knowledge of the available audio and subtitle tracks, getOptions
should be called:
offlineContentManager.getOptions()
As this is an asynchronous call, the response must be handled in the OfflineContentManagerListener
callback:
const removeOfflineContentManagerListener = offlineContentManager.addListener({
onOptionsAvailable: (e) => {
console.log('Options available');
// Select desired tracks for download
},
});
To start a download, first construct an OfflineDownloadRequest
, using values from OfflineContentOptions
then call offlineContentManager.download()
with the request object.
const offlineOptions: OfflineContentOptions; // value from `onOptionsAvailable`
const downloadRequest: OfflineDownloadRequest = {
minimumBitrate: 800000, // Download video with nearest higher available bitrate
audioOptionIds: offlineOptions?.audioOptions.map((option) => option.id), // Download all audio tracks
textOptionIds: offlineOptions?.textOptions.map((option) => option.id), // Download all text tracks
};
offlineContentManager.download(downloadRequest)
Download DRM protected content
For offline download and playback we support the same DRM solutions as presented in our related guide.
Playing Offline Content
In order to play the downloaded content, you only need to load the offline content into the player:
player.loadOfflineContent(offlineContentManager);
OfflineState
You can check the state of the download operation anytime by calling the OfflineContentManager
's state()
API, which is very useful for checking on the state of an asset before performing further actions. For example, checking the asset's offline state before updating the UI or allowing the user to cancel a download:
const offlineState = await offlineContentManager.state()
switch (offlineState) {
case OfflineState.NotDownloaded:
// Content is not downloaded
break;
case OfflineState.Downloading:
// Content is currently downloading
break;
case OfflineState.Suspended:
// Content download is suspended
break;
case OfflineState.Downloaded:
// Content is downloaded
break;
}
Summary
With the solutions mentioned in this guide you will be able to download, manage and play content without internet connection on your iOS and Android devices.
See OfflinePlayback.tsx for a full example implementation on how to use the Offline Feature.
Updated about 1 year ago