TheWidlarzGroup / react-native-video

A <Video /> component for react-native
https://docs.thewidlarzgroup.com/react-native-video/
MIT License
7.2k stars 2.9k forks source link

iOS FairPlay DRM Video Not Playing [Error getting license from URL skd://${contentIdValue}] #2367

Closed MaazF94 closed 3 years ago

MaazF94 commented 3 years ago

Bug

I'm using ExpressPlay with AWS MediaPackage to generate my source URLs and license acquisition URLs (License Server). With Widevine, it's simple plug n play and no issues. With FairPlay, I'm receiving inconsistent errors and never able to play the video. I've confirmed that with my Source URL, License Server URL, and Certificate URL, I can play the video in the Shaka Player Demo. I've shared the URLs as examples in the reproducible code section below.

1. I receive the error "Error getting license from URL skd://${contentIdValue}" with HTTP Status Code 403 Forbidden. ExpressPlay doesn't do anything with the skd value, I've checked with them. The URL should be the License Server URL. Is there a way I can override this?

  1. Very inconsistent in the reasoning behind why the error is thrown. Sometimes, this line returns spcError with an unknown error code, sometimes it doesn't return an error and retrieves the spcData:

NSData *spcData = [loadingRequest streamingContentKeyRequestDataForApp:certificateData contentIdentifier:contentIdData options:nil error:&spcError];

Either way, the error is always the same.

Platform

iOS Which player are you experiencing the problem on:

Environment info

React native info output:

System:
    OS: macOS 11.2.2
    CPU: (8) x64 Apple M1
    Memory: 271.01 MB / 8.00 GB
    Shell: 5.8 - /bin/zsh
  Binaries:
    Node: 15.3.0 - /usr/local/bin/node
    Yarn: Not Found
    npm: 7.0.14 - /usr/local/bin/npm
    Watchman: 4.9.0 - /usr/local/bin/watchman
  Managers:
    CocoaPods: 1.10.0 - /usr/local/bin/pod
  SDKs:
    iOS SDK:
      Platforms: iOS 14.5, DriverKit 20.4, macOS 11.3, tvOS 14.5, watchOS 7.4
    Android SDK: Not Found
  IDEs:
    Android Studio: 4.1 AI-201.8743.12.41.7199119
    Xcode: 12.5/12E262 - /usr/bin/xcodebuild
  Languages:
    Java: 11.0.9.1 - /usr/bin/javac
    Python: 2.7.16 - /usr/bin/python
  npmPackages:
    @react-native-community/cli: Not Found
    react: 16.13.1 => 16.13.1 
    react-native: ~0.63.3 => 0.63.4 
    react-native-macos: Not Found
  npmGlobalPackages:
    *react-native*: Not Found

Library version: 5.1.1

Steps To Reproduce

  1. In RNVideo, Pass your source URI (retrieved from MediaPackage Asset), license certificate URL (Stored in S3 bucket), and license server URL (retrieved through API call to ExpressPlay) as props.

Expected behaviour

  1. The video should play

Reproducible sample code

` const { width, height } = Dimensions.get("window");

<Video source={{ uri: "https://e36c169ad4441ce9fcc50154be8163b8.egress.mediapackage-vod.us-west-2.amazonaws.com/out/v1/9a5ab2b521d24c0b846786bfe3fbc801/98b66a37ba164e55a54b636401117163/657fccc6bc4842539073ce28e18f8442/index.m3u8", }} drm={{ type: "fairplay", certificateUrl: Use_Your_Valid_FPS_Cert, licenseServer: "https://fp.service.expressplay.com/hms/fp/rights/?ExpressPlayToken=BgAk0pGeKZkAJGVmODVmZWNlLTZhNTItNDJjMC05MDFlLTNjMWQyOWFkNGE2MgAAAGCZ2yBWoH2xecLidmf87OHmoiVDeJk3O0s_1jJdW-dYrnzj8PufJy7xFyFgD1pnBZJzTlYA3BmLOYixh8yeYXIU52AuJLMrFbNY9LRpyBcSQ1jSdff802ORE20g-p727GI5_fyLa4xj08V0vLH0NT1sG5SEGA", headers: { "content-type": "application/octet-stream", }, }} style={{ width: width, height: height }} resizeMode="contain" rate={1.0} volume={1.0} /> `

Video sample

included in code sample above

sebastianpaz commented 3 years ago

First, could you please share a code snippet on how you managed to do it on Widevine? I'm experiencing issues with that, and would really appreciate some help.

Regarding your issue with Fairplay DRM, it looks like you're not using the prop getLicense. I believe you should. That prop retrieves the spc blob as a parameter, and then you make a request to the Fairplay License Server using that spc blob (usually encoded in Base 64).

I've used this issue thread as reference: https://github.com/react-native-video/react-native-video/pull/2208

MaazF94 commented 3 years ago

First, could you please share a code snippet on how you managed to do it on Widevine? I'm experiencing issues with that, and would really appreciate some help.

Regarding your issue with Fairplay DRM, it looks like you're not using the prop getLicense. I believe you should. That prop retrieves the spc blob as a parameter, and then you make a request to the Fairplay License Server using that spc blob (usually encoded in Base 64).

I've used this issue thread as reference: #2208

Oh maybe I misunderstood it then. I thought we didn't need to use getLicense. I'll have to do some testing and try it out. Thanks for the suggestion!

For Widevine, I have the exact same code from my original issue except without certificate URL and the source URI which I grabbed from AWS is DASH not HLS (ends with .mpd). The License Server URL is almost the same format except "fp" is replaced with "wv". And of course, it's generated from the ExpressPlay API so it's a different URL with a different token.

MaazF94 commented 3 years ago

@sebastianpaz not sure if it made a difference. Now, I at least see that I'm hitting the right URL but, still getting a 403 response. Any idea why or where exactly I'm getting this 403 from?

` getLicense: async (spcString) => { const base64spc = base64.encode(spcString); return fetch( My_ExpressPlay_License_URL, { method: "POST", headers: { "Content-Type": "application/octet-stream", }, body: JSON.stringify({ getFairplayLicense: { spcMessage: base64spc, }, }), } ) .then((response) => response.json()) .then((response) => { if ( response && response.getFairplayLicenseResponse && response.getFairplayLicenseResponse.ckcResponse ) { return response.getFairplayLicenseResponse.ckcResponse; } throw new Error("No correct response"); }) .catch((error) => { console.error("CKC error", error); }); }

`

sebastianpaz commented 3 years ago

Hey sorry for the late response. Did you configure your FPS certificate on the Apple Developer website? https://developer.apple.com/streaming/fps/

EDIT: Regarding your code, it looks ok to me.

matiasrodriguezbegueri commented 3 years ago

Hi, you were able to solve the issue? i have the same problem.

MaazF94 commented 3 years ago

Yes, I got it working but I switched from expressplay to pallycon. No issues