Offline Playback with the Native Player SDKs

In this topic, you will learn how offline playback works with the Brightcove Native Player SDKs.

Overview

Offline Playback with the Brightcove Native Player SDKs for iOS and Android allows publishers to reach their viewers in entirely new ways while ensuring their content remains secure. Our SDKs offer powerfully simple solutions for complex offline playback problems including download management, offline catalog management, analytics, DRM, and of course playback.

Using offline playback, users can download both DRM-protected and clear (non-encrypted) video content to their devices and watch it when they are not connected.

Requirements

The Brightcove Native Player SDKs support offline playback with the following versions:

Brightcove Native SDK version

  • Native SDK for Android 7.0.1 or newer
  • Native SDK for iOS 6.0.1 or newer

Device OS version

  • Android 5.0+
  • iOS 10.0+, but 10.3+ is recommended

Setup

To get started, do the following:

  • Contact your account manager to enable your account for offline playback.
  • Make sure to use Dynamic Delivery when ingesting your videos.
  • Prepare each video that you want enabled for download.
  • Add the Offline-Playback plugin in your build.gradle file manually:
              
                 
                dependencies {
                  implementation "com.brightcove.player:offline-playback:[SDK_VERSION]"
                }
              
          
  • In the activity where Brightcove Player lives, set a MediaStore through the ExoPlayerVideoDisplayComponent class:
             
            
             val videoDisplayComponent = baseVideoView.videoDisplay as ExoPlayerVideoDisplayComponent?
              videoDisplayComponent?.let {
                videoDisplayComponent.setMediaStore = OfflineStoreManager.getInstance(this)
              }
          
      

Content delivery

Streaming video takes advantage of Video Cloud's multi-bitrate streaming feature which detects bandwidth at the source and delivers the best quality for the device. The offline playback feature supports the following streaming types:

  • Android: Dynamic Adaptive Streaming over HTTP (DASH)
  • iOS: Apple HTTP Live Streaming (HLS)

Rendition downloaded

You may be wondering which rendition is downloaded and used for Offline Playback. Here is the answer:

  • Android - The ExoPlayer sets the default rendition. To find the current rendition, listen to the ExoPlayerVideoDisplayComponent.RENDITION_CHANGED event.

    Internally, the Native SDK for Android uses the DefaultTrackSelector. You can set the peak bitrate for downloading as follows, in your OfflineCatalog object:

    catalog.setVideoBitrate(peakDownloadBitrateInBytes);

  • iOS - If you do not specify a bitrate for your download, you will get the lowest rendition that has a video track.

    To pick a specific variant based on the bitrate or resolution, see the Specifying a Variant Bitrate section of the SDK reference.

Security

The protection of downloaded content is top-of-mind with our Offline solution. The Brightcove Native Player SDKs provide the following functionality to ensure your content is stored safely on viewers' devices:

DRM-protected content

  • For DRM-protected content, the Native SDKs use the following technologies:
  • Video content can only be watched on the device and app that has downloaded the content.

  • Video content can only be watched until a specific date and time expiration.

    The Native SDKs allow users to rent or buy videos. The expiration applies to rentals, and is set in the DRM license using the Native SDKs API for downloading videos. In contrast, the expiration set in the Fastly token applies to streaming content.

    Videos can be viewed within the defined rental period, no matter how long or short. The SDKs store the expiration date as a 32-bit signed integer with a maximum value of 2,147,483,647. For detailed examples, see the Samples section.

  • Video URLs returned to the client will expire so that others can not use them.

All content

  • When the app is deleted, all downloaded content is removed.
  • Your app can delete locally stored content at any time.

Download management

The Brightcove Native Player SDKs handle the complexities of downloading content to a viewer's device, greatly simplifying the process for native applications.

Functionality

The following functionality can be added to your apps to support download management:

Display content

Display a list of content available for streaming or download.

When you set a video's offline_enabled property to true, the Native SDKs will mark this video as downloadable.

Prepare videos

To mark a video as downloadable, you need to do the following:

  1. If you haven't done so already, contact your account manager to enable your account for offline playback.
  2. For each video that you want to be downloadable, set offline enabled by doing one of the following:

    Use Video Cloud Studio

    Use Video Cloud Studio to enable offline playback.

    Offline enabled
    Offline enabled

    Use CMS API

    You can also use the CMS API to set the offline_enabled field to a value of true.

    Here is an example using curl:

      curl --header "Authorization: Bearer $oauth_token" --request PATCH --data '
      {"offline_enabled" : true}
      ' https://cms.api.brightcove.com/v1/accounts/your account id/videos/your video id
Display content
Display content

When working with clear content, see the Best practices section for tips on how to display your content.

Check download size

Brightcove recommends that before a download is requested, you make sure there is enough space in device storage for the download. To get an estimate of the total size of the video download, follow these steps:

  • For iOS, review the information in the Check Download Size section of the iOS App Developer's Guide to Offline Playback.
  • For Android, you can get an estimate in the OnDownloadStarted callback from the DownloadEventListener. Here is an example of how to set the event listener:

      MediaDownloadable.DownloadEventListener downloadEventListener = new MediaDownloadable.DownloadEventListener() {
      //Your implementation.
      }
      OfflineCatalog catalog = new OfflineCatalog(context, eventEmitter, accountId, policyKey);
      catalog.addDownloadEventListener(downloadEventListener);

 

Show local storage space

Inform the user when there is not enough local storage to complete downloading the current item and any items in the queue.

The SDKs provide the estimated size and progress so that you can determine if there is sufficient space for downloads.

Show download status

Display the current download along with its status.

Total estimated size, current download status and percent of downloading progress information will be returned by the SDKs.

Manage downloads

Downloading multiple videos

The Native SDKs will allow multiple videos to be queued for downloads. For example, a user can download multiple episodes of a season and the Native SDKs will manage the process by providing download status for each asset.

Downloading secondary tracks (iOS)

With iOS 13, Apple has changed how downloads work. For details, see the iOS App Developer's Guide to Video Downloading and Offline Playback guide.

Because of this change, the iOS Offline Download sample app may appear to re-download videos with multiple audio tracks. This is because download progress is given for each track. So, the progress bar will start again from zero for each additional audio track.

Here's a brief overview of AVMediaSelectionOptions, subtitles and alternative audio tracks: Adding Subtitles and Alternative Audio Tracks

Determine total download

Is there any way to get didProgressTo for total download for one video token?

No. For a video offline token, there is no aggregated download progress value. The app developer determines how many asset downloads will occur. The first asset download is the main video and the preferred audio and text tracks. It is typically the largest download and progress will advance from 0.00 to 100.00.

If a download request includes additional media selections (which the app developer explicitly requests), the total download time is simply that of the main video and preferred media selection, plus that of each additional media selection. When representing total progress in the UI, chose a scale value for each download such that the sum of all downloads will total 100% and sum the scaled download times of each media selection.

Identify object types

Is there any way to identify which type of object(video or text track) each didProgressTo events related to?

Yes. The additional downloads are of Apple Media Selection Option objects (AVMediaSelectionOption), not tracks. The media selection object being downloaded is identified in the progress callback. (BCOVOfflineVideoManagerDelegate.h)

Apple provides methods for examining the attributes of a media selection option. For details, see Apple's AVMediaSelectionOption.

You can see metadata values in the Xcode debugger console when running the OfflinePlayer sample app (don't be misled by the two English options - it's just a sample app)

OfflinePlayer[523:355259] AVMediaSelection option 0 | legible display name: English
OfflinePlayer[523:355259] AVMediaSelection option 0 | audible display name: English
OfflinePlayer[523:355259] AVMediaSelection option 1 | legible display name: English
OfflinePlayer[523:355259] AVMediaSelection option 1 | audible display name: English

You can see how that's done in the DownloadManager code.

Pause/resume/cancel download

Allow the user to pause, resume or cancel content download.

Download functionality will resume where it left off if the user pauses/resumes or if the download is interrupted. For example, it you lose Wi-Fi connection during download, it will resume where it left off when you are reconnected.

If you cancel a video download, then any progress made will be erased.

Local catalog management

The Brightcove Native Player SDKs simplify the process of managing downloaded local content.

The following functionality can be added to your apps to support local catalog management:

Show downloaded content

Show all of the downloaded episodes for each show/season.

The SDKs return metadata and playback details for all downloaded content. This metadata includes video title, description, thumbnails, available captions, available audio tracks, etc.

There are new metadata properties specific to offline playback, which include the following:

DRM-protected content

  • Token identifier
  • License expiration date

All content

  • Download start and end time
  • Downloaded thumbnail name along with its file URL
  • Downloaded poster name along with its file URL
  • Relative and derived file URL of the video bundle

You can then filter the results for your specific implementation.

Delete local content

Allow users to delete content from local storage.

The SDKs expose a method to delete a video along with its metadata and related assets.

Content playback

The Native SDKs allow you to play content in the following situations:

  • Play a video while it downloads.
  • Play a video after it has been downloaded. Downloaded content can be played back locally when the device is offline or online. The offline video can only be played from local storage.
  • If you choose to stream an online version of the video, you should retrieve a new video object from the Playback Service.

Analytics

Analytics have been introduced for measuring data related to the Offline flow. For details, see the Analytics Related to Offline Playback with the Native SDKs document.

Samples

The following table contains links to code samples to show you how to get started with offline playback:

Sample Application Description
iOS Offline Playback Download and play HLS videos, including those protected with FairPlay encryption. For developer details, see the iOS App Developers Guide for Offline Playback.
Android Offline Playback Download and play DASH videos, including those protected with Widevine encryption.

FAQ

Below you will find answers to some general questions.

DRM-protected content

Can the user change the system clock to bypass the expiration date?

Android: Absolute expiration determines the date and time until which a license is valid. This is enforced by Widevine and the Android DRM layer. Theoretically, the DRM layer in Android must prevent the user from bypassing the expiration period. Any issues that we may have found is described in the Android OS release notes.

iOS: License expiration is enforced by FairPlay. iOS handles all checking for clock changes, etc. An app has the option of checking the license expiration to alert the user that the license has expired. This may be preferable to simply playing back an expired video and then receiving a playback error.


Will the license and offline videos continue loading while the app is in the background?

Android: Yes. Typically, the license is downloaded immediately, but even the license can be downloaded while the app is backgrounded.

iOS: License loading should happen in the foreground. We have a method to preload the license. Downloading of the main video content can happen while the app is in the background.

All content

What is the video format used for downloading offline content?

Android: DRM-protected DASH or non-encrypted DASH.

iOS: HLS steaming. You can specify a bitrate for the download to use a specific variant.


Will downloaded videos playback locally or streaming when the user is online?

A downloaded video can be played back while online or offline, but it will always use the downloaded video. If you choose to play back an online version of the video, you should retrieve a new video object from the Playback Service. The offline video can only be played from local storage.


Best practices

The following guidelines should help when developing your app for offline playback.

Displaying pause/cancel buttons

The pause and cancel buttons should be displayed when video download has started.

Android: You should display the pause and cancel buttons as part of calling the onDownloadStarted callback in the DownloadEventListener. For details, see the Offline Playback sample app.

iOS: For details about how to create an app for Offline Playback, see the iOS App Developer's Guide.

Displaying clear content

If your account is not DRM-enabled or you are working with clear content, the Brightcove Native SDKs will not perform a server-side license request. Therefore, clear content is not considered available for rental or purchase. In most cases, for clear content, it is recommended that you hide the rent and buy buttons and display a single download button instead.

Enabling the feature

Contact your account manager to learn about pricing and to enable the Offline Playback feature for your account.

Troubleshooting

The following tips may help you to investigate issues when downloading videos.

An error may occur when a user tries to download an asset at a higher bitrate than the device can handle due to a slow network.

To avoid this, you could add code to check device capabilities and prevent devices on slow connections from attempting to download high bitrate assets. You can test with a real device while throttling the connection, and view the network traffic with the Charles proxy tool.

Android

For details about handling errors, see the Error Messages from the Native SDK for Android document. This includes error messages related to offline playback.

iOS

For details about handling errors, see the Error Handling with the Native SDK for iOS document.

When the offline playback code receives an error, we catch it and throw an NSError. To get the underlying error, you can try this:

  NSError *underlyingError = initialError.userInfo[NSUnderlyingErrorKey];

For more information, see the iOS App Developers Guide for Offline Playback.

Known issues

For a list of known issues for the Android and iOS operating systems that affect Offline Playback with the Native SDKs, see the Known Issues support document.

Notes and limitations

The following notes apply to the offline playback feature supported by the Native SDKs:

Advertising

Neither client-side nor server-side advertising is supported with offline playback.

HLSe

HLSe content is not supported with offline playback using the Brightcove Native SDK for Android, iOS or tvOS.

Low power mode

Low power mode on devices may affect certain features, including downloading. For more information, see the following:

Shared videos

Shared videos can be downloaded for offline viewing only if the original video can be. The property is inherited from the original video and cannot be changed for shared video only.

Audio-only

The Native SDKs support audio-only content with Offline Playback. You control what viewers see, whether it is a poster image or a custom screen.

The Native SDK for Android requires a VideoView, and the Native SDK for iOS requires a UIView. Because of this, background audio is not supported. This means that audio will not keep playing when a user sends the app to the background.

Android: App deletion

When the app is deleted, all downloaded content is removed. This is true as long as the default storage location is not overridden.

iOS: AirPlay

As a security feature, you cannot stream an offline HLS video to an AirPlay device for playback. This is confirmed by Apple to be an AVFoundation limitation.