Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add MSE support for FairPlay #3346

Closed
avelad opened this issue Apr 19, 2021 · 14 comments · Fixed by #3776
Closed

Add MSE support for FairPlay #3346

avelad opened this issue Apr 19, 2021 · 14 comments · Fixed by #3776
Labels
component: HLS The issue involves Apple's HLS manifest format priority: P3 Useful but not urgent status: archived Archived and locked; will not be updated type: enhancement New feature or request
Milestone

Comments

@avelad
Copy link
Member

avelad commented Apr 19, 2021

I just discovered that Apple has updated all the FairPlay integration documentation including MSE example and how to use the api without prefixes (#2999).

Attached the relevant part in case someone does not have access:
FairPlay Streaming in Safari.zip

There are examples with key rotation, multi keys, etc.

@avelad
Copy link
Member Author

avelad commented Apr 19, 2021

Necessary changes:

  • distinctiveIdentifier has to be not-allowed (I'll send a PR for it)
  • persistentState has to be not-allowed (I'll send a PR for it)
  • Persistent sessions are not allowed (I'll send a PR for it)
  • For the renewal of keys the 'renew' event is listen, which right now is not in the ShakaPlayer code. @joeyparrish Do you have any idea how this should work?
  • The contentType when MSE is not used should be 'application/vnd.apple.mpegurl' right now in the ShakaPlayer it gets 'video/mp4' by default (https://github.com/google/shaka-player/blob/master/lib/player.js#L2020) @joeyparrish Do you have any idea how this should work? Why is video/mp4 hardcoded?
  • The integration of Media Capabilities should take all of this into account. @michellezhuogg

@valotvince
Copy link
Contributor

I think Shaka should also provide a way for developers to be notified of which keySystem has been selected for playback, so that we could fetch/cache the appropriate certificate, and give it back as configuration (could have the same logic that the request/response filters).

@avelad
Copy link
Member Author

avelad commented Apr 19, 2021

I have seen Disney + uses HLS manifest with PlayReady, Widevine, and Fairplay using MSE. That would make us have greater efficiency in the CDN, since there would only be one copy (it would not be necessary to maintain DASH and HLS according to the device). @joeyparrish What is your opinion about this? What priority is this for the ShakaPlayer?

@joeyparrish
Copy link
Member

I think Shaka should also provide a way for developers to be notified of which keySystem has been selected for playback

Do you mean in a specific event? Or just that you should be able to get it in general?

Today you can get this info with player.keySystem() at a few different times early on. You can do it after load() resolves or from the loaded event (roughly equivalent), or from the streaming event (which is earlier in the load process).

Would this suffice, or would you prefer a bespoke event?

@joeyparrish What is your opinion about this? What priority is this for the ShakaPlayer?

This is really exciting! I remember spending lots of fruitless hours trying to make MSE+FairPlay work, so it would be amazing to be able to enable it on desktop and MSE-enabled iOS devices.

I will defer to @ismena for priority, as she has taken over as the team lead.

@joeyparrish joeyparrish added type: enhancement New feature or request component: HLS The issue involves Apple's HLS manifest format and removed needs triage labels Apr 20, 2021
@shaka-bot shaka-bot added this to the Backlog milestone Apr 20, 2021
@avelad
Copy link
Member Author

avelad commented Apr 20, 2021

I have been doing some testing and I have seen that MediaCapabitilies in Safari does not seem to support the encryption part, so with what is now in the repo it would not work.

I think it is related to shaka-project/eme-encryption-scheme-polyfill#18, @michellezhuogg , can you confirm it?

@valotvince
Copy link
Contributor

@joeyparrish I think we should have a certificateURL key per advanced config DRM, Shaka would be responsible of fetching the certificate (if serverCertificate is NOT provided), allowing developers to catch the event through a request / response filter, and then do our own logic (cache the certificate in my own use case, to give it back as serverCertificate for the next load).

That's a thing we already do with the Widevine certificate even if it is not the same exact use case, since we have two license requests triggered by the CDM (the first one to fetch the certificate, the second to fetch the license).

@avelad
Copy link
Member Author

avelad commented Apr 20, 2021

@valotvince Maybe #1906 ?

@valotvince
Copy link
Contributor

@avelad Totally !

@ismena
Copy link
Contributor

ismena commented Apr 20, 2021

PRs on this are very welcome if anybody's interested, otherwise we'll consider it for the team to work on in Q3/Q4.

@avelad
Copy link
Member Author

avelad commented May 4, 2021

Important thing I have seen:

  • You have to make TS work in Safari because if mux.js is used the encrypted event is not triggered by the browser.
  • As Safari works with the encrypted event, you have to change the DRM initialization order because you don't have sessionType until the encypted event is fired. (can be initialized as CENC when it should be SINF / SKD)
  • You have to change the drmInfo object to admit a keyURI so that it can be propagated to the drmEngine (FairPlay case)

joeyparrish pushed a commit that referenced this issue May 5, 2021
@avelad
Copy link
Member Author

avelad commented May 5, 2021

@joeyparrish , you reported #2337, you say that SourceBuffer into sequence mode can be a solution to support formats without container, you know if this could fix the problem that TS is broken for safari? (using sequence mode for TS) https://github.com/google/shaka-player/blob/master/lib/polyfill/mediasource.js#L42

@joeyparrish
Copy link
Member

Based on the comments, it seems that the issue with TS in Safari is what happens when you call "abort()" on a SourceBuffer. I'm not sure I see how sequence mode would change the need to call abort() in some cases. The Safari bug is still reproducible in Safari 14, and nobody from Apple responded in the 4.5 years that bug has been known.

Perhaps to enable direct TS in Safari (without waiting for Apple to fix bugs in WebKit), we could investigate more deeply what it would take to eliminate calls to abort(). I haven't touched that part of the code in a long time, so I don't recall the details.

@efysis1
Copy link

efysis1 commented May 15, 2021

So now we Can play drm content in iOS browser? A bit confusing for me Is HLS+iOS safari + FairPlay. As shaka docs Matrix say "native" i think no, but on bitmovin/prestoplay ive Seen support in Matrix. Is It just their player?

@joeyparrish
Copy link
Member

So now we Can play drm content in iOS browser?

We can already play DRM content in iOS browsers, but only through "native" HLS, using video.src = hlsPlaylistUrl, as opposed to MediaSource playback using Shaka's pure-JavaScript HLS implementation.

What we're discussing here is how to support our own HLS implementation through MediaSource, while still using FairPlay. FairPlay is only available in Safari, and MediaSource is not generally available on iOS, except some versions on iPad. So this would apply only to iPads and macOS. Hopefully Apple will offer MediaSource on all iOS devices some day.

A bit confusing for me Is HLS+iOS safari + FairPlay. As shaka docs Matrix say "native" i think no, but on bitmovin/prestoplay ive Seen support in Matrix. Is It just their player?

"Native" there refers to "native HLS", or Apple's built-in HLS implementation in Safari. Shaka can use that to get FairPlay support. There is work to be done (and documentation to be written by Apple) to allow us to fully support FairPlay with MediaSource playbacks. We would prefer to use MediaSource everywhere we can.

joeyparrish pushed a commit that referenced this issue Feb 7, 2022
Add support for HLS com.apple.streamingkeydelivery through MSE/EME implementation.

Close #3346

## Tests
Tested on:
- Mac 11.6 Safari 15.2
- iOS 15.2 Safari 15.2
- Mac 11.6 Chrome 96 (for potential regressions on Widevine keySystem)

| Mode | DRM API | TS | CMAF (mono-key and multi-keys)
|---|---|---|---|
| file | EME | ✅  | ✅  |
| file | Legacy-prefixed | ✅   | ✅   |
| media-source | EME | **mux-js**: `encrypted` never fired<br />**real MSE**: `encrypted` event received, but with incorrect `sinf` initData (*1)  | ✅  |
| media-source | Legacy-prefixed | **mux-js**: `webkitneedkey` never fired<br/>**real MSE**: TBD  | 🔴 fails to append media segment to SourceBuffer (init segment ok) `(video:4) – "failed fetch and append: code=3015"` |

## Support table 
| Mode | DRM API | TS | CMAF (mono-key and multi-keys)
|---|---|---|---|
| file | EME | ✅  | ✅  |
| file | Legacy-prefixed | ✅   | ✅   |
| media-source | EME | 🚫 `4040: HLS_MSE_ENCRYPTED_MP2T_NOT_SUPPORTED`  | ✅  |
| media-source | Legacy-prefixed | 🚫 `4041: HLS_MSE_ENCRYPTED_LEGACY_APPLE_MEDIA_KEYS_NOT_SUPPORTED`  |🚫 `4041: HLS_MSE_ENCRYPTED_LEGACY_APPLE_MEDIA_KEYS_NOT_SUPPORTED` |

⚠️ Use EME APIs with multi-keys CMAF makes the video stalling with the audio continuing alone after a short time (~3 minutes in the stream, could be shorter, could be longer). Didn't find an explanation to that yet. I've observed the same behaviour with hls.js code so I don't think this is a player issue.
@github-actions github-actions bot added the status: archived Archived and locked; will not be updated label Apr 8, 2022
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 8, 2022
@avelad avelad modified the milestones: Backlog, v4.0 May 4, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
component: HLS The issue involves Apple's HLS manifest format priority: P3 Useful but not urgent status: archived Archived and locked; will not be updated type: enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants