On the playstation 5, reload ASAP if a key become unusable #1399
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Issue
We noticed that the PlayStation 5 may have the HTMLMediaElement on which the content is played stop on a
MEDIA_ERR_DECODEerror if it encounters encrypted media data whose key is not usable due to policy restrictions (the most usual issue being non-respect of HDCP restrictions).This is not an usual behavior, other platforms just do not attempt to decode the encrypted media data and stall the playback instead (which is a much preferable behavior for us as we have some advanced mechanism to restart playback when this happens).
To complexify even more, the RxPlayer learn of that error (through an
"error"event) much later than after receiving the information that a key became undecipherable. The RxPlayer could thus already have performed several operations such asSourceBuffer.removecalls BEFORE it is aware that the media element is on error. Such operations will throw - at that time without any understood reason - which lead to a miscategorized fatal error by the RxPlayer.Consequently, we have to specifically consider platforms with that fail-on-undecipherable-data issue, to perform a work-around in that case.
Work-around
The work-around found for now is to just directly cancel all streaming logic linked to a
MediaSourceas soon as the RxPlayer'sContentDecryptor(its module handling content decryption) signals about unusable keys, which should normally happen synchronously after the corresponding event is triggered by the browser.To ensure this is done as soon as possible (because this is a race with the browser), this is performed in the
ContentInitializerRxPlayer module, which is the module directly interfacing with theContentDecryptor, with media element errors, and with the logic of creatingMediaSourceinstances.If we handled this in the
StreamOrchestratorfor example (which is better able to handle this scenario because it knows which segments have been buffered and are going to be buffered), we would have much more risk to "lose" the race with the browser here, as more RxPlayer modules will be involved as well as two threads and message-passing in a multithreaded scenario.I'm not that satisfied with this solution though. Because a race is still going on between the browser and the RxPlayer, it may break in the future if we bring an asynchronicity (e.g. a round trip to the event loop) between the moment a decryption key becomes unusable and the moment we're reloading the
MediaSource.Perhaps a better solution would be to just let the corresponding
MEDIA_ERR_DECODEhappen, then determine heuristically if it had a good chance to happen due to the aforementioned decryption issue and reload in that case, but this is also difficult to implement.