senza-sdk 4.2.55-fb0c331.0 → 4.2.56
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundle.js +1 -1
- package/package.json +1 -1
- package/src/remotePlayer.js +6 -8
- package/src/senzaShakaPlayer.js +80 -23
package/package.json
CHANGED
package/src/remotePlayer.js
CHANGED
|
@@ -1031,6 +1031,8 @@ class RemotePlayer extends EventTarget {
|
|
|
1031
1031
|
if (this._loadMode === this.LoadMode.LOADING || this._loadMode === this.LoadMode.UNLOADING) {
|
|
1032
1032
|
throw new RemotePlayerError(6502, "Cannot call unload() while previous unload/load is still in progress");
|
|
1033
1033
|
}
|
|
1034
|
+
this._abortSetAudioLanguage = true;
|
|
1035
|
+
this._abortSetSubtitleLanguage = true;
|
|
1034
1036
|
this._abortSeeking = true;
|
|
1035
1037
|
const previousLoadMode = this._loadMode;
|
|
1036
1038
|
this._changeLoadMode(this.LoadMode.UNLOADING);
|
|
@@ -1326,7 +1328,7 @@ class RemotePlayer extends EventTarget {
|
|
|
1326
1328
|
|
|
1327
1329
|
/**
|
|
1328
1330
|
* Handles the asynchronous selection of an audio track.
|
|
1329
|
-
*
|
|
1331
|
+
* It stops audio streamType before changing the track and resumes audio streamType playback if necessary.
|
|
1330
1332
|
* Available only from v3 and on
|
|
1331
1333
|
*
|
|
1332
1334
|
* @param {string} audioTrackId - The ID of the audio track to select.
|
|
@@ -1462,7 +1464,7 @@ class RemotePlayer extends EventTarget {
|
|
|
1462
1464
|
|
|
1463
1465
|
/**
|
|
1464
1466
|
* Handles the asynchronous selection of a text track.
|
|
1465
|
-
*
|
|
1467
|
+
* It stops subtitle streamType before changing the track and resumes subtitle streamType playback if necessary.
|
|
1466
1468
|
* Available only from v3 and on
|
|
1467
1469
|
*
|
|
1468
1470
|
* @param {string} textTrackId - The ID of the text track to select.
|
|
@@ -1775,9 +1777,7 @@ class RemotePlayer extends EventTarget {
|
|
|
1775
1777
|
await this._stop(StreamType.AUDIO);
|
|
1776
1778
|
} catch (error) {
|
|
1777
1779
|
sdkLogger.warn(`remotePlayer _atomicSetAudioLanguage: audioTrackId=${audioTrackId} failed on stop with error ${error.message}.`);
|
|
1778
|
-
|
|
1779
|
-
setLanguageError = error;
|
|
1780
|
-
}
|
|
1780
|
+
// ignore error
|
|
1781
1781
|
}
|
|
1782
1782
|
|
|
1783
1783
|
// check if load/unload were called
|
|
@@ -1844,9 +1844,7 @@ class RemotePlayer extends EventTarget {
|
|
|
1844
1844
|
await this._stop(StreamType.SUBTITLE);
|
|
1845
1845
|
} catch (error) {
|
|
1846
1846
|
sdkLogger.warn(`remotePlayer _atomicSetSubtitleLanguage: textTrackId=${textTrackId} stop failed with error ${error.message}.`);
|
|
1847
|
-
|
|
1848
|
-
setLanguageError = error;
|
|
1849
|
-
}
|
|
1847
|
+
// ignore error
|
|
1850
1848
|
}
|
|
1851
1849
|
|
|
1852
1850
|
// check if load/unload were called
|
package/src/senzaShakaPlayer.js
CHANGED
|
@@ -208,6 +208,8 @@ export class SenzaShakaPlayer extends shaka.Player {
|
|
|
208
208
|
sdkLogger.warn("SenzaShakaPlayer constructor Adding videoElement in the constructor is going to be deprecated in the future. Please use attach method instead.");
|
|
209
209
|
}
|
|
210
210
|
SenzaShakaPlayer._prevInstance = this;
|
|
211
|
+
|
|
212
|
+
|
|
211
213
|
}
|
|
212
214
|
|
|
213
215
|
/**
|
|
@@ -233,6 +235,7 @@ export class SenzaShakaPlayer extends shaka.Player {
|
|
|
233
235
|
* @export
|
|
234
236
|
*/
|
|
235
237
|
async detach(keepAdManager = false) {
|
|
238
|
+
|
|
236
239
|
await super.detach(keepAdManager);
|
|
237
240
|
this._audioTracksMap = {};
|
|
238
241
|
this._textTracksMap = {};
|
|
@@ -400,46 +403,74 @@ export class SenzaShakaPlayer extends shaka.Player {
|
|
|
400
403
|
*/
|
|
401
404
|
async load(url, startTime, mimeType) {
|
|
402
405
|
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
};
|
|
406
|
+
// Create a promise that will resolve when _remotePlayerLoad is called
|
|
407
|
+
let remoteLoadResolver;
|
|
408
|
+
let remoteLoadRejecter;
|
|
409
|
+
const remoteLoadPromise = new Promise((resolve,reject) => {
|
|
410
|
+
remoteLoadResolver = resolve;
|
|
411
|
+
remoteLoadRejecter = reject;
|
|
412
|
+
});
|
|
413
|
+
// Create a flag to indicate whether the manifest load has been handled
|
|
414
|
+
let manifestLoadHandled = false;
|
|
415
|
+
const MANIFEST_TIMEOUT = 15000;
|
|
410
416
|
|
|
411
417
|
// For live streams, we can set a default offset from the live edge
|
|
412
418
|
// This allows for synchronizing the start position for both local and remote players
|
|
413
419
|
// Note: For VOD content, negative start times are treated as 0
|
|
420
|
+
|
|
414
421
|
const { defaultInitialLiveOffset, minInitialLiveOffset } = getPlatformInfo()?.sessionInfo?.settings?.["ui-streamer"] || {};
|
|
415
422
|
if ((startTime === undefined || startTime === 0) && defaultInitialLiveOffset !== undefined) {
|
|
416
|
-
sdkLogger.
|
|
423
|
+
sdkLogger.info(`load() was called with startTime=${startTime}, setting startTime to ${-defaultInitialLiveOffset}`);
|
|
417
424
|
startTime = -defaultInitialLiveOffset;
|
|
418
425
|
} else if (startTime <= 0 && minInitialLiveOffset !== undefined && startTime > -minInitialLiveOffset) {
|
|
419
|
-
sdkLogger.
|
|
426
|
+
sdkLogger.info(`load() was called with startTime=${startTime}, setting startTime to ${-minInitialLiveOffset}`);
|
|
420
427
|
startTime = -minInitialLiveOffset;
|
|
421
428
|
}
|
|
422
429
|
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
await
|
|
430
|
+
// This callbakc will be activated when the manifest is loaded. It will trigger load of the remote player.
|
|
431
|
+
// This will ensure that the remote player is loaded only after the manifest is loaded by local player.
|
|
432
|
+
const responseFilterCallback = async (type) => {
|
|
433
|
+
if (type === shaka.net.NetworkingEngine.RequestType.MANIFEST && !manifestLoadHandled) {
|
|
434
|
+
manifestLoadHandled = true;
|
|
435
|
+
try {
|
|
436
|
+
await this._remotePlayerLoad(url, startTime);
|
|
437
|
+
remoteLoadResolver();
|
|
438
|
+
} catch (error) {
|
|
439
|
+
remoteLoadRejecter(error);
|
|
430
440
|
}
|
|
431
|
-
|
|
432
|
-
} catch (error) {
|
|
433
|
-
sdkLogger.log("Couldn't load remote player. Error:", error);
|
|
434
|
-
this.handleSenzaError(error.code, error.message);
|
|
441
|
+
|
|
435
442
|
}
|
|
436
|
-
}
|
|
443
|
+
};
|
|
444
|
+
|
|
445
|
+
// Register the response filter
|
|
446
|
+
this.getNetworkingEngine().registerResponseFilter(responseFilterCallback);
|
|
447
|
+
|
|
448
|
+
const loadPromise = Promise.all([
|
|
449
|
+
super.load(url, startTime, mimeType),
|
|
450
|
+
remoteLoadPromise
|
|
451
|
+
]);
|
|
452
|
+
// Set a timeout for the manifest load notification
|
|
453
|
+
let timerId;
|
|
454
|
+
const timerPromise = new Promise((_, reject) => {
|
|
455
|
+
timerId = setTimeout(() => {
|
|
456
|
+
const error = new Error("Manifest load timeout");
|
|
457
|
+
error.code = 8003;
|
|
458
|
+
reject(error);
|
|
459
|
+
}, MANIFEST_TIMEOUT);
|
|
460
|
+
});
|
|
461
|
+
|
|
437
462
|
try {
|
|
438
|
-
await
|
|
463
|
+
return await Promise.race([loadPromise, timerPromise]);
|
|
464
|
+
|
|
439
465
|
} catch (error) {
|
|
440
|
-
sdkLogger.log("Couldn't load
|
|
466
|
+
sdkLogger.log("Couldn't load player. Error:", error);
|
|
441
467
|
this.handleSenzaError(error.code, error.message);
|
|
468
|
+
|
|
469
|
+
} finally {
|
|
470
|
+
this.getNetworkingEngine().unregisterResponseFilter(responseFilterCallback);
|
|
471
|
+
clearTimeout(timerId);
|
|
442
472
|
}
|
|
473
|
+
|
|
443
474
|
}
|
|
444
475
|
|
|
445
476
|
/***
|
|
@@ -508,6 +539,32 @@ export class SenzaShakaPlayer extends shaka.Player {
|
|
|
508
539
|
|
|
509
540
|
}
|
|
510
541
|
|
|
542
|
+
async _remotePlayerLoad(url,startTime) {
|
|
543
|
+
const waitForLoadModeChange = () => {
|
|
544
|
+
const timeout = this.remotePlayer._remotePlayerConfirmationTimeout + 2000;
|
|
545
|
+
return Promise.race([
|
|
546
|
+
new Promise(resolve => this.remotePlayer.addEventListener("onloadmodechange", resolve, { once: true })),
|
|
547
|
+
new Promise((_, reject) => setTimeout(() => reject(`Timeout: Event "onloadmodechange" did not occur within ${timeout}ms`), timeout))
|
|
548
|
+
]);
|
|
549
|
+
};
|
|
550
|
+
|
|
551
|
+
if (!this.isInRemotePlayback || remotePlayer.getAssetUri() !== url) {
|
|
552
|
+
this._audioTracksMap = {};
|
|
553
|
+
this._videoTracksMap = {};
|
|
554
|
+
try {
|
|
555
|
+
if (this.remotePlayer.getLoadMode() === this.remotePlayer.LoadMode.UNLOADING) {
|
|
556
|
+
sdkLogger.warn("load() was called while previous unload is still in progress, waiting for unload to finish");
|
|
557
|
+
await waitForLoadModeChange();
|
|
558
|
+
}
|
|
559
|
+
sdkLogger.info("Loading remote player with startTime:", startTime);
|
|
560
|
+
await this.remotePlayer.load(url, startTime);
|
|
561
|
+
sdkLogger.log("Remote player loaded successfully");
|
|
562
|
+
} catch (error) {
|
|
563
|
+
sdkLogger.error("Couldn't load remote player. Error:", error);
|
|
564
|
+
this.handleSenzaError(error.code, error.message);
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
}
|
|
511
568
|
/**
|
|
512
569
|
* @private
|
|
513
570
|
*/
|