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 unresponsive remote controller when media changes #175

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 18 additions & 5 deletions src/js/chromecast/ChromecastSessionManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,31 @@ class ChromecastSessionManager {

this._addCastContextEventListeners();

// Remove global event listeners when this player instance is destroyed to prevent
// memory leaks.
this.player.on('dispose', this._removeCastContextEventListeners.bind(this));
this.player.on('dispose', () => {
// Remove global event listeners when this player instance is destroyed
// to prevent memory leaks.
this._removeCastContextEventListeners();

// Clean up references since we can instantiate
// RemotePlayer & RemotePlayerController multiple times on the page life cycle
this.remotePlayer = null;
this.remotePlayerController = null;
});

this._notifyPlayerOfDevicesAvailabilityChange(this.getCastContext().getCastState());
}

static hasConnected = false;

/**
* Used by ChromecastTech to setup remotePlayerController after media is loaded.
*
* */
setupPlayerController() {
this.remotePlayer = new cast.framework.RemotePlayer();
this.remotePlayerController = new cast.framework.RemotePlayerController(this.remotePlayer);
}

static hasConnected = false;

/**
* Add event listeners for events triggered on the current CastContext.
*
Expand Down
37 changes: 32 additions & 5 deletions src/js/tech/ChromecastTech.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,19 @@ module.exports = function(videojs) {
this._eventListeners = [];

this.videojsPlayer = this.videojs(options.playerId);

// videoPlayer.chromecastSessionManager will be undefined when
// players change during active casting. videojs will auto engage ChromecastTech
// on the new player before player.chromecast() is invoked
// which we depend on to initialize ChromecastSessionManager
// & assigns it to the player
if (!this.videojsPlayer.chromecastSessionManager) {
this.videojsPlayer.chromecastSessionManager = new ChromecastSessionManager(this.videojsPlayer);
}
this._chromecastSessionManager = this.videojsPlayer.chromecastSessionManager;

this._ui.updatePoster(this.videojsPlayer.poster());

this._remotePlayer = this._chromecastSessionManager.getRemotePlayer();
this._remotePlayerController = this._chromecastSessionManager.getRemotePlayerController();
this._listenToPlayerControllerEvents();
this.on('dispose', this._removeAllEventListeners.bind(this));

this._hasPlayedAnyItem = false;
this._requestTitle = options.requestTitleFn || function() { /* noop */ };
this._requestSubtitle = options.requestSubtitleFn || function() { /* noop */ };
Expand All @@ -82,6 +86,11 @@ module.exports = function(videojs) {
this._initialStartTime = options.startTime || 0;

this._playSource(options.source, this._initialStartTime);
// Creating remotePlayerController after media is loaded
// fixes the unresponsive controller when media changes
this.on('loadeddata', () => {
this._setupPlayerController();
});
this.ready(function() {
this.setMuted(options.muted);
}.bind(this));
Expand Down Expand Up @@ -171,6 +180,24 @@ module.exports = function(videojs) {
this._playSource(source, 0);
}

/**
* Creates RemotePlayer & RemotePlayerController
* sets up events listener & handles cleanup on dispose
*
* @private
* */
_setupPlayerController() {
this._chromecastSessionManager.setupPlayerController();
this._remotePlayer = this._chromecastSessionManager.getRemotePlayer();
this._remotePlayerController = this._chromecastSessionManager.getRemotePlayerController();
this._listenToPlayerControllerEvents();
this.on('dispose', () => {
this._removeAllEventListeners();
this._remotePlayer = null;
this._remotePlayerController = null;
});
}

/**
* Plays the given source, beginning at an optional starting time.
*
Expand Down