senza-sdk 4.2.65-d2761c0.0 → 4.3.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/dist/implementation.bundle.js +2 -0
- package/dist/implementation.bundle.js.LICENSE.txt +57 -0
- package/package.json +18 -9
- package/src/api.js +258 -327
- package/src/{alarmManager.js → implementation/alarmManager.js} +15 -52
- package/src/implementation/api.js +363 -0
- package/src/{deviceManager.js → implementation/deviceManager.js} +6 -78
- package/src/{lifecycle.js → implementation/lifecycle.js} +37 -225
- package/src/implementation/messageManager.js +55 -0
- package/src/{platformManager.js → implementation/platformManager.js} +5 -23
- package/src/{remotePlayer.js → implementation/remotePlayer.js} +35 -237
- package/src/{senzaShakaPlayer.js → implementation/senzaShakaPlayer.js} +92 -125
- package/src/{utils.js → implementation/utils.js} +15 -6
- package/src/interface/alarmManager.js +76 -0
- package/src/interface/api.js +8 -0
- package/src/{devSequence.js → interface/devSequence.js} +35 -0
- package/src/interface/deviceManager.js +143 -0
- package/src/interface/lifecycle.js +284 -0
- package/src/interface/messageManager.js +54 -0
- package/src/interface/platformManager.js +42 -0
- package/src/interface/remotePlayer.js +469 -0
- package/src/interface/senzaShakaPlayer.js +168 -0
- package/src/interface/utils.js +45 -0
- package/src/messageManager.js +0 -88
- /package/src/{SessionInfo.js → implementation/SessionInfo.js} +0 -0
- /package/src/{devHelper.js → implementation/devHelper.js} +0 -0
- /package/src/{eventListenersManager.js → implementation/eventListenersManager.js} +0 -0
- /package/src/{subtitlesUtils.js → implementation/subtitlesUtils.js} +0 -0
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { SenzaShakaPlayer as SenzaShakaInterface, shaka } from "../interface/senzaShakaPlayer";
|
|
2
|
+
|
|
2
3
|
import { remotePlayer, lifecycle, getPlatformInfo } from "./api";
|
|
3
4
|
import { sdkLogger, iso6393to1 } from "./utils";
|
|
5
|
+
import moment from "moment";
|
|
6
|
+
|
|
4
7
|
|
|
5
8
|
// Define custom error category
|
|
6
9
|
shaka.util.Error.Category.SENZA_PLAYER_ERROR = 50;
|
|
@@ -30,31 +33,7 @@ class SenzaError extends shaka.util.Error {
|
|
|
30
33
|
}
|
|
31
34
|
|
|
32
35
|
|
|
33
|
-
|
|
34
|
-
// if we don't Copy the shaka module, the Player class will be replaced for all the other modules that import shaka
|
|
35
|
-
const senzaShaka = { ...shaka };
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* SenzaShakaPlayer subclass of Shaka that handles both local and remote playback.
|
|
40
|
-
*
|
|
41
|
-
* @class SenzaShakaPlayer
|
|
42
|
-
*
|
|
43
|
-
* @example
|
|
44
|
-
* import { SenzaShakaPlayer } from "./senzaShakaPlayer.js";
|
|
45
|
-
*
|
|
46
|
-
* try {
|
|
47
|
-
* const videoElement = document.getElementById("video");
|
|
48
|
-
* const player = new SenzaShakaPlayer(videoElement);
|
|
49
|
-
* await player.load("http://playable.url/file.mpd");
|
|
50
|
-
* await videoElement.play(); // will start the playback
|
|
51
|
-
*
|
|
52
|
-
* } catch (err) {
|
|
53
|
-
* console.error("SenzaShakaPlayer failed with error", err);
|
|
54
|
-
* }
|
|
55
|
-
*/
|
|
56
|
-
|
|
57
|
-
export class SenzaShakaPlayer extends shaka.Player {
|
|
36
|
+
export class SenzaShakaPlayer extends SenzaShakaInterface {
|
|
58
37
|
/** @private {SenzaShakaPlayer|null} Previous instance of the player */
|
|
59
38
|
static _prevInstance = null;
|
|
60
39
|
|
|
@@ -76,7 +55,7 @@ export class SenzaShakaPlayer extends shaka.Player {
|
|
|
76
55
|
* @private
|
|
77
56
|
* @type {number}
|
|
78
57
|
* @description Timeout in milliseconds to wait for playing event
|
|
79
|
-
* @default
|
|
58
|
+
* @default 4000
|
|
80
59
|
*/
|
|
81
60
|
_playingTimeout = 4000;
|
|
82
61
|
|
|
@@ -139,7 +118,7 @@ export class SenzaShakaPlayer extends shaka.Player {
|
|
|
139
118
|
});
|
|
140
119
|
}
|
|
141
120
|
},
|
|
142
|
-
"pause"
|
|
121
|
+
"pause": () => {
|
|
143
122
|
this._resetPlayPromise();
|
|
144
123
|
this.remotePlayer.pause()
|
|
145
124
|
.catch(error => {
|
|
@@ -185,7 +164,7 @@ export class SenzaShakaPlayer extends shaka.Player {
|
|
|
185
164
|
originatesFromRemotePlayer: true
|
|
186
165
|
};
|
|
187
166
|
|
|
188
|
-
const response = await this.getNetworkingEngine().request(
|
|
167
|
+
const response = await this.getNetworkingEngine().request(shaka.net.NetworkingEngine.RequestType.LICENSE, request).promise;
|
|
189
168
|
|
|
190
169
|
let responseBody = response.data;
|
|
191
170
|
if (response.status < 200 || response.status >= 300) {
|
|
@@ -306,13 +285,44 @@ export class SenzaShakaPlayer extends shaka.Player {
|
|
|
306
285
|
}
|
|
307
286
|
|
|
308
287
|
/**
|
|
309
|
-
*
|
|
310
|
-
*
|
|
311
|
-
* @
|
|
312
|
-
* @
|
|
313
|
-
* @param {function(shaka.Player)=} dependencyInjector Optional callback
|
|
314
|
-
* which is called to inject mocks into the Player. Used for testing.
|
|
288
|
+
* @private
|
|
289
|
+
* @type {number}
|
|
290
|
+
* @description Minimum suggested presentation delay in seconds
|
|
291
|
+
* @default 15
|
|
315
292
|
*/
|
|
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
|
+
|
|
316
326
|
constructor(videoElement, videoContainer, dependencyInjector) {
|
|
317
327
|
super(videoElement, videoContainer, dependencyInjector);
|
|
318
328
|
|
|
@@ -330,7 +340,14 @@ export class SenzaShakaPlayer extends shaka.Player {
|
|
|
330
340
|
this._addRemotePlayerEventListeners();
|
|
331
341
|
SenzaShakaPlayer._prevInstance = this;
|
|
332
342
|
const playTimeout = getPlatformInfo()?.sessionInfo?.settings?.["ui-streamer"]?.playingEventTimeout;
|
|
333
|
-
this._playingTimeout = (playTimeout >= 0) ? playTimeout*1000 : this._playingTimeout;
|
|
343
|
+
this._playingTimeout = (playTimeout >= 0) ? playTimeout * 1000 : this._playingTimeout;
|
|
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
|
+
}
|
|
334
351
|
|
|
335
352
|
// if video element is provided, add the listeres here. In this case ,there is no need to call attach.
|
|
336
353
|
if (videoElement) {
|
|
@@ -338,8 +355,25 @@ export class SenzaShakaPlayer extends shaka.Player {
|
|
|
338
355
|
sdkLogger.warn("SenzaShakaPlayer constructor Adding videoElement in the constructor is going to be deprecated in the future. Please use attach method instead.");
|
|
339
356
|
}
|
|
340
357
|
|
|
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
|
+
|
|
341
374
|
}
|
|
342
375
|
|
|
376
|
+
|
|
343
377
|
_attach(videoElement) {
|
|
344
378
|
this.videoElement = videoElement;
|
|
345
379
|
|
|
@@ -386,27 +420,11 @@ export class SenzaShakaPlayer extends shaka.Player {
|
|
|
386
420
|
this._attachVideoElementToRemotePlayer();
|
|
387
421
|
}
|
|
388
422
|
|
|
389
|
-
/**
|
|
390
|
-
* Overrides the attach method of shaka.Player to attach the video element.
|
|
391
|
-
*
|
|
392
|
-
* @param {HTMLVideoElement} videoElement - The video element to be used for local playback.
|
|
393
|
-
* @param {boolean} [initializeMediaSource=true] - Whether to initialize the media source.
|
|
394
|
-
*/
|
|
395
423
|
async attach(videoElement, initializeMediaSource = true) {
|
|
396
424
|
await super.attach(videoElement, initializeMediaSource);
|
|
397
425
|
this._attach(videoElement);
|
|
398
426
|
}
|
|
399
427
|
|
|
400
|
-
/**
|
|
401
|
-
* Detach the player from the current media element. Leaves the player in a
|
|
402
|
-
* state where it cannot play media, until it has been attached to something
|
|
403
|
-
* else.
|
|
404
|
-
*
|
|
405
|
-
* @param {boolean=} keepAdManager
|
|
406
|
-
*
|
|
407
|
-
* @return {!Promise}
|
|
408
|
-
* @export
|
|
409
|
-
*/
|
|
410
428
|
async detach(keepAdManager = false) {
|
|
411
429
|
// Clear any pending timeout
|
|
412
430
|
this._resetPlayPromise();
|
|
@@ -437,14 +455,6 @@ export class SenzaShakaPlayer extends shaka.Player {
|
|
|
437
455
|
this.videoElement = null;
|
|
438
456
|
}
|
|
439
457
|
|
|
440
|
-
/**
|
|
441
|
-
* Unloads the currently playing stream, if any.
|
|
442
|
-
*
|
|
443
|
-
* @param {boolean=} initializeMediaSource
|
|
444
|
-
* @param {boolean=} keepAdManager
|
|
445
|
-
* @return {!Promise}
|
|
446
|
-
* @export
|
|
447
|
-
*/
|
|
448
458
|
async unload(initializeMediaSource = true, keepAdManager = false) {
|
|
449
459
|
// Call the remote player's unload method
|
|
450
460
|
try {
|
|
@@ -459,27 +469,14 @@ export class SenzaShakaPlayer extends shaka.Player {
|
|
|
459
469
|
await super.unload(initializeMediaSource, keepAdManager);
|
|
460
470
|
}
|
|
461
471
|
|
|
462
|
-
/**
|
|
463
|
-
* Overrides the getTextTracks method to use the remote player's text tracks.
|
|
464
|
-
* @returns {Array} An array of text tracks.
|
|
465
|
-
*/
|
|
466
472
|
getTextLanguages() {
|
|
467
473
|
return Object.keys(this._textTracksMap);
|
|
468
474
|
}
|
|
469
475
|
|
|
470
|
-
/**
|
|
471
|
-
* Overrides the getAudioTracks method to use the remote player's audio tracks.
|
|
472
|
-
* @returns {Array} An array of audio tracks.
|
|
473
|
-
*/
|
|
474
476
|
getAudioLanguages() {
|
|
475
477
|
return Object.keys(this._audioTracksMap);
|
|
476
478
|
}
|
|
477
479
|
|
|
478
|
-
/**
|
|
479
|
-
* Overrides the selectAudioLanguage method to use the remote player's audio track selection.
|
|
480
|
-
* @param {string} language - The language to select.
|
|
481
|
-
* @param {string=} role - The role of the track to select. (e.g. 'main', 'caption', or 'commentary')
|
|
482
|
-
*/
|
|
483
480
|
selectAudioLanguage(language, role) {
|
|
484
481
|
sdkLogger.log("Selecting audio language:", language, "with role: ", role);
|
|
485
482
|
if (this._audioTracksMap[language]) {
|
|
@@ -490,11 +487,6 @@ export class SenzaShakaPlayer extends shaka.Player {
|
|
|
490
487
|
super.selectAudioLanguage(language, role);
|
|
491
488
|
}
|
|
492
489
|
|
|
493
|
-
/**
|
|
494
|
-
* Overrides the selectTextLanguage method to use the remote player's text track selection.
|
|
495
|
-
* @param {string} language - The language to select.
|
|
496
|
-
* @param {string=} role - The role of the track to select.
|
|
497
|
-
*/
|
|
498
490
|
selectTextLanguage(language, role) {
|
|
499
491
|
sdkLogger.log("Selecting text language:", language, "with role:", role);
|
|
500
492
|
if (this._textTracksMap[language]) {
|
|
@@ -505,20 +497,12 @@ export class SenzaShakaPlayer extends shaka.Player {
|
|
|
505
497
|
super.selectTextLanguage(language, role);
|
|
506
498
|
}
|
|
507
499
|
|
|
508
|
-
/**
|
|
509
|
-
* Overrides the setTextTrackVisibility method to use the remote player's text track visibility settings.
|
|
510
|
-
* @param {boolean} visible - Whether the text tracks should be visible.
|
|
511
|
-
*/
|
|
512
500
|
setTextTrackVisibility(visible) {
|
|
513
501
|
sdkLogger.log("Setting text track visibility to:", visible);
|
|
514
502
|
remotePlayer.setTextTrackVisibility(visible);
|
|
515
503
|
super.setTextTrackVisibility(visible);
|
|
516
504
|
}
|
|
517
505
|
|
|
518
|
-
/**
|
|
519
|
-
* Helper function that makes it easier to check if lifecycle.state is
|
|
520
|
-
* either background or inTransitionToBackground.
|
|
521
|
-
*/
|
|
522
506
|
get isInRemotePlayback() {
|
|
523
507
|
return lifecycle.state === lifecycle.UiState.BACKGROUND || lifecycle.state === lifecycle.UiState.IN_TRANSITION_TO_BACKGROUND;
|
|
524
508
|
}
|
|
@@ -584,12 +568,6 @@ export class SenzaShakaPlayer extends shaka.Player {
|
|
|
584
568
|
this.dispatchEvent(new shaka.util.FakeEvent("error", errorMap));
|
|
585
569
|
}
|
|
586
570
|
|
|
587
|
-
/**
|
|
588
|
-
* Loads a media URL into both local and remote players.
|
|
589
|
-
*
|
|
590
|
-
* @param {string} url - The URL of the media to load.
|
|
591
|
-
* @returns {Promise<void>}
|
|
592
|
-
*/
|
|
593
571
|
async load(url, startTime, mimeType) {
|
|
594
572
|
|
|
595
573
|
// Create a promise that will resolve when _remotePlayerLoad is called
|
|
@@ -618,16 +596,30 @@ export class SenzaShakaPlayer extends shaka.Player {
|
|
|
618
596
|
|
|
619
597
|
// This callbakc will be activated when the manifest is loaded. It will trigger load of the remote player.
|
|
620
598
|
// This will ensure that the remote player is loaded only after the manifest is loaded by local player.
|
|
621
|
-
const responseFilterCallback = async (type) => {
|
|
622
|
-
if (type === shaka.net.NetworkingEngine.RequestType.MANIFEST
|
|
623
|
-
manifestLoadHandled = true;
|
|
599
|
+
const responseFilterCallback = async (type, response) => {
|
|
600
|
+
if (type === shaka.net.NetworkingEngine.RequestType.MANIFEST) {
|
|
624
601
|
try {
|
|
625
|
-
|
|
626
|
-
|
|
602
|
+
if (response.data && this._minSuggestedPresentationDelay > 0) {
|
|
603
|
+
const manifestText = new TextDecoder().decode(response.data);
|
|
604
|
+
const modifiedText = this._updateManifestDelayIfBelowMinimum(manifestText);
|
|
605
|
+
if (modifiedText) {
|
|
606
|
+
const responseData = new TextEncoder().encode(modifiedText).buffer;
|
|
607
|
+
response.data = responseData;
|
|
608
|
+
}
|
|
609
|
+
}
|
|
627
610
|
} catch (error) {
|
|
628
|
-
|
|
611
|
+
sdkLogger.error("Error processing manifest:", error);
|
|
629
612
|
}
|
|
630
613
|
|
|
614
|
+
if (!manifestLoadHandled) {
|
|
615
|
+
manifestLoadHandled = true;
|
|
616
|
+
try {
|
|
617
|
+
await this._remotePlayerLoad(url, startTime);
|
|
618
|
+
remoteLoadResolver();
|
|
619
|
+
} catch (error) {
|
|
620
|
+
remoteLoadRejecter(error);
|
|
621
|
+
}
|
|
622
|
+
}
|
|
631
623
|
}
|
|
632
624
|
};
|
|
633
625
|
|
|
@@ -662,13 +654,6 @@ export class SenzaShakaPlayer extends shaka.Player {
|
|
|
662
654
|
|
|
663
655
|
}
|
|
664
656
|
|
|
665
|
-
/***
|
|
666
|
-
*
|
|
667
|
-
* Configure the Player instance.
|
|
668
|
-
* @param {Object} config the configuration object
|
|
669
|
-
* @returns {Boolean}
|
|
670
|
-
*/
|
|
671
|
-
|
|
672
657
|
async destroy() {
|
|
673
658
|
await lifecycle.moveToForeground();
|
|
674
659
|
SenzaShakaPlayer._prevInstance = null;
|
|
@@ -676,10 +661,6 @@ export class SenzaShakaPlayer extends shaka.Player {
|
|
|
676
661
|
return super.destroy();
|
|
677
662
|
}
|
|
678
663
|
|
|
679
|
-
/**
|
|
680
|
-
* A temporary override for older versions of Shaka.
|
|
681
|
-
* Senza doesn't support out-of-band subtitles
|
|
682
|
-
*/
|
|
683
664
|
addTextTrack(uri, language, kind, mimeType, codec, label, forced = false) {
|
|
684
665
|
sdkLogger.warn("addTextTrack is deprecated, please use addTextTrackAsync");
|
|
685
666
|
super.addTextTrackAsync(uri, language, kind, mimeType, codec, label, forced).then(subs => {
|
|
@@ -687,20 +668,6 @@ export class SenzaShakaPlayer extends shaka.Player {
|
|
|
687
668
|
});
|
|
688
669
|
}
|
|
689
670
|
|
|
690
|
-
/**
|
|
691
|
-
* Override the configure method to add custom configuration handling
|
|
692
|
-
* Supports the following additional configuration options:
|
|
693
|
-
* - shouldStopOnRemotePlayerError: boolean - If true, local player will be stopped on remote player error
|
|
694
|
-
*
|
|
695
|
-
* @override
|
|
696
|
-
* @param {Object} config - Configuration object to be merged with existing config
|
|
697
|
-
* @param {boolean} [config.shouldStopOnRemotePlayerError=true] - Whether to stop local player on remote player error
|
|
698
|
-
* @example
|
|
699
|
-
* player.configure({
|
|
700
|
-
* shouldStopOnRemotePlayerError: false, // Don't stop local playback on remote player error
|
|
701
|
-
* // ... other shaka configurations
|
|
702
|
-
* });
|
|
703
|
-
*/
|
|
704
671
|
configure(config) {
|
|
705
672
|
sdkLogger.log("configure player with: ", JSON.stringify(config));
|
|
706
673
|
|
|
@@ -810,5 +777,5 @@ export class SenzaShakaPlayer extends shaka.Player {
|
|
|
810
777
|
|
|
811
778
|
}
|
|
812
779
|
|
|
813
|
-
|
|
814
|
-
export {
|
|
780
|
+
shaka.Player = SenzaShakaPlayer;
|
|
781
|
+
export { shaka };
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import { getPlatformInfo } from "./api";
|
|
2
|
-
import pack from "../package.json";
|
|
3
2
|
import { sessionInfo } from "./SessionInfo";
|
|
4
|
-
const { version } = pack;
|
|
5
3
|
|
|
6
4
|
const REST_RESPONSE_TIMEOUT_SECONDS = 5;
|
|
7
5
|
|
|
6
|
+
export function getVersion() {
|
|
7
|
+
return typeof IMPLEMENTATION_VERSION !== "undefined"
|
|
8
|
+
// eslint-disable-next-line no-undef
|
|
9
|
+
? IMPLEMENTATION_VERSION
|
|
10
|
+
: "unknown";
|
|
11
|
+
};
|
|
12
|
+
|
|
8
13
|
export function getFCID() {
|
|
9
14
|
return Math.round(Math.random() * 100000) + "-" + getPlatformInfo().sessionInfo?.connectionId;
|
|
10
15
|
}
|
|
@@ -42,7 +47,7 @@ class SdkLogger {
|
|
|
42
47
|
console.info(`[hs-sdk] [metrics] ${JSON.stringify(metricObj)}`);
|
|
43
48
|
}
|
|
44
49
|
withFields(logFields) {
|
|
45
|
-
return new SdkLogger({...this.logFields, ...logFields});
|
|
50
|
+
return new SdkLogger({ ...this.logFields, ...logFields });
|
|
46
51
|
}
|
|
47
52
|
formatLogString(data) {
|
|
48
53
|
let logString = "[hs-sdk] " + data.join(" ");
|
|
@@ -51,9 +56,13 @@ class SdkLogger {
|
|
|
51
56
|
}
|
|
52
57
|
return logString;
|
|
53
58
|
}
|
|
59
|
+
addfields(fields) {
|
|
60
|
+
this.logFields = { ...this.logFields, ...fields };
|
|
61
|
+
return this;
|
|
62
|
+
}
|
|
54
63
|
}
|
|
55
64
|
|
|
56
|
-
export const sdkLogger = new SdkLogger({sdkVersion:
|
|
65
|
+
export const sdkLogger = new SdkLogger({ sdkVersion: getVersion(), url: window?.location?.href ?? "" });
|
|
57
66
|
|
|
58
67
|
export async function getRestResponse(messageName) {
|
|
59
68
|
|
|
@@ -64,14 +73,14 @@ export async function getRestResponse(messageName) {
|
|
|
64
73
|
|
|
65
74
|
return new Promise((resolve, reject) => {
|
|
66
75
|
const FCID = getFCID();
|
|
67
|
-
const logger = sdkLogger.withFields({FCID});
|
|
76
|
+
const logger = sdkLogger.withFields({ FCID });
|
|
68
77
|
const message = {
|
|
69
78
|
type: "restRequest",
|
|
70
79
|
name: messageName,
|
|
71
80
|
method: "GET",
|
|
72
81
|
fcid: FCID
|
|
73
82
|
};
|
|
74
|
-
const request = {target: "TC", waitForResponse: true, message: JSON.stringify(message)};
|
|
83
|
+
const request = { target: "TC", waitForResponse: true, message: JSON.stringify(message) };
|
|
75
84
|
let timeoutHandler = 0;
|
|
76
85
|
const queryId = window.cefQuery({
|
|
77
86
|
request: JSON.stringify(request),
|
|
@@ -0,0 +1,76 @@
|
|
|
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
|
+
/**
|
|
21
|
+
* AlarmManager is a singleton class that manages the alarms in the application. It fires events whose types are the names of the alarms.
|
|
22
|
+
* @fires MyAlarm
|
|
23
|
+
*/
|
|
24
|
+
class AlarmManager extends EventTarget {
|
|
25
|
+
|
|
26
|
+
addEventListener(type, callback) {
|
|
27
|
+
noop("AlarmManager.addEventListener", type, callback);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
removeEventListener(type, callback) {
|
|
31
|
+
noop("AlarmManager.removeEventListener", type, callback);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Set alarm to be fired at the specified time, event when ui is released
|
|
35
|
+
* @param {string} alarmName unique name for the alarm
|
|
36
|
+
* @param {number} alarmTime target time for the alarm to be fired, represented by the number of milliseconds elapsed since the epoch
|
|
37
|
+
* @param {string} [data] data to be passed back when the alarm is fired
|
|
38
|
+
* */
|
|
39
|
+
addAlarm(alarmName, alarmTime, data = "", toleranceBefore = 0, toleranceAfter = 0) {
|
|
40
|
+
noop("AlarmManager.addAlarm", alarmName, alarmTime, data, toleranceBefore, toleranceAfter);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** Delete the specified alarm
|
|
44
|
+
* @param {string} alarmName name of alarm to be deleted
|
|
45
|
+
*
|
|
46
|
+
* */
|
|
47
|
+
deleteAlarm(alarmName) {
|
|
48
|
+
noop("AlarmManager.deleteAlarm", alarmName);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** Delete all alarms
|
|
52
|
+
*
|
|
53
|
+
* */
|
|
54
|
+
deleteAllAlarms() {
|
|
55
|
+
noop("AlarmManager.deleteAllAlarms");
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** Async function that asks for all active alarms
|
|
59
|
+
* @returns {Promise} when resolved, returns an array of objects containing alarmName and alarmTime fields
|
|
60
|
+
* @throws {string} error string in case of an error
|
|
61
|
+
*
|
|
62
|
+
* */
|
|
63
|
+
getActiveAlarms() {
|
|
64
|
+
return noop("AlarmManager.getActiveAlarms");
|
|
65
|
+
}
|
|
66
|
+
}
|
|
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
|
+
export { AlarmManager };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { Lifecycle } from "./lifecycle.js";
|
|
2
|
+
export { DeviceManager } from "./deviceManager.js";
|
|
3
|
+
export { PlatformManager } from "./platformManager.js";
|
|
4
|
+
export { AlarmManager } from "./alarmManager.js";
|
|
5
|
+
export { MessageManager } from "./messageManager.js";
|
|
6
|
+
export { RemotePlayer } from "./remotePlayer.js";
|
|
7
|
+
export { SenzaShakaPlayer as ShakaPlayer, shaka } from "./senzaShakaPlayer.js";
|
|
8
|
+
export { showSequence, initSequence } from "./devSequence.js";
|
|
@@ -204,6 +204,7 @@ 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);
|
|
207
208
|
sdkLogger.log("Sequence initialized.");
|
|
208
209
|
};
|
|
209
210
|
|
|
@@ -257,3 +258,37 @@ export const showSequence = (visible = true) => {
|
|
|
257
258
|
}
|
|
258
259
|
container.style.visibility = visible ? "visible" : "hidden";
|
|
259
260
|
};
|
|
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
|
+
|