fix(player): encrypted playback throws before the first segment - #237
Merged
Conversation
media-segment-request.js files every request in activeXhrs and then attaches a `loadend` listener to each, so the plain object the key interceptor handed back threw TypeError: xhr.addEventListener is not a function before a single segment was decrypted — encrypted playback showed a black frame, in the app and in the CMS preview alike. No-ops are enough: VHS's handleLoadEnd only reads `aborted`, and a request answered from memory is never aborted.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Encrypted video fails with a black frame and this in the console:
Why
media-segment-request.jscollects every request in anactiveXhrsarray and then attaches aloadendlistener to each one:installMemoryKeyXhranswers the sentinel key URI with a plain object carryingresponse,status,abortedandabort. It had noaddEventListener, so theforEachthrew and took the whole segment load with it — before anything was decrypted.The comment in the interceptor accounted for the abort list ("mediaSegmentRequest files whatever comes back in its abort list") but not for the listener attached to the same array a few lines later.
The fix
No-op
addEventListener/removeEventListeneron the response object. Nothing depends on the event arriving: VHS'shandleLoadEndonly callsabortFn()when the request reportsaborted, and a request answered from memory is never aborted. Those two plusabort()are the only methods VHS calls on these objects — checked against the whole segment path in the pinned build.Tests
Two added to
vhsKeyInterceptor.test.ts, driving what VHS actually does rather than what the interface says: file the returned object in an array, attach aloadendlistener to it, then abort it. With the fix reverted the first fails with the sameaddEventListener is not a functionseen in the browser. 95 pass across the package.Not fixed here
VIDEOJS: ERROR: The \"youtube\" tech is undefinedalso appears on every player init:techOrdernamesyoutube, and the tech is only imported when a YouTube URL is played. It is noise rather than breakage — video.js skips an unregistered entry, which is what the comment inplayerOptions.tsrelies on — but it logs at error level every time. Worth a separate decision about whether to buildtechOrderafter the tech registers.