videojs / videojs-contrib-eme

Supports Encrypted Media Extensions for playback of encrypted content in Video.js
Other
199 stars 71 forks source link

DRM callbacks not fired on Safari, version 4.0.0 #156

Open dwassing opened 2 years ago

dwassing commented 2 years ago

Hello! I recently discovered that the DRM callbacks of the plugin do not fire when I run version 4.0.0 and consequently my DRM fails to load.

macOS version 11.6 Videojs-contrib-eme: 4.0.0 Video.js: 7.17.0 Safari: 15.0 (16612.1.29.41.4)

Some sample implementation code, built with Angular (typescript) & webpack:

if ('WebKitMediaKeys' in window){
  this.player.src({
    src: src,
    type: type,
    keySystems: {
      'com.apple.fps.1_0': {
        videoRobustness: 'SW_SECURE_CRYPTO',
        getCertificate: (emeOptions, callback) => {
          videojs.xhr(
            {
              method: 'GET',
              url: '<redacted>',
              responseType: 'arraybuffer',
            },
            (err, response, responseBody) => {
            if (err) {
              callback(err);
              return;
            }
            callback(null, new Uint8Array(responseBody));
          });
        },
        getContentId: (emeOptions, initData) => {
          const contentId = this.extractContentId(initData);
          return contentId;
        },
        getLicense: (emeOptions, contentId, keyMessage, callback) => {
          videojs.xhr(
            {
              method: 'POST',
              url: this.fairPlayUrlBuilder(src),
              responseType: 'text',
              headers: {
                'x-client-certificate': <redacted>
              },
              body: keyMessage,
            },
            (err, response, responseBody) => {
              if (err) {
                callback(err);
                return;
              }
              callback(null, this.licenseRequestLoaded(responseBody));
            });
        }
      }
    }
  });
}

In the above code the extractContentId and licenseRequestLoaded functions do the necessary UintArray operations, the fairPlayUrlBuilder function handles internal api calls for license/source fetching. This implementation works fine with 3.9.0, but with 4.0.0 I get the following error: VIDEOJS: - "ERROR:" - "(CODE:5 MEDIA_ERR_ENCRYPTED)" - "The operation is not supported." Which is not surprising because the getCertificate callback never fires to begin with.

Is this related to https://github.com/videojs/videojs-contrib-eme/issues/140 ? Should I be using 3.10.1 ?

I am staying on 3.9.0 for now, but since I found nothing regarding 4.0.0 I felt like I should at least bring it to your attention. I would like to hear if anyone else has this problem. Thank you!

gkatsev commented 2 years ago

It's probably worth sticking with 3.9.0 if it's working for you. While 4.0.0 should be working, assuming that you updated appropriately (see #147), we have noticed cases where DRM wasn't working but should've. Unfortunately, we haven't had a chance to investigate it further. v3.10.1 should be equivalent to v3.9.0.

dwassing commented 2 years ago

Thank you for pointing out that commit @gkatsev, since 3.9.0 does indeed work fine for me I will postpone the update on my end. The implementation for fairplay was a lot more tricky than the one for widevine, and I followed a sample implementation that uses a lot of conversion between Uint8Arrays and Uint16Arrays (meaning I used the legacy API). Because of this, I likely will have to adjust for the 4.0.0 version in some way. But before I do any changes, I will wait and see if and when you get a chance to investigate further. Though, it strikes me as fairly strange that I get no response from either the getCertificate or getContentId callbacks even before any conversion is supposed to take place.

I am not sure whether to leave this open or closed. I am putting this on my to-investigate pile for now, if you think that this can be closed, feel free to do so.

Edit: I tried a quick fix with 4.0.0 by removing all UintArray pieces and using strings instead, but I still get no signs that any callbacks are ever called.

gavriguy commented 1 year ago

Hi it looks like 3.9.0 is not working either (Safari Version 16.5 (18615.2.9.11.4)). Maybe you have new insights on what is the best way to be able to run the fairplay drm functions on Safari?

fanguitocoder commented 1 month ago

Any updates in this issue? Neither the functions are working, or the licenseUri/certificateUri requests are going out for me.