The CONNECT Player for Android SDK 5.x (SDK 5) is NAGRA’s latest player product for Android. Although the architecture has changed, the API remains similar to the previous version (NAGRA Media Player SDK for Android 4.x or SDK 4). Internally, the main difference in architecture is the use of ExoPlayer as the basic player instead of a native player. Along with this document which highlights the differences, we advise you to follow the Android SDK 5 Example Code Quick Start guide and try to build some of the example code demos.

Integration differences

Much of the API changes are in the naming of the packages, classes and methods. Although there are still two main classes providing access to a CONNECT player instance - OTVVideoView and OTVMediaPlayer, there are some other differences of which to be aware.

Area of difference

SDK 4

SDK 5

SDK NameNMPSDKOTVSDK
SDK library type.jar.aar
Public classes and method namesNMPXxxOTVXxx
Package root namenagra.nmp.sdknagra.otv.sdk
Supported OS Versions4.4+5.0+
Android SDKAPI 23: Android 6.0 (Marshmallow)API 30: Android 11.0 (R)
Java compiler1.8.01.8.0
DRMWidevine
PRM
Widevine
PlayReady
PRM (non-silent mode)
Multi-instanceNoYes*
AndroidX dependencyNoYes
Room persistence library dependencyNoYes
*Some device hardware does not support decoding of multi-instance encrypted content.

Some specific changes are described briefly here; for more details, see the Android SDK 5 Integration Guide.

Setting the OTVVideoView

Unlike SDK 4, the OTVVideoView can and should be created dynamically, not during the creation of the Activity. This allows OTVVideoView to be attached to a UI frame and enables you to use multiple player instances (e.g. for PiP).

Setting up playback

String STREAM_URI = "https://path-to-stream/manifest.mpd";
FrameLayout theFrame = findViewById(R.id.frame);
OTVVideoView theView = new OTVVideoView(this);

// Loading the SDK library
OTVSDK.load(this);

// Set-up player and UI
theView.setVideoPath(STREAM_URI);
theFrame.addView(theView);

// Start/resume playback
theView.start();
JAVA

The OTVVideoView lifespan is therefore aligned with that of the player. Also, when zapping, setVideoPath() can be called rather than destroying a view and replacing it with a new one.

Main UI thread for capturing events

Except for the naming conventions described above, events sent from the SDK and registering for listeners are performed similarly to SDK4. However, to ensure all events are captured, the setting-up of the listeners must be done from the main UI thread. This should not be an issue in normal circumstances where the listeners are set up during an Activity’s onCreate(), or following an interaction with the user via the UI.

Example of setting up a listener

public class MainActivity extends Activity {
  ...
  @Override
  protected void onCreate(Bundle savedInstanceState) {
  ...
  OTVSDK.load(this);
  
  // inside onCreate()
  OTVVideoView theView = new OTVVideoView(this);
  ...
  // Setting up a listener for onCompletion
  theView.setOnCompletionListener(mp -> {
    Toast.makeText(this,"PLAYBACK END",
                    Toast.LENGTH_LONG).show();
  });
  ...
  // Set-up URL and start playback
  ...
  }
...
JAVA

DRM - Widevine

The use of Widevine DRM has been simplified, and you now only need to implement the OTVMediaDrmCallbackinterface and provide a licence server URL. SDK 5 also provides a default implementation of the OTVMediaDrmCallback interface OTVHttpMediaDrmCallback.

When creating the OTVMediaDrmCallback interface implementation, the application passes the licence server URI in the constructor. Extra parameters can then be passed to this object in key-value pairs, using the setKeyRequestProperty(String name, String value) method, such as Content-Type >or Accept. The callback class object can be instantiated once for each player, and some properties can be changed whenever a new asset with its own credentials needs to be played.

If the callbacks provided by the SDK do not meet the requirements for a specific server, you can create a customised version of the callback class.

See the encrypted playback example code provided in the SDK 5 package.

DRM - PlayReady

PlayReady support was introduced in SDK 5 version 5.5.0. Set-up for playback with PlayReady is very similar Widevine; the same callback implementation OTVHttpMediaDrmCallback can be used. Within this implementation, some configuration is slightly different to the one for Widevine. See the encrypted playback example code for PlayReady provided in the SDK 5 package.

Offline playback for PlayReady streams is not yet supported.

DRM - PRM

Similar to Widevine, you now only need to implement the OTVPRMNonSilentCallback interface and provide licence server credentials. SDK 5 provides a default implementation of the OTVPRMNonSilentCallback interface: OTVSSPPRMNonSilentCallback for communication with SSP licence servers (NAGRA’s Secure Service Platform) in Non-silent Direct Mode. Alternatively, you may implement the callback interface for your own licence server and portal in Non-silent Indirect mode.

Non-silent Direct mode, where the PAK fetches both licences and keys is no longer supported.

For specific details, see the NAGRA PRM-protected playback feature and the encrypted playback example code provided in the SDK5 package.

Offline playback (Download to Go)

SDK 5 maintains the same approach as SDK 4 with regards to offline playback steps:

  • After user selection, a stream is analysed until it is PREPARED.
  • A video bitrate to download is selected, and that video (along with all other tracks) is downloaded.
  • Decryption keys are fetched at the start of the download.
  • Downloading can be paused and resumes after the start of the download.
  • Playback of the downloaded content can start after sufficient data is downloaded.

Additional capabilities introduced in SDK5:

  • Support for offline playback of encrypted DASH streams
  • A download can be done in the background as a service

  • Parallel downloading of segments for better download speed

    Due to the different architecture of SDK 5, assets that have been marked for download and are in the PREPARED state (bitrate not yet selected and actual download not started), will not persist. If the application terminates and restarts, the PREPARED downloads will be removed. Although preparing and starting downloads are separate steps, we recommend that the application combines the two into a single step. See, for example, the offline-service example code

See the various example code snippets provided for implementation of offline playback for DASH+Widevine, HLS+PRM, and Downloading content in an Android Service.

Offline playback is not yet supported for PlayReady-encrypted streams.

Lifecycle

As SDK 5 supports multiple instances, static objects (apart from some string constants) have been removed. When zapping, you have the choice of either recycling the player instance or passing a new stream URL (and with encrypted content, updating the DRM callback class).

Certain situations, such as rotation, move to the background and back etc, may cause the activity to be destroyed with onDestroy() event and re-created with onCreate() event. In such cases, when resuming, playback would start from the beginning of the asset rather than from where playback was interrupted. This is not the desired behaviour. The solution for that is listening to configuration changes (onConfigurationChanged()) and handling the configuration changes in the activity. When implementing the onConfigurationChanged() override, detach the player from its parent (which is going to be destroyed) and attach it to a new view.

  1. In the application manifest (AndroidManifest.xml) add a configChanges setting for the activity owning the player:

        ...
        <activity android:name=".MainActivity"
            android:configChanges="orientation|screenSize">
        ...
    XML
  2. In the activity controlling the player, add an overridingonConfigurationChanged()as per the code below.

          @Override
          public void onConfigurationChanged(Configuration newConfig) {
            super.onConfigurationChanged(newConfig);
            if (mOTVVideoView.getParent() != null) {
              ViewGroup parent = (ViewGroup) mOTVVideoView.getParent();
              parent.removeView(mOTVVideoView);
            }
            mFrame.addView(mOTVVideoView);
          }
    JAVA

An example of this implementation can be found in the example code for basic playback provided in this package.

See also Handling the configuration change yourself in the Android Developers site.

getSeekableRangeInfo() in Live streams

getSeekableRangeInfo() provides a pair of long integers indicating the start and end time of playable content in the stream to which a seekTo() operation can be performed. The range for VoD is usually between 0 and the duration. In SDK 4 the Live stream range is between a negative number (past) and zero (current live point); whereas in SDK 5, the range values are always positive, and 0 signifies the earliest time available to seek back to.

setVolume()

In SDK4, setVolume() used to set the system volume. As SDK 5 now supports multiple instances, setVolume() sets the playback volume for the specific player instance.

Subtitle rendering settings (nagra.nmp.sdk.subtitle.settings package)

The entire nagra.nmp.sdk.subtitle.settings package has been deprecated. System-wide settings for the device now control subtitles appearance (colours, size, style).

Setting debug levels for logs

The method setDebugLogs()in OTVVideoView has been deprecated. For setting log levels, please use OTVLog.setLogLevel(int logLevel) and OTVLog.logLevel(). The log level options are:

  • LOG_LEVEL_INFO (default for opy-sdk-android-version-sdk-production.aar)
  • LOG_LEVEL_DEBUG
  • LOG_LEVEL_VERBOSE (default for opy-sdk-android-version-sdk-integration.aar)

The SDK always produces Warning and Critical/Error logs, along with some support critical messages.

Resolution/bitrate capping

When applying a new cap while a stream is already playing, the cap is applied immediately (as opposed to a cap only on future downloaded segments). The playback buffers are flushed, and fresh data is downloaded, causing a slight interruption in playback.

Advertising with Google IMA

Users of IMA on SDK 4 should note these subtle differences when migrating:

  • There is no longer any need for the IMAWrapperSettingsBuilder class due to adopting a later IMA version with an API deprecation.
  • There is no need for the allowance of the video view in the layout as its created dynamically.

Offline playback

  • Although OTVDownloadManager is not a singleton, it is not necessary to instantiate it more than once. A listener implementing it must be provided when instantiating OTVDownloadManager.
  • Multiple downloads can now run concurrently
  • The download continues when the application is in the background

External subtitles

Whereas in SDK 4 external SRT subtitles could be added to a playing stream anytime, with SDK 5 such subtitles should be added to the player as soon as the playback URL is set (adding them later will reset playback to the beginning).

Subtitles’ text configuration

In SDK 4, the configuration of text-based subtitles (colour, typeface, size etc.) is configurable via the SDK, SDK 5 uses the device’s system configuration to align with other services and applications.

Feature differences

With the new SDK, some features are not yet implemented (and some are implemented only for the newer product). The table below compares the two versions’ features and will be updated for each release.

Feature

SDK 4

SDK 5

HLS StreamingYes (+PRM)Yes (+PRM)
DASH StreamingRequires additional licenceYes (+Widevine, PlayReady)
HEVC decodingYesYes
Multi-instance/PiPNoYes, however, some device hardware decoders will prevent concurrent playback of multiple video streams.
There are also limitations on concurrent playback of multiple HLS+PRM streams.
Multiple audio tracks (HLS)YesYes, although if multi-audio tracks are on the same MPEG2 TS with video only the default track can be selected.
Multiple audio tracks (DASH)YesYes
Subtitles (HLS)CC608
CC708
WebVTT
SMPTE-TT over ID3
CC608
WebVTT
Subtitles (DASH)CC608
CC708
WebVTT
SMPTE-TT over ID3
CC608
CC708
WebVTT
SMPTE-TT (text only)
Hardware/Software decodingBothDevice supported codecs only
NexGuard Forensic WatermarkingYes (1.1.5)Yes (1.1.5)
Insight AnalyticsYesYes
Advertising with Google IMAYesYes
Offline playback (D2G)HLS onlyDASH (+Widevine). PlayReady not yet supported
HLS (+PRM).
Resolution/bitrate cappingYesYes
Device CalibrationYesFuture
Output ControlYesFuture
Thumbnail previewsYesFuture
Scale-with-crop videoYesYes