senza-sdk 4.3.1-ca3d96f.0 → 4.3.1-e113d43.0
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 +8 -9
- package/src/api.js +2 -14
- package/src/implementation/api.js +4 -0
- package/src/implementation/lifecycle.js +10 -9
- package/src/implementation/messageManager.js +33 -0
- package/src/implementation/platformManager.js +19 -0
- package/src/implementation/remotePlayer.js +215 -17
- package/src/implementation/senzaShakaPlayer.js +127 -104
- package/src/interface/alarmManager.js +21 -28
- package/src/interface/devSequence.js +0 -35
- package/src/interface/deviceManager.js +21 -30
- package/src/interface/lifecycle.js +39 -44
- package/src/interface/messageManager.js +27 -34
- package/src/interface/platformManager.js +5 -11
- package/src/interface/remotePlayer.js +180 -209
- package/src/interface/senzaShakaPlayer.js +5 -2
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { shaka } from "../interface/senzaShakaPlayer";
|
|
2
2
|
|
|
3
3
|
import { remotePlayer, lifecycle, getPlatformInfo } from "./api";
|
|
4
4
|
import { sdkLogger, iso6393to1 } from "./utils";
|
|
5
|
-
import moment from "moment";
|
|
6
|
-
|
|
7
5
|
|
|
8
6
|
// Define custom error category
|
|
9
7
|
shaka.util.Error.Category.SENZA_PLAYER_ERROR = 50;
|
|
@@ -33,7 +31,26 @@ class SenzaError extends shaka.util.Error {
|
|
|
33
31
|
}
|
|
34
32
|
|
|
35
33
|
|
|
36
|
-
|
|
34
|
+
/**
|
|
35
|
+
* SenzaShakaPlayer subclass of Shaka that handles both local and remote playback.
|
|
36
|
+
*
|
|
37
|
+
* @class SenzaShakaPlayer
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* import { SenzaShakaPlayer } from "./senzaShakaPlayer.js";
|
|
41
|
+
*
|
|
42
|
+
* try {
|
|
43
|
+
* const videoElement = document.getElementById("video");
|
|
44
|
+
* const player = new SenzaShakaPlayer(videoElement);
|
|
45
|
+
* await player.load("http://playable.url/file.mpd");
|
|
46
|
+
* await videoElement.play(); // will start the playback
|
|
47
|
+
*
|
|
48
|
+
* } catch (err) {
|
|
49
|
+
* console.error("SenzaShakaPlayer failed with error", err);
|
|
50
|
+
* }
|
|
51
|
+
*/
|
|
52
|
+
|
|
53
|
+
export class SenzaShakaPlayer extends shaka.Player {
|
|
37
54
|
/** @private {SenzaShakaPlayer|null} Previous instance of the player */
|
|
38
55
|
static _prevInstance = null;
|
|
39
56
|
|
|
@@ -55,9 +72,9 @@ export class SenzaShakaPlayer extends SenzaShakaInterface {
|
|
|
55
72
|
* @private
|
|
56
73
|
* @type {number}
|
|
57
74
|
* @description Timeout in milliseconds to wait for playing event
|
|
58
|
-
* @default
|
|
75
|
+
* @default 3000
|
|
59
76
|
*/
|
|
60
|
-
_playingTimeout =
|
|
77
|
+
_playingTimeout = 3000;
|
|
61
78
|
|
|
62
79
|
/**
|
|
63
80
|
* @private
|
|
@@ -72,7 +89,7 @@ export class SenzaShakaPlayer extends SenzaShakaInterface {
|
|
|
72
89
|
* @description Whether to stop remote player on error
|
|
73
90
|
* @default false
|
|
74
91
|
*/
|
|
75
|
-
|
|
92
|
+
_shouldStopRemotePlayerOnError = false;
|
|
76
93
|
|
|
77
94
|
/**
|
|
78
95
|
* @private
|
|
@@ -118,7 +135,7 @@ export class SenzaShakaPlayer extends SenzaShakaInterface {
|
|
|
118
135
|
});
|
|
119
136
|
}
|
|
120
137
|
},
|
|
121
|
-
"pause": () => {
|
|
138
|
+
"pause" : () => {
|
|
122
139
|
this._resetPlayPromise();
|
|
123
140
|
this.remotePlayer.pause()
|
|
124
141
|
.catch(error => {
|
|
@@ -263,15 +280,13 @@ export class SenzaShakaPlayer extends SenzaShakaInterface {
|
|
|
263
280
|
|
|
264
281
|
|
|
265
282
|
/**
|
|
266
|
-
* Handles errors
|
|
267
|
-
* The promise returned to the call for video element play will be rejected.
|
|
283
|
+
* Handles errors for play promises and remote player events.
|
|
268
284
|
* @private
|
|
269
285
|
* @param {Error} error - The error object.
|
|
270
286
|
*/
|
|
271
287
|
_handlePlayPromiseError(error) {
|
|
272
288
|
|
|
273
289
|
sdkLogger.error("Error while waiting for playing event:", error);
|
|
274
|
-
|
|
275
290
|
if (this._playPromiseReject) {
|
|
276
291
|
this._playPromiseReject(error);
|
|
277
292
|
this._playPromiseResolve = null;
|
|
@@ -281,48 +296,16 @@ export class SenzaShakaPlayer extends SenzaShakaInterface {
|
|
|
281
296
|
clearTimeout(this._playTimeoutId);
|
|
282
297
|
this._playTimeoutId = null;
|
|
283
298
|
}
|
|
284
|
-
|
|
285
299
|
}
|
|
286
300
|
|
|
287
301
|
/**
|
|
288
|
-
*
|
|
289
|
-
*
|
|
290
|
-
* @
|
|
291
|
-
* @
|
|
302
|
+
* Creates an instance of SenzaShakaPlayer, which is a subclass of shaka.Player.
|
|
303
|
+
*
|
|
304
|
+
* @param {HTMLVideoElement} videoElement - The video element to be used for local playback. This parameter is optional. If not provided, the video element can be attached later using the attach method.
|
|
305
|
+
* @param {HTMLElement=} videoContainer - The videoContainer to construct UITextDisplayer
|
|
306
|
+
* @param {function(shaka.Player)=} dependencyInjector Optional callback
|
|
307
|
+
* which is called to inject mocks into the Player. Used for testing.
|
|
292
308
|
*/
|
|
293
|
-
_minSuggestedPresentationDelay = 15;
|
|
294
|
-
|
|
295
|
-
/**
|
|
296
|
-
* Modifies the suggestedPresentationDelay in the manifest text
|
|
297
|
-
* @private
|
|
298
|
-
* @param {string} manifestText - The MPD manifest text
|
|
299
|
-
* @returns {string} - Modified manifest text , or undefined if no modification was done
|
|
300
|
-
*/
|
|
301
|
-
_updateManifestDelayIfBelowMinimum(manifestText) {
|
|
302
|
-
// Look for suggestedPresentationDelay attribute
|
|
303
|
-
const match = manifestText.match(/suggestedPresentationDelay="([^"]+)"/);
|
|
304
|
-
if (match) {
|
|
305
|
-
const durationString = match[1];
|
|
306
|
-
const duration = moment.duration(durationString);
|
|
307
|
-
const currentDelay = duration.asSeconds();
|
|
308
|
-
|
|
309
|
-
sdkLogger.info(`Found suggestedPresentationDelay in manifest: ${currentDelay.toFixed(3)}s`);
|
|
310
|
-
|
|
311
|
-
if (currentDelay < this._minSuggestedPresentationDelay) {
|
|
312
|
-
// Replace the value in the manifest text with 3 decimal places
|
|
313
|
-
manifestText = manifestText.replace(
|
|
314
|
-
/suggestedPresentationDelay="[^"]+"/,
|
|
315
|
-
`suggestedPresentationDelay="PT${this._minSuggestedPresentationDelay.toFixed(3)}S"`
|
|
316
|
-
);
|
|
317
|
-
sdkLogger.info(`Updated manifest suggestedPresentationDelay to ${this._minSuggestedPresentationDelay.toFixed(3)}s`);
|
|
318
|
-
return manifestText;
|
|
319
|
-
}
|
|
320
|
-
} else {
|
|
321
|
-
sdkLogger.info("suggestedPresentationDelay is not defined at the manifest");
|
|
322
|
-
}
|
|
323
|
-
return undefined;
|
|
324
|
-
}
|
|
325
|
-
|
|
326
309
|
constructor(videoElement, videoContainer, dependencyInjector) {
|
|
327
310
|
super(videoElement, videoContainer, dependencyInjector);
|
|
328
311
|
|
|
@@ -340,14 +323,7 @@ export class SenzaShakaPlayer extends SenzaShakaInterface {
|
|
|
340
323
|
this._addRemotePlayerEventListeners();
|
|
341
324
|
SenzaShakaPlayer._prevInstance = this;
|
|
342
325
|
const playTimeout = getPlatformInfo()?.sessionInfo?.settings?.["ui-streamer"]?.playingEventTimeout;
|
|
343
|
-
this._playingTimeout = (playTimeout >= 0) ? playTimeout
|
|
344
|
-
|
|
345
|
-
// Initialize minSuggestedPresentationDelay from UI settings or use default
|
|
346
|
-
const uiSettings = getPlatformInfo()?.sessionInfo?.settings?.["ui-streamer"];
|
|
347
|
-
if (uiSettings?.minSuggestedPresentationDelay !== undefined) {
|
|
348
|
-
this._minSuggestedPresentationDelay = uiSettings.minSuggestedPresentationDelay;
|
|
349
|
-
sdkLogger.info(`Using configured minSuggestedPresentationDelay: ${this._minSuggestedPresentationDelay}s`);
|
|
350
|
-
}
|
|
326
|
+
this._playingTimeout = (playTimeout >= 0) ? playTimeout*1000 : this._playingTimeout;
|
|
351
327
|
|
|
352
328
|
// if video element is provided, add the listeres here. In this case ,there is no need to call attach.
|
|
353
329
|
if (videoElement) {
|
|
@@ -355,25 +331,8 @@ export class SenzaShakaPlayer extends SenzaShakaInterface {
|
|
|
355
331
|
sdkLogger.warn("SenzaShakaPlayer constructor Adding videoElement in the constructor is going to be deprecated in the future. Please use attach method instead.");
|
|
356
332
|
}
|
|
357
333
|
|
|
358
|
-
this.configure({
|
|
359
|
-
manifest: {
|
|
360
|
-
defaultPresentationDelay: this._minSuggestedPresentationDelay // in seconds
|
|
361
|
-
}
|
|
362
|
-
});
|
|
363
|
-
|
|
364
|
-
remotePlayer.configure({
|
|
365
|
-
minSuggestedPresentationDelay: this._minSuggestedPresentationDelay
|
|
366
|
-
});
|
|
367
|
-
|
|
368
|
-
this.addEventListener("buffering", () => {
|
|
369
|
-
if (this.videoElement) {
|
|
370
|
-
sdkLogger.info("Buffering at time:", this.videoElement.currentTime);
|
|
371
|
-
}
|
|
372
|
-
});
|
|
373
|
-
|
|
374
334
|
}
|
|
375
335
|
|
|
376
|
-
|
|
377
336
|
_attach(videoElement) {
|
|
378
337
|
this.videoElement = videoElement;
|
|
379
338
|
|
|
@@ -420,11 +379,27 @@ export class SenzaShakaPlayer extends SenzaShakaInterface {
|
|
|
420
379
|
this._attachVideoElementToRemotePlayer();
|
|
421
380
|
}
|
|
422
381
|
|
|
382
|
+
/**
|
|
383
|
+
* Overrides the attach method of shaka.Player to attach the video element.
|
|
384
|
+
*
|
|
385
|
+
* @param {HTMLVideoElement} videoElement - The video element to be used for local playback.
|
|
386
|
+
* @param {boolean} [initializeMediaSource=true] - Whether to initialize the media source.
|
|
387
|
+
*/
|
|
423
388
|
async attach(videoElement, initializeMediaSource = true) {
|
|
424
389
|
await super.attach(videoElement, initializeMediaSource);
|
|
425
390
|
this._attach(videoElement);
|
|
426
391
|
}
|
|
427
392
|
|
|
393
|
+
/**
|
|
394
|
+
* Detach the player from the current media element. Leaves the player in a
|
|
395
|
+
* state where it cannot play media, until it has been attached to something
|
|
396
|
+
* else.
|
|
397
|
+
*
|
|
398
|
+
* @param {boolean=} keepAdManager
|
|
399
|
+
*
|
|
400
|
+
* @return {!Promise}
|
|
401
|
+
* @export
|
|
402
|
+
*/
|
|
428
403
|
async detach(keepAdManager = false) {
|
|
429
404
|
// Clear any pending timeout
|
|
430
405
|
this._resetPlayPromise();
|
|
@@ -455,6 +430,14 @@ export class SenzaShakaPlayer extends SenzaShakaInterface {
|
|
|
455
430
|
this.videoElement = null;
|
|
456
431
|
}
|
|
457
432
|
|
|
433
|
+
/**
|
|
434
|
+
* Unloads the currently playing stream, if any.
|
|
435
|
+
*
|
|
436
|
+
* @param {boolean=} initializeMediaSource
|
|
437
|
+
* @param {boolean=} keepAdManager
|
|
438
|
+
* @return {!Promise}
|
|
439
|
+
* @export
|
|
440
|
+
*/
|
|
458
441
|
async unload(initializeMediaSource = true, keepAdManager = false) {
|
|
459
442
|
// Call the remote player's unload method
|
|
460
443
|
try {
|
|
@@ -469,14 +452,27 @@ export class SenzaShakaPlayer extends SenzaShakaInterface {
|
|
|
469
452
|
await super.unload(initializeMediaSource, keepAdManager);
|
|
470
453
|
}
|
|
471
454
|
|
|
455
|
+
/**
|
|
456
|
+
* Overrides the getTextTracks method to use the remote player's text tracks.
|
|
457
|
+
* @returns {Array} An array of text tracks.
|
|
458
|
+
*/
|
|
472
459
|
getTextLanguages() {
|
|
473
460
|
return Object.keys(this._textTracksMap);
|
|
474
461
|
}
|
|
475
462
|
|
|
463
|
+
/**
|
|
464
|
+
* Overrides the getAudioTracks method to use the remote player's audio tracks.
|
|
465
|
+
* @returns {Array} An array of audio tracks.
|
|
466
|
+
*/
|
|
476
467
|
getAudioLanguages() {
|
|
477
468
|
return Object.keys(this._audioTracksMap);
|
|
478
469
|
}
|
|
479
470
|
|
|
471
|
+
/**
|
|
472
|
+
* Overrides the selectAudioLanguage method to use the remote player's audio track selection.
|
|
473
|
+
* @param {string} language - The language to select.
|
|
474
|
+
* @param {string=} role - The role of the track to select. (e.g. 'main', 'caption', or 'commentary')
|
|
475
|
+
*/
|
|
480
476
|
selectAudioLanguage(language, role) {
|
|
481
477
|
sdkLogger.log("Selecting audio language:", language, "with role: ", role);
|
|
482
478
|
if (this._audioTracksMap[language]) {
|
|
@@ -487,6 +483,11 @@ export class SenzaShakaPlayer extends SenzaShakaInterface {
|
|
|
487
483
|
super.selectAudioLanguage(language, role);
|
|
488
484
|
}
|
|
489
485
|
|
|
486
|
+
/**
|
|
487
|
+
* Overrides the selectTextLanguage method to use the remote player's text track selection.
|
|
488
|
+
* @param {string} language - The language to select.
|
|
489
|
+
* @param {string=} role - The role of the track to select.
|
|
490
|
+
*/
|
|
490
491
|
selectTextLanguage(language, role) {
|
|
491
492
|
sdkLogger.log("Selecting text language:", language, "with role:", role);
|
|
492
493
|
if (this._textTracksMap[language]) {
|
|
@@ -497,12 +498,20 @@ export class SenzaShakaPlayer extends SenzaShakaInterface {
|
|
|
497
498
|
super.selectTextLanguage(language, role);
|
|
498
499
|
}
|
|
499
500
|
|
|
501
|
+
/**
|
|
502
|
+
* Overrides the setTextTrackVisibility method to use the remote player's text track visibility settings.
|
|
503
|
+
* @param {boolean} visible - Whether the text tracks should be visible.
|
|
504
|
+
*/
|
|
500
505
|
setTextTrackVisibility(visible) {
|
|
501
506
|
sdkLogger.log("Setting text track visibility to:", visible);
|
|
502
507
|
remotePlayer.setTextTrackVisibility(visible);
|
|
503
508
|
super.setTextTrackVisibility(visible);
|
|
504
509
|
}
|
|
505
510
|
|
|
511
|
+
/**
|
|
512
|
+
* Helper function that makes it easier to check if lifecycle.state is
|
|
513
|
+
* either background or inTransitionToBackground.
|
|
514
|
+
*/
|
|
506
515
|
get isInRemotePlayback() {
|
|
507
516
|
return lifecycle.state === lifecycle.UiState.BACKGROUND || lifecycle.state === lifecycle.UiState.IN_TRANSITION_TO_BACKGROUND;
|
|
508
517
|
}
|
|
@@ -547,12 +556,11 @@ export class SenzaShakaPlayer extends SenzaShakaInterface {
|
|
|
547
556
|
const isCritical = this._isErrorCritical(remotePlayerErrorCode);
|
|
548
557
|
const error = this._createSenzaError(remotePlayerErrorCode, message, isCritical);
|
|
549
558
|
const errorMap = new Map();
|
|
550
|
-
const shouldStopPlayback = this._shouldStopOnRemotePlayerError && this.videoElement && isCritical;
|
|
551
559
|
errorMap.set("detail", error);
|
|
552
560
|
|
|
553
561
|
// Check if we should stop playback - only for critical errors when configured
|
|
554
|
-
|
|
555
|
-
|
|
562
|
+
if (this._shouldStopRemotePlayerOnError &&
|
|
563
|
+
this.videoElement && isCritical) {
|
|
556
564
|
try {
|
|
557
565
|
sdkLogger.warn("Stopping local player playback due to critical error");
|
|
558
566
|
// Stop only local playback
|
|
@@ -560,14 +568,18 @@ export class SenzaShakaPlayer extends SenzaShakaInterface {
|
|
|
560
568
|
} catch (stopError) {
|
|
561
569
|
sdkLogger.error("Error while trying to stop video element playback:", stopError);
|
|
562
570
|
}
|
|
563
|
-
// Handle error while waiting for play event. If the error is not critical or the system is configured not to stop remote player on error,
|
|
564
|
-
// the playback timeout will start the local playback
|
|
565
|
-
this._handlePlayPromiseError(error);
|
|
566
571
|
}
|
|
567
|
-
|
|
572
|
+
// Handle error while waiting for play event
|
|
573
|
+
this._handlePlayPromiseError(error);
|
|
568
574
|
this.dispatchEvent(new shaka.util.FakeEvent("error", errorMap));
|
|
569
575
|
}
|
|
570
576
|
|
|
577
|
+
/**
|
|
578
|
+
* Loads a media URL into both local and remote players.
|
|
579
|
+
*
|
|
580
|
+
* @param {string} url - The URL of the media to load.
|
|
581
|
+
* @returns {Promise<void>}
|
|
582
|
+
*/
|
|
571
583
|
async load(url, startTime, mimeType) {
|
|
572
584
|
|
|
573
585
|
// Create a promise that will resolve when _remotePlayerLoad is called
|
|
@@ -596,30 +608,16 @@ export class SenzaShakaPlayer extends SenzaShakaInterface {
|
|
|
596
608
|
|
|
597
609
|
// This callbakc will be activated when the manifest is loaded. It will trigger load of the remote player.
|
|
598
610
|
// This will ensure that the remote player is loaded only after the manifest is loaded by local player.
|
|
599
|
-
const responseFilterCallback = async (type
|
|
600
|
-
if (type === shaka.net.NetworkingEngine.RequestType.MANIFEST) {
|
|
611
|
+
const responseFilterCallback = async (type) => {
|
|
612
|
+
if (type === shaka.net.NetworkingEngine.RequestType.MANIFEST && !manifestLoadHandled) {
|
|
613
|
+
manifestLoadHandled = true;
|
|
601
614
|
try {
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
const modifiedText = this._updateManifestDelayIfBelowMinimum(manifestText);
|
|
605
|
-
if (modifiedText) {
|
|
606
|
-
const responseData = new TextEncoder().encode(modifiedText).buffer;
|
|
607
|
-
response.data = responseData;
|
|
608
|
-
}
|
|
609
|
-
}
|
|
615
|
+
await this._remotePlayerLoad(url, startTime);
|
|
616
|
+
remoteLoadResolver();
|
|
610
617
|
} catch (error) {
|
|
611
|
-
|
|
618
|
+
remoteLoadRejecter(error);
|
|
612
619
|
}
|
|
613
620
|
|
|
614
|
-
if (!manifestLoadHandled) {
|
|
615
|
-
manifestLoadHandled = true;
|
|
616
|
-
try {
|
|
617
|
-
await this._remotePlayerLoad(url, startTime);
|
|
618
|
-
remoteLoadResolver();
|
|
619
|
-
} catch (error) {
|
|
620
|
-
remoteLoadRejecter(error);
|
|
621
|
-
}
|
|
622
|
-
}
|
|
623
621
|
}
|
|
624
622
|
};
|
|
625
623
|
|
|
@@ -654,6 +652,13 @@ export class SenzaShakaPlayer extends SenzaShakaInterface {
|
|
|
654
652
|
|
|
655
653
|
}
|
|
656
654
|
|
|
655
|
+
/***
|
|
656
|
+
*
|
|
657
|
+
* Configure the Player instance.
|
|
658
|
+
* @param {Object} config the configuration object
|
|
659
|
+
* @returns {Boolean}
|
|
660
|
+
*/
|
|
661
|
+
|
|
657
662
|
async destroy() {
|
|
658
663
|
await lifecycle.moveToForeground();
|
|
659
664
|
SenzaShakaPlayer._prevInstance = null;
|
|
@@ -661,6 +666,10 @@ export class SenzaShakaPlayer extends SenzaShakaInterface {
|
|
|
661
666
|
return super.destroy();
|
|
662
667
|
}
|
|
663
668
|
|
|
669
|
+
/**
|
|
670
|
+
* A temporary override for older versions of Shaka.
|
|
671
|
+
* Senza doesn't support out-of-band subtitles
|
|
672
|
+
*/
|
|
664
673
|
addTextTrack(uri, language, kind, mimeType, codec, label, forced = false) {
|
|
665
674
|
sdkLogger.warn("addTextTrack is deprecated, please use addTextTrackAsync");
|
|
666
675
|
super.addTextTrackAsync(uri, language, kind, mimeType, codec, label, forced).then(subs => {
|
|
@@ -668,16 +677,30 @@ export class SenzaShakaPlayer extends SenzaShakaInterface {
|
|
|
668
677
|
});
|
|
669
678
|
}
|
|
670
679
|
|
|
680
|
+
/**
|
|
681
|
+
* Override the configure method to add custom configuration handling
|
|
682
|
+
* Supports the following additional configuration options:
|
|
683
|
+
* - shouldStopRemotePlayerOnError: boolean - If true, remote player will be stopped on error
|
|
684
|
+
*
|
|
685
|
+
* @override
|
|
686
|
+
* @param {Object} config - Configuration object to be merged with existing config
|
|
687
|
+
* @param {boolean} [config.shouldStopRemotePlayerOnError=true] - Whether to stop remote player on error
|
|
688
|
+
* @example
|
|
689
|
+
* player.configure({
|
|
690
|
+
* shouldStopRemotePlayerOnError: false, // Don't stop remote player on error
|
|
691
|
+
* // ... other shaka configurations
|
|
692
|
+
* });
|
|
693
|
+
*/
|
|
671
694
|
configure(config) {
|
|
672
695
|
sdkLogger.log("configure player with: ", JSON.stringify(config));
|
|
673
696
|
|
|
674
697
|
// Handle custom configuration
|
|
675
|
-
if (config.
|
|
676
|
-
this.
|
|
698
|
+
if (config.shouldStopRemotePlayerOnError !== undefined) {
|
|
699
|
+
this._shouldStopRemotePlayerOnError = !!config.shouldStopRemotePlayerOnError;
|
|
677
700
|
// Remove our custom config so it doesn't get passed to parent
|
|
678
701
|
// Use rest operator without creating a named variable for the removed property
|
|
679
702
|
// eslint-disable-next-line no-unused-vars
|
|
680
|
-
const {
|
|
703
|
+
const { shouldStopRemotePlayerOnError, ...shakaConfig } = config;
|
|
681
704
|
config = shakaConfig;
|
|
682
705
|
}
|
|
683
706
|
|
|
@@ -1,28 +1,31 @@
|
|
|
1
1
|
import { noop } from "./utils";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* alarm event
|
|
5
|
-
*
|
|
6
|
-
* @event AlarmManager#MyAlarm
|
|
7
|
-
* @description Fired when time of 'MyAlarm' arrives. If this alarm triggers the application load and the application doesn't call
|
|
8
|
-
* lifecycle.moveToForeground() in the alarm callback (i.e. the application remains in the background after the callback is completed),
|
|
9
|
-
* the application will be unloaded.
|
|
10
|
-
* NOTE: If you perform async operations in the callback (without moving to foreground), you must wait for the async
|
|
11
|
-
* operation to finish before returning from the callback, otherwise the application will be unloaded before the async operation is finished.<br>
|
|
12
|
-
* @example
|
|
13
|
-
* alarmManager.addEventListener("MyAlarm", async (e) => {
|
|
14
|
-
* console.log("alarm MyAlarm arrived with data", e.detail);
|
|
15
|
-
* await fetch("http://www.example.com");
|
|
16
|
-
* });
|
|
17
|
-
* alarmManager.addAlarm("MyAlarm", Date.now() + 60*60*1000, "MyData");
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
2
|
/**
|
|
3
|
+
* @class AlarmManager
|
|
21
4
|
* AlarmManager is a singleton class that manages the alarms in the application. It fires events whose types are the names of the alarms.
|
|
22
5
|
* @fires MyAlarm
|
|
23
6
|
*/
|
|
24
7
|
export class AlarmManager extends EventTarget {
|
|
25
8
|
|
|
9
|
+
/**
|
|
10
|
+
* alarm event
|
|
11
|
+
*
|
|
12
|
+
* @event AlarmManager#MyAlarm
|
|
13
|
+
* @description Fired when time of 'MyAlarm' arrives. If this alarm triggers the application load and the application doesn't call
|
|
14
|
+
* lifecycle.moveToForeground() in the alarm callback (i.e. the application remains in the background after the callback is completed),
|
|
15
|
+
* the application will be unloaded.
|
|
16
|
+
* NOTE: If you perform async operations in the callback (without moving to foreground), you must wait for the async
|
|
17
|
+
* operation to finish before returning from the callback, otherwise the application will be unloaded before the async operation is finished.<br>
|
|
18
|
+
* @example
|
|
19
|
+
* alarmManager.addEventListener("MyAlarm", async (e) => {
|
|
20
|
+
* console.log("alarm MyAlarm arrived with data", e.detail);
|
|
21
|
+
* await fetch("http://www.example.com");
|
|
22
|
+
* });
|
|
23
|
+
* alarmManager.addAlarm("MyAlarm", Date.now() + 60*60*1000, "MyData");
|
|
24
|
+
*/
|
|
25
|
+
constructor() {
|
|
26
|
+
super();
|
|
27
|
+
}
|
|
28
|
+
|
|
26
29
|
addEventListener(type, callback) {
|
|
27
30
|
noop("AlarmManager.addEventListener", type, callback);
|
|
28
31
|
}
|
|
@@ -64,13 +67,3 @@ export class AlarmManager extends EventTarget {
|
|
|
64
67
|
return noop("AlarmManager.getActiveAlarms");
|
|
65
68
|
}
|
|
66
69
|
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* @module
|
|
70
|
-
* @type {AlarmManager}
|
|
71
|
-
* @example
|
|
72
|
-
* import { alarmManager } from "senza-sdk";
|
|
73
|
-
*
|
|
74
|
-
* @return {AlarmManager} pointer to the AlarmManager singleton
|
|
75
|
-
*/
|
|
76
|
-
"needed for the module doc comment to be recognized";
|
|
@@ -204,7 +204,6 @@ const setupSequence = (components, items) => {
|
|
|
204
204
|
};
|
|
205
205
|
methodInject(components, inject, (name) => name.startsWith("_") || name.startsWith("get"));
|
|
206
206
|
handleKeys(items);
|
|
207
|
-
playersEvents(components, items);
|
|
208
207
|
sdkLogger.log("Sequence initialized.");
|
|
209
208
|
};
|
|
210
209
|
|
|
@@ -258,37 +257,3 @@ export const showSequence = (visible = true) => {
|
|
|
258
257
|
}
|
|
259
258
|
container.style.visibility = visible ? "visible" : "hidden";
|
|
260
259
|
};
|
|
261
|
-
function playersEvents(components, items) {
|
|
262
|
-
components.remotePlayer.addEventListener("videoelementattached", () => {
|
|
263
|
-
const video = components.remotePlayer._videoElement;
|
|
264
|
-
if (video && !video._devSequenceRateChangeHandler) {
|
|
265
|
-
video._devSequenceRateChangeHandler = () => {
|
|
266
|
-
items.push({
|
|
267
|
-
component: "localPlayer",
|
|
268
|
-
id: "ratechange=" + video.playbackRate,
|
|
269
|
-
time: performance.now() - currentTime
|
|
270
|
-
});
|
|
271
|
-
};
|
|
272
|
-
video.addEventListener("ratechange", video._devSequenceRateChangeHandler);
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
if (video && !video._devSequencePlayingHandler) {
|
|
276
|
-
video._devSequencePlayingHandler = () => {
|
|
277
|
-
items.push({
|
|
278
|
-
component: "localPlayer",
|
|
279
|
-
id: "playing event",
|
|
280
|
-
time: performance.now() - currentTime
|
|
281
|
-
});
|
|
282
|
-
};
|
|
283
|
-
video.addEventListener("playing", video._devSequencePlayingHandler);
|
|
284
|
-
}
|
|
285
|
-
});
|
|
286
|
-
components.remotePlayer.addEventListener("playing", () => {
|
|
287
|
-
items.push({
|
|
288
|
-
component: "remotePlayer",
|
|
289
|
-
id: "playing event",
|
|
290
|
-
time: performance.now() - currentTime
|
|
291
|
-
});
|
|
292
|
-
});
|
|
293
|
-
}
|
|
294
|
-
|
|
@@ -1,24 +1,30 @@
|
|
|
1
1
|
import { sdkLogger, noop } from "./utils.js";
|
|
2
2
|
|
|
3
|
-
const wifiInfo = {
|
|
4
|
-
|
|
5
|
-
quality: 0,
|
|
6
|
-
ssid: "unknown",
|
|
7
|
-
bssid: "unknown"
|
|
8
|
-
};
|
|
9
|
-
/**
|
|
10
|
-
* @deprecated Instead, call deviceManager.getWifiInfo() periodically
|
|
11
|
-
* @event DeviceManager#wifiInfoUpdated
|
|
12
|
-
* @example
|
|
13
|
-
* deviceManager.addEventListener("wifiInfoUpdated", () => {
|
|
14
|
-
* console.info("Wifi info has been updated to", deviceManager.wifiInfo);
|
|
15
|
-
* });
|
|
16
|
-
*
|
|
17
|
-
*/
|
|
3
|
+
const wifiInfo = {};
|
|
4
|
+
|
|
18
5
|
/**
|
|
6
|
+
* @class DeviceManager
|
|
19
7
|
* DeviceManager is a singleton class that manages the device
|
|
20
8
|
*/
|
|
21
9
|
export class DeviceManager extends EventTarget {
|
|
10
|
+
|
|
11
|
+
constructor() {
|
|
12
|
+
super();
|
|
13
|
+
wifiInfo.level = 0;
|
|
14
|
+
wifiInfo.quality = 0;
|
|
15
|
+
wifiInfo.ssid = "unknown";
|
|
16
|
+
wifiInfo.bssid = "unknown";
|
|
17
|
+
/**
|
|
18
|
+
* @deprecated Instead, call deviceManager.getWifiInfo() periodically
|
|
19
|
+
* @event DeviceManager#wifiInfoUpdated
|
|
20
|
+
* @example
|
|
21
|
+
* deviceManager.addEventListener("wifiInfoUpdated", () => {
|
|
22
|
+
* console.info("Wifi info has been updated to", deviceManager.wifiInfo);
|
|
23
|
+
* });
|
|
24
|
+
*
|
|
25
|
+
*/
|
|
26
|
+
}
|
|
27
|
+
|
|
22
28
|
/**
|
|
23
29
|
* @property {object} DeviceInfo
|
|
24
30
|
* @property {string} DeviceInfo.deviceId
|
|
@@ -125,18 +131,3 @@ export class DeviceManager extends EventTarget {
|
|
|
125
131
|
return Promise.resolve({});
|
|
126
132
|
}
|
|
127
133
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* @module
|
|
132
|
-
* @type {DeviceManager}
|
|
133
|
-
* @example
|
|
134
|
-
* import { deviceManager } from "senza-sdk";
|
|
135
|
-
* const wifiInfo = await deviceManager.getWifiInfo();
|
|
136
|
-
* console.info(wifiInfo.ssid);
|
|
137
|
-
* await deviceManager.clearWifi();
|
|
138
|
-
* deviceManager.reboot();
|
|
139
|
-
*
|
|
140
|
-
* @return {DeviceManager} pointer to the DeviceManager singleton
|
|
141
|
-
*/
|
|
142
|
-
"needed for the module doc comment to be recognized";
|