Offline downloads using the VdoCipher Flutter Package
Overview
The VdoCipher Flutter Package offers capability to download videos to local storage for offline playback on Android devices running Lollipop and above (API level 20+).
It includes APIs to :
- Fetch available download options for a video in your dashboard
- Download media assets to local storage
- Track download progress
- Manage downloads (query or delete downloads)
Note: Ensure android.permission.FOREGROUND_SERVICE_DATA_SYNC is declared in the manifest for download to work when target SDK version is set as 34 and higher.
Add the below permission in the android/app/src/main/AndroidManifest.xml
-
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
Generating OTP for Offline Playback
To initialize video playback on website or app, your backend has to generate
an OTP
+playbackInfo
using the VdoCipher API. The regular OTP does
not have permission to be persisted offline. To enable offline playback you
will need to send additional parameters while making the API call for the OTP.
You can specify the time period for which the offline download will be available for playback. The time period of validity is called the rental duration. Beyond the rental duration the license will expire, and the downloaded file will no longer play.
You can find more details on the OTP-based playback mechanism at the API page.
Get the available options for a media
A video in your VdoCipher dashboard may be encoded in multiple bitrates (for adaptive streaming). Hence, there are some options regarding what exactly needs to be downloaded. As adaptive playback is not possible in offline mode, you must download exactly one video track and one audio track.
The first step is to get the available options for the media. We'll use the OptionsDownloader
class for this. We'll need a playbackInfo
and otp
corresponding to the video to fetch the options.
OptionsDownloader optionsDownloader = new OptionsDownloader();
optionsDownloader.downloadOptionsWithOtp(
otp, playbackInfo, customPlayerId, (downloadOptions) {
// we have received the available download options
}, (vdoError) {
// there was an error downloading the available options
});
A DownloadOptions
object contains a MediaInfo
object (with general information about the media, such as title and description) and a list of VideoTrack
and AudioTrack
. These tracks contain relevant information such as bitrate, resolution, language, etc.
Once we've obtained the available options, the next step is to make a selection of which tracks to download.
Select the tracks to download
As mentioned previously, we must select exactly one audio track and one video track. As soon as we have the download options, we can either make selections automatically based on user preferences (e.g. select the highest quality/bitrate) or present the options to the user to select.
Once a selection has been made (automatically or by the user), make a DownloadSelections
object using the options we received in the previous step and the indexes of the audio and video track we want to download from the provided AudioTrack
and VideoTrack
list in DownloadOptions
.
// `audioTrackIndex` and `videoTrackIndex` is the track index from `downloadOptions.allAudio` and `downloadOptions.allVideo` respectively
DownloadSelections downloadSelections = new DownloadSelections(downloadOptions, videoTrackIndex, audioTrackIndex);
Enqueue request for download
The VdoDownloadManager
class handles enqueuing requests for download.
Now that we have made the selctions specifying which tracks to download. Next step is to create a DownloadRequest
using DownloadSelections
.
//Create download request object from download selections
DownloadRequest downloadRequest = new DownloadRequest(downloadSelections);
//If you are using safetynet, set safetynet API key like this
downloadRequest.safetyNetApiKey = API_KEY; //your api key
The above section contains information on setting up SafetyNet with media download, which is no longer recommended and not supported in our latest package. Play integrity is now the recommended way for device attestation. Please get in touch with us through Support to use Play integrity.
Now we have a DownloadRequest
that can be enqueued for download right away.
// enqueue request to VdoDownloadManager for download
VdoDownloadManager vdoDownloadManager = VdoDownloadManager.getInstance();
vdoDownloadManager.enqueue(downloadRequest);
This will add the request to the download queue and start download when the requirements for downloads to progress are met.
Monitoring download progress
We can monitor the progress of the download queue by registering a EventListener
with the VdoDownloadManager
.
// register a listener for download events
VdoDownloadManager vdoDownloadManager = VdoDownloadManager.getInstance();
vdoDownloadManager.addDownloadEventListener(eventListener);
// don't forget to de-register the listener
vdoDownloadManager.removeDownloadEventListener(eventListener);
Query for downloads
VdoDownloadManager
allows querying for all downloads managed by it or only specific downloads specified by filters.
Queries provide status of all downloads that are queued or downloding or completed. Make a Query
object and specify any filters you want.
Query query = new Query();
// set mediaId filters if these are the only videos for which you want the status
query.filterByMediaId([mediaId1, mediaId2]);
// set filters by status
// let's filter for downloads which are paused and downloading
query.filterByStatus([VdoDownloadManager.STATUS_PAUSED, VdoDownloadManager.STATUS_DOWNLOADING]);
Now we can use this query object to query status for the specified downloads like this.
List<DownloadStatus> downloadStatusList = await vdoDownloadManager.query(query);
A query result is provided as a future of DownloadStatus
list, DownloadStatus
objects provides information such as the MediaInfo
, status, any errors if they occured while downloading, etc.
Offline Playback
For playing downloaded videos, the initial step involves creating an EmbedInfo for offline playback. This EmbedInfo is then utilized in conjunction with the VdoPlayer.
import 'package:vdocipher_flutter/vdocipher_flutter.dart';
// Utilize the mediaId of the downloaded video.
EmbedInfo embedInfo = EmbedInfo.offline(mediaId: mediaId);
Widget playerWidget = VdoPlayer(
embedInfo: embedInfo,
onPlayerCreated: (controller) => _onPlayerCreated(controller),
onFullscreenChange: _onFullscreenChange,
onError: _onVdoError,
);
Note: Ensure to substitute mediaId
with the actual media ID of the downloaded video.
Delete downloads
To delete a media download use the remove()
method of VdoDownloadManager
. This will cancel the download if it is still downloading or pending and remove any downloaded media files. You will also receive a onDeleted()
callback if you have an EventListener
registered with the VdoDownloadManager
.
VdoDownloadManager vdoDownloadManager = VdoDownloadManager.getInstance();
vdoDownloadManager.remove(mediaId);
Pause downloads
To pause a media download use the stopDownload()
method of VdoDownloadManager
. You will also receive an onChanged()
callback if you have an EventListener
registered with the VdoDownloadManager
.
VdoDownloadManager vdoDownloadManager = VdoDownloadManager.getInstance();
vdoDownloadManager.stopDownload(mediaId);
Resume downloads
To resume a media download use the resumeDownload()
method of VdoDownloadManager
. You will also receive a onChanged()
callback if you have an EventListener
registered with the VdoDownloadManager
.
VdoDownloadManager vdoDownloadManager = VdoDownloadManager.getInstance();
vdoDownloadManager.resumeDownload(mediaId);
Check if video is expired
Not supported in iOS
To check if a video is expired, use the DownloadStatus.isExpired()
method. This will return true or false based on whether the provided media id is expired or not.
// Call isExpired() method on downloadStatus object to check for expiry.
bool isExpired = await downloadStatus.isExpired();
if (isExpired) {
// Either re-download the video or remove the video.
}
- If the video is expired, adjust the UI accordingly. Avoid playing the expired video to prevent displaying error code 6187 along with a message; the error message will provide viewers with context about the video expiration.
- For expired video, you can choose to either re-download the video or remove the video.