video.js multiple sources for fairplay widevine playready livestream DRM

308 views Asked by At

I want to use video.js to display a DRM-protected livestream that will work in the major browsers. I have a Fairplay livestream (for Apple devices) and a Widevine/Playready livestream (for everything else). I've confirmed that my livestreams work as standalone players on the appropriate platforms, what I'm not sure about is what approach to take to dynamically serve the Fairplay livestream/licenses to Apple devices and the MPEG-DASH stream/licences to everyone else.

detectSupportedCDMs() doc in https://github.com/videojs/videojs-contrib-eme/ says 'be carefule about using this' and I've seen notes that it fails?

This all seems like the usecase for DRM with video.js but I can't find any sample code. Has anyone else set this up?

1

There are 1 answers

0
Will On

The answer to this is surprisingly un-documented.

A first big thing I didn't understand was that Fairplay is only for Safari, even on MacOS and iOS. Firefox and Chrome on MacOS use Widevine, Firefox on iOS uses Widevine, and Chrome and MS Edge on iOS use Fairplay.

Another thing is that player.eme.detectSupportedCDMs() both doesn't currently return anything but an error AND is completely unnecessary.

Assuming that 'dashsrc' is the src for our MPEG-DASH with Widevine/Playready DRM, and 'fairplaysrc' is the src for our HLS with Fairplay DRM, we can use the video.js Browser object contents to decide which to use:

if (videojs.browser.IS_ANY_SAFARI){
// all versions of safari on all platforms require Fairplay DRM
player.src(fairplaysrc);
} else if(videojs.browser.IS_IOS && videojs.browser.IS_CHROMIUM) {
// on iPhone/iPad Chrome uses Fairplay but doesn't use the Safari engine.  Firefox and Edge use Widevine/Playready it seems (?).
player.src(fairplaysrc);
} else {
player.src(dashsrc);
}

The solution above took much to much time to figure out.

Here's the complete code that worked using an EZDRM livestream setup to have a combined Widevine/Playready MPEG-DASH and an HLS Fairplay:

<video-js id='vidjslivestream' controls preload='auto'  class='vjs-16-9 vjs-big-play-centered' ></video-js>
<link rel=stylesheet media='all' type='text/css' href='https://vjs.zencdn.net/8.6.1/video-js.css'/><style> .vjs-poster{ background-size: 100% !important; } </style><script src='https://vjs.zencdn.net/8.6.1/video.min.js'></script>
<script src='https://cdn.jsdelivr.net/npm/[email protected]/dist/videojs-contrib-eme.min.js'></script>
<script type='text/javascript'>
(function() {
  var vid = document.getElementById('vidjslivestream');
  var player = videojs(vid);
  player.eme();
  player.on('ready', function() {

  var dashsrc = {
    src: 'REDACTED.mpd',
    type: 'application/dash+xml',
    keySystems: {
      'com.widevine.alpha': 'https://widevine-dash.ezdrm.com/widevine-php/widevine-foreignkey.php?REDACTED',
      'com.microsoft.playready': 'https://playready.ezdrm.com/cency/preauth.aspx?REDACTED'
    }
  };

  var fairplaysrc = {
    src: 'REDACTED.m3u8',
    type: 'application/x-mpegURL',
    keySystems: {
        'com.apple.fps.1_0': {
            certificateUri: 'REDACTED/fairplay.cer',
            licenseUri: 'https://fps.ezdrm.com/api/licenses/auth?REDACTED',
            options: {
                persistentState: 'required'
            }
        }
    }
  };
  if (videojs.browser.IS_ANY_SAFARI){
    player.src(fairplaysrc);
  } else if(videojs.browser.IS_IOS && videojs.browser.IS_CHROMIUM) {
    player.src(fairplaysrc);
  } else {
    player.src(dashsrc);
  }
});

})();
</script>