diff --git a/lib/cast/cast_proxy.js b/lib/cast/cast_proxy.js index 700d8f1f9b7..e2852f8d85c 100644 --- a/lib/cast/cast_proxy.js +++ b/lib/cast/cast_proxy.js @@ -81,17 +81,21 @@ shaka.cast.CastProxy = class extends shaka.util.FakeEventTarget { this.compiledToExternNames_ = new Map(); /** @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_(), - androidReceiverCompatible); - + this.sender_ = null; - this.init_(); + if (window.chrome) { + this.sender_ = new shaka.cast.CastSender( + receiverAppId, + () => this.onCastStatusChanged_(), + () => this.onFirstCastStateUpdate_(), + (targetName, event) => this.onRemoteEvent_(targetName, event), + () => this.onResumeLocal_(), + () => this.getInitState_(), + androidReceiverCompatible); + this.init_(); + } else { + this.initWithoutSender_(); + } } /** @@ -163,6 +167,9 @@ shaka.cast.CastProxy = class extends shaka.util.FakeEventTarget { * @export */ canCast() { + if (!this.sender_) { + return false; + } return this.sender_.apiReady() && this.sender_.hasReceivers(); } @@ -171,6 +178,9 @@ shaka.cast.CastProxy = class extends shaka.util.FakeEventTarget { * @export */ isCasting() { + if (!this.sender_) { + return false; + } return this.sender_.isCasting(); } @@ -179,6 +189,9 @@ shaka.cast.CastProxy = class extends shaka.util.FakeEventTarget { * @export */ receiverName() { + if (!this.sender_) { + return ''; + } return this.sender_.receiverName(); } @@ -188,6 +201,9 @@ shaka.cast.CastProxy = class extends shaka.util.FakeEventTarget { * @export */ async cast() { + if (!this.sender_) { + return; + } // TODO: transfer manually-selected tracks? // TODO: transfer side-loaded text tracks? @@ -208,6 +224,9 @@ shaka.cast.CastProxy = class extends shaka.util.FakeEventTarget { * @export */ setAppData(appData) { + if (!this.sender_) { + return; + } this.sender_.setAppData(appData); } @@ -216,6 +235,9 @@ shaka.cast.CastProxy = class extends shaka.util.FakeEventTarget { * @export */ suggestDisconnect() { + if (!this.sender_) { + return; + } this.sender_.showDisconnectDialog(); } @@ -224,6 +246,9 @@ shaka.cast.CastProxy = class extends shaka.util.FakeEventTarget { * @export */ forceDisconnect() { + if (!this.sender_) { + return; + } this.sender_.forceDisconnect(); } @@ -243,6 +268,10 @@ shaka.cast.CastProxy = class extends shaka.util.FakeEventTarget { this.receiverAppId_ = newAppId; this.androidReceiverCompatible_ = newCastAndroidReceiver; + if (!this.sender_) { + return; + } + // Destroy the old sender this.sender_.forceDisconnect(); await this.sender_.destroy(); @@ -262,6 +291,15 @@ shaka.cast.CastProxy = class extends shaka.util.FakeEventTarget { this.sender_.init(); } + /** + * Initialize the Proxies without Cast sender. + * @private + */ + initWithoutSender_() { + this.videoProxy_ = /** @type {Object} */(this.localVideo_); + this.playerProxy_ = /** @type {Object} */(this.localPlayer_); + } + /** * Initialize the Proxies and the Cast sender. * @private diff --git a/test/cast/cast_proxy_unit.js b/test/cast/cast_proxy_unit.js index c4f2d3e5b32..39ac2772c0e 100644 --- a/test/cast/cast_proxy_unit.js +++ b/test/cast/cast_proxy_unit.js @@ -23,7 +23,11 @@ describe('CastProxy', () => { /** @type {shaka.cast.CastProxy} */ let proxy; + const originalWindowChrome = window.chrome; + beforeEach(() => { + window.chrome = window.chrome || {}; + mockCastSenderConstructor = jasmine.createSpy('CastSender constructor'); mockCastSenderConstructor.and.callFake(createMockCastSender); shaka.cast.CastSender = Util.spyFunc(mockCastSenderConstructor); @@ -42,6 +46,7 @@ describe('CastProxy', () => { } finally { shaka.cast.CastSender = originalCastSender; } + window.chrome = originalWindowChrome; }); describe('constructor', () => {