Skip to content

Commit

Permalink
Add a temporary fix to enable casting.
Browse files Browse the repository at this point in the history
Issue #1948

Change-Id: Id3953cdc32f1cdd02729c1a3f08c522b2ee376f1
  • Loading branch information
ismena committed Jun 3, 2019
1 parent d5bd998 commit 3e3e940
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 22 deletions.
115 changes: 93 additions & 22 deletions lib/cast/cast_proxy.js
Expand Up @@ -79,14 +79,28 @@ shaka.cast.CastProxy = class extends shaka.util.FakeEventTarget {
/** @private {shaka.util.EventManager} */
this.eventManager_ = null;

/** @private {shaka.cast.CastSender} */
this.sender_ = new shaka.cast.CastSender(
receiverAppId,
() => this.onCastStatusChanged_(),
() => this.onFirstCastStateUpdate_(),
(targetName, event) => this.onRemoteEvent_(targetName, event),
() => this.onResumeLocal_(),
() => this.getInitState_());
/** @private {string} */
this.receiverAppId_ = receiverAppId;

if (this.receiverAppId_) {
// TODO: This is temporary fix to get casting working.
// It masks the fact that we're at the moment unable to
// change the receiver id sucessfully.
// It relies on the assumption that changing one actual
// id to another is a very edgy use case (usually apps have
// only one receiver app).
// It unblocks casting in the world where UI can be configured,
// but it's hacky and must be changed to a permanent solution
// allowing to change Receiver App ID for reals.
/** @private {shaka.cast.CastSender} */
this.sender_ = new shaka.cast.CastSender(
receiverAppId,
() => this.onCastStatusChanged_(),
() => this.onFirstCastStateUpdate_(),
(targetName, event) => this.onRemoteEvent_(targetName, event),
() => this.onResumeLocal_(),
() => this.getInitState_());
}

this.init_();
}
Expand Down Expand Up @@ -184,6 +198,13 @@ shaka.cast.CastProxy = class extends shaka.util.FakeEventTarget {
* @export
*/
async cast() {
if (!this.sender_) {
throw new shaka.util.Error(
shaka.util.Error.Severity.RECOVERABLE,
shaka.util.Error.Category.CAST,
shaka.util.Error.Code.CAST_RECEIVER_APP_ID_MISSING);
}

const initState = this.getInitState_();

// TODO: transfer manually-selected tracks?
Expand All @@ -206,31 +227,74 @@ shaka.cast.CastProxy = class extends shaka.util.FakeEventTarget {
* @export
*/
setAppData(appData) {
this.sender_.setAppData(appData);
if (this.sender_) {
this.sender_.setAppData(appData);
}
}

/**
* Show a dialog where user can choose to disconnect from the cast connection.
* @export
*/
suggestDisconnect() {
this.sender_.showDisconnectDialog();
if (this.sender_) {
this.sender_.showDisconnectDialog();
}
}

/**
* Force the receiver app to shut down by disconnecting.
* @export
*/
forceDisconnect() {
this.sender_.forceDisconnect();
if (this.sender_) {
this.sender_.forceDisconnect();
}
}


/**
* @param {string} newAppId
* @export
*/
async changeReceiverId(newAppId) {
if (newAppId == this.receiverAppId_) {
// Nothing to change
return;
}

this.receiverAppId_ = newAppId;

// TODO: This code doesn't work correctly at the moment. Changing
// one working receiver id to another needs to be figured out.
// Destroy the old sender
if (this.sender_) {
this.sender_.forceDisconnect();
await this.sender_.destroy();
this.sender_ = null;
}


// Create the new one
this.sender_ = new shaka.cast.CastSender(
newAppId,
() => this.onCastStatusChanged_(),
() => this.onFirstCastStateUpdate_(),
(targetName, event) => this.onRemoteEvent_(targetName, event),
() => this.onResumeLocal_(),
() => this.getInitState_());

this.sender_.init();
}

/**
* Initialize the Proxies and the Cast sender.
* @private
*/
init_() {
this.sender_.init();
if (this.sender_) {
this.sender_.init();
}

this.eventManager_ = new shaka.util.EventManager();

Expand Down Expand Up @@ -395,6 +459,9 @@ shaka.cast.CastProxy = class extends shaka.util.FakeEventTarget {
* @private
*/
onResumeLocal_() {
goog.asserts.assert(this.sender_,
'Cast sender should not be null!');

// Transfer back the player state.
for (const pair of shaka.cast.CastUtils.PlayerInitState) {
const getter = pair[0];
Expand Down Expand Up @@ -484,15 +551,16 @@ shaka.cast.CastProxy = class extends shaka.util.FakeEventTarget {

// If we are casting, but the first update has not come in yet, use local
// values, but not local methods.
if (this.sender_.isCasting() && !this.sender_.hasRemoteProperties()) {
if (this.sender_ && this.sender_.isCasting() &&
!this.sender_.hasRemoteProperties()) {
const value = this.localVideo_[name];
if (typeof value != 'function') {
return value;
}
}

// Use local values and methods if we are not casting.
if (!this.sender_.isCasting()) {
if (!this.sender_ || !this.sender_.isCasting()) {
let value = this.localVideo_[name];
if (typeof value == 'function') {
value = value.bind(this.localVideo_);
Expand All @@ -509,7 +577,7 @@ shaka.cast.CastProxy = class extends shaka.util.FakeEventTarget {
* @private
*/
videoProxySet_(name, value) {
if (!this.sender_.isCasting()) {
if (!this.sender_ || !this.sender_.isCasting()) {
this.localVideo_[name] = value;
return;
}
Expand All @@ -522,7 +590,7 @@ shaka.cast.CastProxy = class extends shaka.util.FakeEventTarget {
* @private
*/
videoProxyLocalEvent_(event) {
if (this.sender_.isCasting()) {
if (this.sender_ && this.sender_.isCasting()) {
// Ignore any unexpected local events while casting. Events can still be
// fired by the local video and Player when we unload() after the Cast
// connection is complete.
Expand Down Expand Up @@ -561,7 +629,9 @@ shaka.cast.CastProxy = class extends shaka.util.FakeEventTarget {
if (name == 'getSharedConfiguration') {
shaka.log.warning(
'Can\'t share configuration across a network. Returning copy.');
return this.sender_.get('player', 'getConfiguration');
return this.sender_ ?
this.sender_.get('player', 'getConfiguration') :
this.localPlayer_.getConfiguration();
}

if (name == 'getNetworkingEngine') {
Expand All @@ -574,7 +644,7 @@ shaka.cast.CastProxy = class extends shaka.util.FakeEventTarget {
return () => this.localPlayer_.getNetworkingEngine();
}

if (this.sender_.isCasting()) {
if (this.sender_ && this.sender_.isCasting()) {
// These methods are unavailable or otherwise stubbed during casting.
if (name == 'getManifest' || name == 'drmInfo') {
return () => {
Expand Down Expand Up @@ -602,7 +672,8 @@ shaka.cast.CastProxy = class extends shaka.util.FakeEventTarget {

// If we are casting, but the first update has not come in yet, use local
// getters, but not local methods.
if (this.sender_.isCasting() && !this.sender_.hasRemoteProperties()) {
if (this.sender_ && this.sender_.isCasting() &&
!this.sender_.hasRemoteProperties()) {
if (shaka.cast.CastUtils.PlayerGetterMethods[name]) {
const value = /** @type {Object} */(this.localPlayer_)[name];
goog.asserts.assert(typeof value == 'function',
Expand All @@ -612,7 +683,7 @@ shaka.cast.CastProxy = class extends shaka.util.FakeEventTarget {
}

// Use local getters and methods if we are not casting.
if (!this.sender_.isCasting()) {
if (!this.sender_ || !this.sender_.isCasting()) {
const value = /** @type {Object} */(this.localPlayer_)[name];
goog.asserts.assert(typeof value == 'function',
'only methods on Player');
Expand All @@ -627,7 +698,7 @@ shaka.cast.CastProxy = class extends shaka.util.FakeEventTarget {
* @private
*/
playerProxyLocalEvent_(event) {
if (this.sender_.isCasting()) {
if (this.sender_ && this.sender_.isCasting()) {
// Ignore any unexpected local events while casting.
return;
}
Expand All @@ -641,7 +712,7 @@ shaka.cast.CastProxy = class extends shaka.util.FakeEventTarget {
* @private
*/
onRemoteEvent_(targetName, event) {
goog.asserts.assert(this.sender_.isCasting(),
goog.asserts.assert(this.sender_ && this.sender_.isCasting(),
'Should only receive remote events while casting');
if (!this.sender_.isCasting()) {
// Ignore any unexpected remote events.
Expand Down
6 changes: 6 additions & 0 deletions lib/util/error.js
Expand Up @@ -804,6 +804,12 @@ shaka.util.Error.Code = {
'CAST_RECEIVER_APP_UNAVAILABLE': 8006,


/**
* No receiver app id has been provided, making casting impossible.
*/
'CAST_RECEIVER_APP_ID_MISSING': 8007,


/**
* Offline storage is not supported on this browser; it is required for
* offline support.
Expand Down
2 changes: 2 additions & 0 deletions ui/controls.js
Expand Up @@ -353,6 +353,8 @@ shaka.ui.Controls = class extends shaka.util.FakeEventTarget {
configure(config) {
this.config_ = config;

this.castProxy_.changeReceiverId(config.castReceiverAppId);

if (this.controlsContainer_) {
// Deconstruct the old layout if applicable
shaka.util.Dom.removeAllChildren(this.controlsContainer_);
Expand Down

0 comments on commit 3e3e940

Please sign in to comment.