PallyCon Widevine Android TV SDK Guide

PallyCon Widevine Android TV SDK makes it easy to apply Google's Widevine Modular DRM when developing media service apps for Android TV platform. 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 Callback API and License Token API guides. For technical questions about using the SDK, please visit our Helpdesk site.

SDK products can be requested when subscribing to PallyCon cloud commercial service. Then SDK can be downloaded from the Download page of PallyCon admin site.


Requirements

  • Android version 5.0 (Lollipop) or later
  • This SDK has been tested on Android Studio 2.2.3 and will not work on the simulator.

Note

  • To develop application using the SDK, first sign up for PallyCon Admin Site, and get Site ID and Site Key from the site.

Quick Start

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

  1. Create Android TV module : Android Studio -> File -> New -> New Module

  2. Extract downloaded SDK file.

  3. Copy PallyconWVMSDK.jar file to project/module/libs/ folder in your project.

  4. Copy armeabi, x86 folder to /src/main/jniLibs/ folder in your project

  5. Apply the below configuration in build.gradle (module).

     android {
         defaultConfig {
             minSdkVersion 21
             targetSdkVersion 26
             multiDexEnabled true
         }
     }
     dependencies {
         compile fileTree(dir: 'libs', include: ['*.jar'])
         compile 'com.android.support:leanback-v17:26.+'
         compile 'com.android.support:appcompat-v7:26.+'
         compile 'com.github.bumptech.glide:glide:3.4.+'
         compile 'com.google.android.exoplayer:exoplayer:r2.3.0'
     }
    
  6. Implement PallyconDownloadTask.PallyconDownloadEventListener in VideoDetailsFragment.(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
         }
     };
    
  7. Create PallyconDownloadTask object with content information.

     downloadTask = new PallyconDownloadTask(getActivity(), Uri.parse(mSelectedMovie.uri), mSelectedMovie.name, false, VideoDetailsFragment.this, eventHandler);
    
  8. Start downloading content if the content is not previously downloaded.

     Intent intent = new Intent(getActivity(), PlaybackOverlayActivity.class);
     intent.putExtra(DetailsActivity.MOVIE, mSelectedMovie);
     boolean result = downloadTask.isDownloadCompleted();
     if(result == true) {
         startActivity(intent);
     } else {
         downloadTask.execute();
     }
    
  9. After the download is complete, you can issue a license using the following APIs before playback.

     WVMAgent.downloadLicense(mSelectedMovie.drmSchemeUuid, mSelectedMovie.drmLicenseUrl, Uri.parse(mSelectedMovie.uri), mSelectedMovie.userId, mSelectedMovie.cid, mSelectedMovie.oid);
    
  10. Implement player in PlaybackOverlayActivity.java using ExoPlayer development guide.

    Please refer to the below guide from Google for more information about Exoplayer. https://developer.android.com/guide/topics/media/exoplayer.html

  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 and sample source
         }
    
         @Override
         public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
             // refer to API document and sample source
         }
    
         @Override
         public void onLoadingChanged(boolean isLoading) {
             // refer to API document and sample source
         }
    
         @Override
         public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
             // refer to API document and sample source
         }
    
         @Override
         public void onPlayerError(ExoPlaybackException e) {
             // refer to API document and sample source
         }
    
         @Override
         public void onPositionDiscontinuity() {
             // refer to API document and sample source
         }
     };
    
  12. Implement PallyconStreamingDrmSessionManager.PallyconEventListener. (refer to sample project)

    Important : content playback should be prohibited to prevent illegal use of content when DetectedDeviceTimeModifiedException occurs.

     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. Implement PlaybackOverlayFragment.OnPlayPauseClickedListener.

     if (position == 0 || mPlaybackState == LeanbackPlaybackState.IDLE) {
         initializePlayer(movie);
         mPlaybackState = LeanbackPlaybackState.IDLE;
     }
     if (playPause && mPlaybackState != LeanbackPlaybackState.PLAYING) {
         mPlaybackState = LeanbackPlaybackState.PLAYING;
         if (position > 0) {
             player.seekTo(position);
             player.setPlayWhenReady(true);
         }
     } else {
         mPlaybackState = LeanbackPlaybackState.PAUSED;
         player.setPlayWhenReady(false);
     }
    
  14. When onKeyUp event is called, it communicates with PlaybackOverlayFragment.

     PlaybackOverlayFragment playbackOverlayFragment = (PlaybackOverlayFragment) getFragmentManager().findFragmentById(R.id.playback_controls_fragment);
     switch (keyCode) {
         case KeyEvent.KEYCODE_MEDIA_PLAY:
             playbackOverlayFragment.togglePlayback(false);
             return true;
         case KeyEvent.KEYCODE_MEDIA_PAUSE:
             playbackOverlayFragment.togglePlayback(false);
             return true;
         case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
             if (mPlaybackState == LeanbackPlaybackState.PLAYING) {
                 playbackOverlayFragment.togglePlayback(false);
             } else {
                 playbackOverlayFragment.togglePlayback(true);
             }
             return true;
         default:
             return super.onKeyUp(keyCode, event);
     }
    
  15. Get PallyconWVMSDK instance in initializePlayer().

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

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

     WVMAgent.setPallyconEventListener(pallyconEventListener);
    
  18. 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);
    
  19. Input the above drmSessionManager as a parameter when creating ExoPlayer

     player = ExoPlayerFactory.newSimpleInstance(this, trackSelector, new DefaultLoadControl(), drmSessionManager);
    
  20. 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);

API References

Please refer to the doc/en/api_reference.html file of the SDK zip file for detailed explanation of each API.


results matching ""

    No results matching ""