From 6d9fa2f75db131821bc3ee129b4fe2292dcb71b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Velad=20Galv=C3=A1n?= Date: Fri, 25 Oct 2024 11:11:44 +0200 Subject: [PATCH] chore: Simplify listener management to be able to use the same basic listeners in MSE and src= (#7501) Related to https://github.com/shaka-project/shaka-player/issues/5022 --- lib/player.js | 175 +++++++++++++++++++++++--------------------------- 1 file changed, 79 insertions(+), 96 deletions(-) diff --git a/lib/player.js b/lib/player.js index 0a44af3b07..21bbc523e6 100644 --- a/lib/player.js +++ b/lib/player.js @@ -2437,6 +2437,81 @@ shaka.Player = class extends shaka.util.FakeEventTarget { this.mediaSourceEngine_ = mediaSourceEngine; } + /** + * Adds the basic media listeners + * + * @param {HTMLMediaElement} mediaElement + * @param {number} startTimeOfLoad + * @private + */ + addBasicMediaListeners_(mediaElement, startTimeOfLoad) { + const updateStateHistory = () => this.updateStateHistory_(); + const onRateChange = () => this.onRateChange_(); + this.loadEventManager_.listen(mediaElement, 'playing', updateStateHistory); + this.loadEventManager_.listen(mediaElement, 'pause', updateStateHistory); + this.loadEventManager_.listen(mediaElement, 'ended', updateStateHistory); + this.loadEventManager_.listen(mediaElement, 'ratechange', onRateChange); + if (mediaElement.remote) { + this.loadEventManager_.listen(mediaElement.remote, 'connect', + () => this.onTracksChanged_()); + this.loadEventManager_.listen(mediaElement.remote, 'connecting', + () => this.onTracksChanged_()); + this.loadEventManager_.listen(mediaElement.remote, 'disconnect', + () => this.onTracksChanged_()); + } + if (mediaElement.audioTracks) { + this.loadEventManager_.listen(mediaElement.audioTracks, 'addtrack', + () => this.onTracksChanged_()); + this.loadEventManager_.listen(mediaElement.audioTracks, 'removetrack', + () => this.onTracksChanged_()); + this.loadEventManager_.listen(mediaElement.audioTracks, 'change', + () => this.onTracksChanged_()); + } + + if (mediaElement.textTracks) { + this.loadEventManager_.listen( + mediaElement.textTracks, 'addtrack', (e) => { + const trackEvent = /** @type {!TrackEvent} */(e); + if (trackEvent.track) { + const track = trackEvent.track; + goog.asserts.assert( + track instanceof TextTrack, 'Wrong track type!'); + + switch (track.kind) { + case 'metadata': + this.processTimedMetadataSrcEqls_(track); + break; + + case 'chapters': + this.activateChaptersTrack_(track); + break; + + default: + this.onTracksChanged_(); + break; + } + } + }); + this.loadEventManager_.listen(mediaElement.textTracks, 'removetrack', + () => this.onTracksChanged_()); + this.loadEventManager_.listen(mediaElement.textTracks, 'change', + () => this.onTracksChanged_()); + } + + // Wait for the 'loadedmetadata' event to measure load() latency, but only + // if preload is set in a way that would result in this event firing + // automatically. + // See https://github.com/shaka-project/shaka-player/issues/2483 + if (mediaElement.preload != 'none') { + this.loadEventManager_.listenOnce( + mediaElement, 'loadedmetadata', () => { + const now = Date.now() / 1000; + const delta = now - startTimeOfLoad; + this.stats_.setLoadLatency(delta); + }); + } + } + /** * Starts loading the content described by the parsed manifest. * @@ -2466,13 +2541,8 @@ shaka.Player = class extends shaka.util.FakeEventTarget { movePlayhead: (delta) => { mediaElement.currentTime += delta; }, }); - const updateStateHistory = () => this.updateStateHistory_(); - const onRateChange = () => this.onRateChange_(); - this.loadEventManager_.listen( - mediaElement, 'playing', updateStateHistory); - this.loadEventManager_.listen(mediaElement, 'pause', updateStateHistory); - this.loadEventManager_.listen(mediaElement, 'ended', updateStateHistory); - this.loadEventManager_.listen(mediaElement, 'ratechange', onRateChange); + // Add all media element listeners. + this.addBasicMediaListeners_(mediaElement, startTimeOfLoad); // Check the status of the LCEVC Dec Object. Reset, create, or close // depending on the config. @@ -2501,24 +2571,6 @@ shaka.Player = class extends shaka.util.FakeEventTarget { // "streaming" so that they can access internal information. this.loadMode_ = shaka.Player.LoadMode.MEDIA_SOURCE; - if (mediaElement.textTracks) { - this.loadEventManager_.listen( - mediaElement.textTracks, 'addtrack', (e) => { - const trackEvent = /** @type {!TrackEvent} */(e); - if (trackEvent.track) { - const track = trackEvent.track; - goog.asserts.assert( - track instanceof TextTrack, 'Wrong track type!'); - - switch (track.kind) { - case 'chapters': - this.activateChaptersTrack_(track); - break; - } - } - }); - } - // The event must be fired after we filter by restrictions but before the // active stream is picked to allow those listening for the "streaming" // event to make changes before streaming starts. @@ -2726,13 +2778,6 @@ shaka.Player = class extends shaka.util.FakeEventTarget { } this.fullyLoaded_ = true; - - // Wait for the 'loadedmetadata' event to measure load() latency. - this.loadEventManager_.listenOnce(mediaElement, 'loadedmetadata', () => { - const now = Date.now() / 1000; - const delta = now - startTimeOfLoad; - this.stats_.setLoadLatency(delta); - }); } /** @@ -2896,72 +2941,8 @@ shaka.Player = class extends shaka.util.FakeEventTarget { const rebufferThreshold = this.config_.streaming.rebufferingGoal; this.startBufferManagement_(mediaElement, rebufferThreshold); - // Add all media element listeners. - const updateStateHistory = () => this.updateStateHistory_(); - const onRateChange = () => this.onRateChange_(); - this.loadEventManager_.listen( - mediaElement, 'playing', updateStateHistory); - this.loadEventManager_.listen(mediaElement, 'pause', updateStateHistory); - this.loadEventManager_.listen(mediaElement, 'ended', updateStateHistory); - this.loadEventManager_.listen(mediaElement, 'ratechange', onRateChange); - - // Wait for the 'loadedmetadata' event to measure load() latency, but only - // if preload is set in a way that would result in this event firing - // automatically. - // See https://github.com/shaka-project/shaka-player/issues/2483 - if (mediaElement.preload != 'none') { - this.loadEventManager_.listenOnce( - mediaElement, 'loadedmetadata', () => { - const now = Date.now() / 1000; - const delta = now - startTimeOfLoad; - this.stats_.setLoadLatency(delta); - }); - } - - // The audio tracks are only available on Safari at the moment, but this - // drives the tracks API for Safari's native HLS. So when they change, - // fire the corresponding Shaka Player event. - if (mediaElement.audioTracks) { - this.loadEventManager_.listen(mediaElement.audioTracks, 'addtrack', - () => this.onTracksChanged_()); - this.loadEventManager_.listen(mediaElement.audioTracks, 'removetrack', - () => this.onTracksChanged_()); - this.loadEventManager_.listen(mediaElement.audioTracks, 'change', - () => this.onTracksChanged_()); - } - if (mediaElement.textTracks) { this.createTextDisplayer_(); - this.loadEventManager_.listen( - mediaElement.textTracks, 'addtrack', (e) => { - const trackEvent = /** @type {!TrackEvent} */(e); - if (trackEvent.track) { - const track = trackEvent.track; - goog.asserts.assert( - track instanceof TextTrack, 'Wrong track type!'); - - switch (track.kind) { - case 'metadata': - this.processTimedMetadataSrcEqls_(track); - break; - - case 'chapters': - this.activateChaptersTrack_(track); - break; - - default: - this.onTracksChanged_(); - break; - } - } - }); - - this.loadEventManager_.listen( - mediaElement.textTracks, 'removetrack', - () => this.onTracksChanged_()); - this.loadEventManager_.listen( - mediaElement.textTracks, 'change', - () => this.onTracksChanged_()); this.loadEventManager_.listen( mediaElement, 'enterpictureinpicture', () => { const track = this.getFilteredTextTracks_() @@ -2979,6 +2960,8 @@ shaka.Player = class extends shaka.util.FakeEventTarget { } }); } + // Add all media element listeners. + this.addBasicMediaListeners_(mediaElement, startTimeOfLoad); // By setting |src| we are done "loading" with src=. We don't need to set // the current time because |playhead| will do that for us.