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

fix: output-restricted event handling for unplayable streams #1305

Merged
merged 6 commits into from
Aug 17, 2022

Conversation

alex-barstow
Copy link
Contributor

@alex-barstow alex-barstow commented Aug 9, 2022

Description

This change will improve handling of EME 'keystatuschange' events of the type 'output-restricted', which occurs when the client does not meet HDCP compliance. The existing implementation uses blacklistCurrentPlaylist() to exclude a single playlist from ABR selection when such an event is encountered, but does not handle cases where there are multiple unplayable HD streams.

Specific Changes proposed

I am proposing we do the following:

  • When encountering an 'output-restricted', we should assume that this is due to HDCP non-compliance and that all HD playlists will be unplayable.
  • Therefore, exclude all HD playlists from ABR selection.
  • Unplayable segments may have already been buffered, so after excluding the HD playlists, perform a fastQualityChange_() which will clear the buffer and switch to a playable SD stream.

@codecov
Copy link

codecov bot commented Aug 9, 2022

Codecov Report

Merging #1305 (4f0153d) into main (97e02fb) will increase coverage by 0.00%.
The diff coverage is 93.33%.

@@           Coverage Diff           @@
##             main    #1305   +/-   ##
=======================================
  Coverage   86.30%   86.31%           
=======================================
  Files          39       39           
  Lines        9842     9855   +13     
  Branches     2293     2298    +5     
=======================================
+ Hits         8494     8506   +12     
- Misses       1348     1349    +1     
Impacted Files Coverage Δ
src/videojs-http-streaming.js 91.08% <93.33%> (+0.03%) ⬆️

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

@alex-barstow alex-barstow requested a review from gesinger August 9, 2022 17:10
@@ -1062,11 +1062,34 @@ class VhsHandler extends Component {

this.player_.tech_.on('keystatuschange', (e) => {
if (e.status === 'output-restricted') {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we change this to:

      if (e.status !== 'output-restricted') {
        return;
      }

we can remove a level of indentation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, should have done that.

const masterPlaylist = this.masterPlaylistController_.media();
const excludedHDPlaylists = [];

if (masterPlaylist && masterPlaylist.playlists) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same for this line too, we can return early if these aren't available.

message: `DRM keystatus changed to ${e.status}. Playlist will fail to play. Check for HDCP content.`,
blacklistDuration: Infinity
});
const masterPlaylist = this.masterPlaylistController_.media();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this.masterPlaylistController_.media() actually returns the currently active media playlist. You want

Suggested change
const masterPlaylist = this.masterPlaylistController_.media();
const masterPlaylist = this.masterPlaylistController_.master();

Comment on lines 1069 to 1070
// Assume all HD streams are unplayable and exclude them from ABR selection, then perform
// a fastQualityChange to clear the buffer since it may already contain unplayable segments
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be better to move the second part of the comment ("...clear the buffer since it may already contain unplayable segments") above the call to fastQualityChange_

Comment on lines 1074 to 1076
if (!playlist.excludeUntil || playlist.excludeUntil < Infinity) {

playlist.excludeUntil = Infinity;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if we need to check the current excludeUntil and can instead probably just set playlist.excludeUntil = Infinity;.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added this to make sure we only exclude/clear buffer/switch playlists once in the event we get multiple output-restricted events, which I have encountered in testing.

if (excludedHDPlaylists.length) {
videojs.log.warn(
'DRM keystatus changed to "output-restricted." Removing the following HD playlists ' +
'that will most likely fail to play and clearing already buffered HD segments. ' +
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically, we're clearing a buffer which may contain more than just HD segments.

Suggested change
'that will most likely fail to play and clearing already buffered HD segments. ' +
'that will most likely fail to play and clearing the buffer. ' +

videojs.log.warn(
'DRM keystatus changed to "output-restricted." Removing the following HD playlists ' +
'that will most likely fail to play and clearing already buffered HD segments. ' +
'Check for HDCP content.',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may not always be an issue for the stream provider, but can instead involve, for instance, the client not having the right hardware to play back HDCP content. We can add something like:

`This may be due to HDCP restrictions on the stream and the capabilities of the current device."

};

const excludes = [];
this.player.tech_.vhs.masterPlaylistController_.media = () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
this.player.tech_.vhs.masterPlaylistController_.media = () => {
this.player.tech_.vhs.masterPlaylistController_.master = () => {

@alex-barstow alex-barstow requested a review from gesinger August 15, 2022 20:14
@misteroneill misteroneill merged commit 23bbf84 into main Aug 17, 2022
@misteroneill misteroneill deleted the fix-output-restricted-handling branch August 17, 2022 17:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants