Widevine Android SDK Guide

Overview

PallyCon Widevine Android SDK makes it easy to apply Google’s Widevine Modular DRM when developing media service apps for Android. This document describes how to use the libraries and sample project included in the SDK.

Details of PallyCon Multi DRM service integration are provided in License Token Guide. For technical questions about using the SDK, please visit our Helpdesk site.

This SDK product can be downloaded from PallyCon Github repository. In the trial account, you can freely test SDK products within the trial limit on the number of licenses issued. However, in order to apply the SDK to commercial services, you must apply for a plan that includes SDK usage rights when subscribing to PallyCon commercial plans.

Requirements

  • Android version 4.4 (KitKat) or later. AndroidX library is used.
  • PallyCon Widevine Android SDK uses Google ExoPlayer internally. For ExoPlayer support by SDK version, please refer to the Release Notes.

Tutorial Video

This video is a tutorial for playing DRM content using the sample project included in the SDK.

For optimal playback, select ‘1080p’ as the video quality and enable subtitle (Korean or English) before starting playback.

Quick Start

You can apply PallyCon Widevine Android SDK to your development project by following these steps:

  1. Extract downloaded SDK file.

  2. Copy PallyconWVMSDK.aar file to project/module/libs/ folder in your project.

  3. Apply the below configuration in build.gradle (project).

    buildscript {  
        repositories {  
            jcenter()  
            google()  
            flatDir {  
    	        dirs 'libs'  
    	    }
        }  
        dependencies {  
            classpath 'com.android.tools.build:gradle:3.2.1'  
    
    // NOTE: Do not place your application dependencies here; they belong  
    // in the individual module build.gradle files  }  
    }  
    
    allprojects {  
        repositories {  
            jcenter()  
            google()  
        }  
    }
    
  4. Apply the below configuration in build.gradle (module).

    android {
        defaultConfig {
            minSdkVersion 19
            targetSdkVersion 28
            multiDexEnabled true
        }
    
        compileOptions {
            sourceCompatibility JavaVersion.VERSION_1_8
            targetCompatibility JavaVersion.VERSION_1_8
        }
    }
    
    dependencies {
        implementation fileTree(dir: 'libs', include: ['*.jar'])
        implementation fileTree(dir: 'libs', include: ['*.aar'])
        implementation 'androidx.appcompat:appcompat:1.1.0'
        implementation 'androidx.vectordrawable:vectordrawable-animated:1.1.0'
        implementation 'androidx.recyclerview:recyclerview:1.0.0'
        implementation 'androidx.legacy:legacy-support-v4:1.0.0'
        implementation 'androidx.mediarouter:mediarouter:1.1.0'
        implementation 'com.google.android.gms:play-services-cast-framework:17.1.0'
        implementation 'com.google.android.exoplayer:exoplayer:2.10.4'
    }
    
  5. Implement PallyconDownloadTask.PallyconDownloadEventListener in MainActivity.(refer to sample project)

    private PallyconDownloadTask.PallyconDownloadEventListener eventListener = new PallyconDownloadTask.PallyconDownloadEventListener() {
        @Override
        public void onPreExecute() {
            // called on preparing download
        }
    
        @Override
        public void onPostExecute() {
            // called on download complete
        }
    
        @Override
        public void onProgressUpdate(String fileName, long downloadedSize, long totalSize, int percent, int downloadIndex) {
            // called on progress update : refer to API document
        }
    
        @Override
        public void onCancelled() {
            // called on canceling download : refer to API document
        }
    
        @Override
        public void onNetworkError(NetworkConnectedException e) {
            // called on network error : refer to API document
        }
    
        @Override
        public void onPallyconDownloadError(PallyconDownloadException e) {
            // called on download error : refer to API document
        }
    };
    
  6. To use the download callback, implement the callback function and enter it into the PallyconDownloadTask constructor. If you do not use callback, enter null.

    DownloadCallbackImpl downloadCallback = new DownloadCallbackImpl(getApplicationContext());
    
  7. Create PallyconDownloadTask object with content information.

    downloadTask = new PallyconDownloadTask(MainActivity.this, content.uri, content.name, listener, eventHandler);
    
  8. Start downloading content if the content is not previously downloaded.

    boolean result = downloadTask.isDownloadCompleted();
    if(result == true) {
        Uri localUri = downloadTask.getLocalUri(content.uri, content.name);
    } else {
        downloadTask.execute();	
    }
    
  9. After the download is complete, you can issue a license using the following APIs before playback

    WVMAgent.downloadLicense(content.drmSchemeUuid, content.drmLicenseUrl, content.uri, content.userId, content.cid, content.oid);
    
  10. Implement player in PlayerActivity.java using ExoPlayer development guide.

  11. Implement ExoPlayer.EventListener. (refer to sample project)

    private ExoPlayer.EventListener playerEventListener = new ExoPlayer.EventListener() {
        @Override
        public void onTimelineChanged(Timeline timeline, Object manifest){
            //  refer to API document & sample source
        }
    
        @Override
        public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
            //  refer to API document & sample source
        }
    
        @Override
        public void onLoadingChanged(boolean isLoading) {
            //  refer to API document & sample source
        }
    
        @Override
        public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
            //  refer to API document & sample source
        }
    
        @Override
        public void onPlayerError(ExoPlaybackException e) {
            //  refer to API document & sample source
        }
    
        @Override
        public void onPositionDiscontinuity() {
            //  refer to API document & sample source
        }
    };
    
  12. Implement PallyconStreamingDrmSessionManager.PallyconEventListener. (refer to sample project)

    private PallyconStreamingDrmSessionManager.PallyconEventListener eventListener = new PallyconStreamingDrmSessionManager.PallyconEventListener() {
        @Override
        public void onDrmKeysLoaded(Map<String, String> licenseInfo) {
            // refer to API document
        }
    
        @Override
        public void onDrmSessionManagerError(Exception e) {
            // refer to API document
            if (e instanceof NetworkConnectedException) {
    
            } else if (e instanceof PallyconDrmException) {
    
            } else if (e instanceof PallyconEncrypterException) {
    
            } else if (e instanceof PallyconServerResponseException) {
    
            } else if (e instanceof KeysExpiredException) {
    
            } else if (e instanceof DetectedDeviceTimeModifiedException) {
                // Important : content playback should be prohibited to prevent illegal use of content.
            } else {
    
            }
        }
    };
    
  13. Get PallyconWVMSDK instance.

    PallyconWVMSDK WVMAgent = PallyconWVMSDKFactory.getInstance(this, Global.enableNcgCenc);
    
  14. Set Site ID and Site Key issued by PallyCon Console Site to PallyconWVMSDK instance.

    WVMAgent.init(this, eventHandler, "SITEID", "SITEKEY");
    
  15. Register a listener to receive events from the object of PallyconWVMSDK.

    WVMAgent.setPallyconEventListener(pallyconEventListener);
    
  16. Create PallyconDrmSessionManager with information for license acquisition.

    drmSessionManager = WVMAgent.createDrmSessionManager(drmSchemeUuid, drmLicenseUrl, uri, userId, cid, oid);
    

    If you use license token type integration, set the token information as below.

    drmSessionManager = WVMAgent.createDrmSessionManagerByToken(drmSchemeUuid, drmLicenseUrl, uri, userId, cid, token);
    
  17. Input the above drmSessionManager as a parameter when creating ExoPlayer

    player = ExoPlayerFactory.newSimpleInstance(this, trackSelector, new DefaultLoadControl(), drmSessionManager);
    
  18. Input the playerEventListener when registering Player Listener as well.

    player.addListener(playerEventListener);
    

Preventing screen recording

To prevent content leaks with screen recording apps, you should block the capture function by adding the following code to your application:

SurfaceView view = (SurfaceView)simpleExoPlayerView.getVideoSurfaceView();
view.setSecure(true);

Other notes

API Reference Documentation

For a detailed description of the APIs provided by the SDK, please refer to the API reference document included in the SDK file. (doc/en/api_reference.html)

AndroidTV SDK

If you are developing a media service app for Android TV devices, you can use the separately provided PallyCon Widevine AndroidTV SDK. The SDK guide is similar to that of the Android SDK. Please refer to the AndroidTV SDK sample code for details.

Previous
Next