senza-sdk 4.2.53 → 4.2.54-01d7afc.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "senza-sdk",
3
- "version": "4.2.53",
3
+ "version": "4.2.54-01d7afc.0",
4
4
  "main": "./src/api.js",
5
5
  "description": "API for Senza application",
6
6
  "license": "MIT",
package/src/lifecycle.js CHANGED
@@ -102,7 +102,9 @@ class Lifecycle extends EventTarget {
102
102
  * @private
103
103
  */
104
104
  this._isInitialized = false;
105
- this._inTransition = false;
105
+ this._inTransitionToForeground = false;
106
+ this._inTransitionToBackground = false;
107
+ this._inTransitionToStandby = false;
106
108
 
107
109
  /**
108
110
  * Event listeners manager for the userdisconnected event
@@ -349,7 +351,7 @@ class Lifecycle extends EventTarget {
349
351
  // This api is part of epic HSDEV-713
350
352
  _moveToUiStandby() {
351
353
  if (window.cefQuery) {
352
- this._inTransition = true;
354
+ this._inTransitionToStandby = true;
353
355
  return new Promise((resolve, reject) => {
354
356
  const FCID = getFCID();
355
357
  const request = { target: "TC", waitForResponse: false, internalAction: "uiExit", message: JSON.stringify({ type: "uiStandbyRequest", fcid: FCID }) };
@@ -360,12 +362,12 @@ class Lifecycle extends EventTarget {
360
362
  persistent: false,
361
363
  onSuccess: () => {
362
364
  logger.log("[ moveToUiStandby ] moveToUiStandby successfully sent");
363
- this._inTransition = false;
365
+ this._inTransitionToStandby = false;
364
366
  resolve(true);
365
367
  },
366
368
  onFailure: (code, msg) => {
367
369
  logger.error(`[ moveToUiStandby ] moveToUiStandby failed: ${code} ${msg}`);
368
- this._inTransition = false;
370
+ this._inTransitionToStandby = false;
369
371
  reject(`moveToUiStandby failed: ${code} ${msg}`);
370
372
  }
371
373
  });
@@ -501,6 +503,14 @@ class Lifecycle extends EventTarget {
501
503
  this._countdown = null;
502
504
  }
503
505
 
506
+ /**
507
+ * @private
508
+ */
509
+ _isInTransition() {
510
+ return this._inTransitionToForeground || this._inTransitionToBackground || this._inTransitionToStandby;
511
+ }
512
+
513
+
504
514
  /**
505
515
  * @deprecated use lifecycle.state instead.
506
516
  * Async function that returns the ui lifecycle state
@@ -543,14 +553,19 @@ class Lifecycle extends EventTarget {
543
553
  */
544
554
  moveToForeground() {
545
555
  if (window.cefQuery) {
546
- if (this._inTransition || this._state === this.UiState.FOREGROUND || this._state === this.UiState.IN_TRANSITION_TO_FOREGROUND) {
547
- sdkLogger.warn(`lifecycle moveToForeground: No need to transition to foreground, state: ${this._state} transition: ${this._inTransition}`);
556
+ const inTransition = this._isInTransition();
557
+ if (inTransition || this._state === this.UiState.FOREGROUND || this._state === this.UiState.IN_TRANSITION_TO_FOREGROUND) {
558
+ sdkLogger.warn(`lifecycle moveToForeground: No need to transition to foreground, state: ${this._state} transition: ${inTransition}`);
548
559
  return Promise.resolve(false);
549
560
  }
550
- this._inTransition = true;
561
+ this._inTransitionToForeground = true;
551
562
  alarmManager._moveToForegroundCalled();
552
563
  const FCID = getFCID();
553
564
  if (this._remotePlayerApiVersion >= 2) {
565
+ // Only update to playing UI if we started seeking in ABR. But, if we are seeking while already paused, keep the target seek state as is.
566
+ if (remotePlayer._isSeekingByApplication && remotePlayer._targetSeekPlayingState === TargetPlayingState.PLAYING_ABR) {
567
+ remotePlayer._targetSeekPlayingState = TargetPlayingState.PLAYING_UI;
568
+ }
554
569
  return new Promise((resolve, reject) => {
555
570
  const FCID = getFCID();
556
571
  const logger = sdkLogger.withFields({ FCID });
@@ -570,14 +585,14 @@ class Lifecycle extends EventTarget {
570
585
  onSuccess: () => {
571
586
  const duration = Date.now() - timeBeforeSendingRequest;
572
587
  logger.withFields({ duration }).log(`stop completed successfully after ${duration} ms`);
573
- this._inTransition = false;
588
+ this._inTransitionToForeground = false;
574
589
  timerId = clearTimer(timerId);
575
590
  resolve(true);
576
591
  },
577
592
  onFailure: (code, msg) => {
578
593
  const duration = Date.now() - timeBeforeSendingRequest;
579
594
  logger.withFields({ duration }).log(`stop failed after ${duration} ms. Error code: ${code}, error message: ${msg}`);
580
- this._inTransition = false;
595
+ this._inTransitionToForeground = false;
581
596
  timerId = clearTimer(timerId);
582
597
  reject(new SenzaError(code, msg));
583
598
  }
@@ -586,7 +601,7 @@ class Lifecycle extends EventTarget {
586
601
  const timeout = this._remotePlayerConfirmationTimeout + 1000;
587
602
  timerId = setTimeout(() => {
588
603
  logger.log(`stop reached timeout of ${timeout} ms, canceling query id ${queryId}`);
589
- this._inTransition = false;
604
+ this._inTransitionToForeground = false;
590
605
  window.cefQueryCancel(queryId);
591
606
  reject(new SenzaError(6000, `stop reached timeout of ${timeout} ms`));
592
607
  }, timeout, queryId);
@@ -601,11 +616,11 @@ class Lifecycle extends EventTarget {
601
616
  persistent: false,
602
617
  onSuccess: () => {
603
618
  logger.log("uiActiveRequest successfully sent");
604
- this._inTransition = false;
619
+ this._inTransitionToForeground = false;
605
620
  resolve(true);
606
621
  },
607
622
  onFailure: (code, msg) => {
608
- this._inTransition = false;
623
+ this._inTransitionToForeground = false;
609
624
  logger.error(`uiActiveRequest failed: ${code} ${msg}`);
610
625
  reject(`uiActiveRequest failed: ${code} ${msg}`);
611
626
  }
@@ -618,10 +633,6 @@ class Lifecycle extends EventTarget {
618
633
 
619
634
  _moveToBackground() {
620
635
  if (window.cefQuery) {
621
- if (this._inTransition || this._state === this.UiState.BACKGROUND || this._state === this.UiState.IN_TRANSITION_TO_BACKGROUND) {
622
- sdkLogger.warn(`lifecycle moveToBackground: No need to transition to background, state: ${this._state} transition: ${this._inTransition}`);
623
- return Promise.resolve(false);
624
- }
625
636
  // If audio sync is disabled, we only need to sync before remote player starts playing
626
637
  if (!isAudioSyncConfigured()) {
627
638
  remotePlayer._syncRemotePlayerWithLocalPlayer();
@@ -633,7 +644,7 @@ class Lifecycle extends EventTarget {
633
644
  return this._moveToUiStandby();
634
645
  }
635
646
 
636
- this._inTransition = true;
647
+ this._inTransitionToBackground = true;
637
648
  return new Promise((resolve, reject) => {
638
649
  const FCID = getFCID();
639
650
  const logger = sdkLogger.withFields({ FCID });
@@ -670,14 +681,14 @@ class Lifecycle extends EventTarget {
670
681
  onSuccess: () => {
671
682
  const duration = Date.now() - timeBeforeSendingRequest;
672
683
  logger.withFields({ duration }).log(`play completed successfully after ${duration} ms`);
673
- this._inTransition = false;
684
+ this._inTransitionToBackground = false;
674
685
  timerId = clearTimer(timerId);
675
686
  resolve();
676
687
  },
677
688
  onFailure: (code, msg) => {
678
689
  const duration = Date.now() - timeBeforeSendingRequest;
679
690
  logger.withFields({ duration }).log(`play failed after ${duration} ms. Error code: ${code}, error message: ${msg}`);
680
- this._inTransition = false;
691
+ this._inTransitionToBackground = false;
681
692
  timerId = clearTimer(timerId);
682
693
  reject(new SenzaError(code, msg));
683
694
  }
@@ -687,7 +698,7 @@ class Lifecycle extends EventTarget {
687
698
  const timeout = this._remotePlayerConfirmationTimeout + 1000;
688
699
  timerId = setTimeout(() => {
689
700
  logger.log(`play reached timeout of ${timeout} ms, canceling query id ${queryId}`);
690
- this._inTransition = false;
701
+ this._inTransitionToBackground = false;
691
702
  window.cefQueryCancel(queryId);
692
703
  reject(new SenzaError(6000, `play reached timeout of ${timeout} ms`));
693
704
  }, timeout, queryId);
@@ -710,12 +721,13 @@ class Lifecycle extends EventTarget {
710
721
  * Failure to process the moveToBackground command will result in the promise being rejected.
711
722
  */
712
723
  moveToBackground() {
713
- if (remotePlayer._isSeekingByApplication) {
714
- if (window.cefQuery) {
715
- if (this._inTransition || this._state === this.UiState.BACKGROUND || this._state === this.UiState.IN_TRANSITION_TO_BACKGROUND) {
716
- sdkLogger.warn(`lifecycle moveToBackground: No need to transition to background, state: ${this._state} transition: ${this._inTransition}`);
717
- return Promise.resolve(false);
718
- }
724
+ if (window.cefQuery) {
725
+ const inTransition = this._isInTransition();
726
+ if (inTransition || this._state === this.UiState.BACKGROUND || this._state === this.UiState.IN_TRANSITION_TO_BACKGROUND) {
727
+ sdkLogger.warn(`lifecycle moveToBackground: No need to transition to background, state: ${this._state} transition: ${inTransition}`);
728
+ return Promise.resolve(false);
729
+ }
730
+ if (remotePlayer._isSeekingByApplication) {
719
731
  remotePlayer._targetSeekPlayingState = TargetPlayingState.PLAYING_ABR;
720
732
  return Promise.resolve(true);
721
733
  }
@@ -1454,15 +1454,15 @@ class RemotePlayer extends EventTarget {
1454
1454
  async _atomicSeek() {
1455
1455
  sdkLogger.info("Seeking: local video element seeking start while isPLaying=", this._isPlaying);
1456
1456
 
1457
- // Initialize the target playing state unless changed during the seek process
1458
- // In the future, we should allow for seeking in background. Currently, there's no
1459
- // way to know when the web application will call moveToForeground (i.e Before/After seek)
1460
- // Therefore, for now, we will assume the target is either paused or playing in ui unless
1461
- // specifically receiving a moveToBackground during the process.
1462
- // if (this._isPlaying && (lifecycle.state === lifecycle.UiState.BACKGROUND || lifecycle.state === lifecycle.UiState.IN_TRANSITION_TO_BACKGROUND)) {
1463
- // this._targetSeekPlayingState = TargetPlayingState.PLAYING_ABR;
1464
- // }
1465
- this._targetSeekPlayingState = this._isPlaying ? TargetPlayingState.PLAYING_UI : TargetPlayingState.PAUSED;
1457
+ if (this._isPlaying) {
1458
+ if (!lifecycle._inTransitionToForeground && (lifecycle._inTransitionToBackground || lifecycle.state === lifecycle.UiState.BACKGROUND || lifecycle.state === lifecycle.UiState.IN_TRANSITION_TO_BACKGROUND)) {
1459
+ this._targetSeekPlayingState = TargetPlayingState.PLAYING_ABR;
1460
+ } else {
1461
+ this._targetSeekPlayingState = TargetPlayingState.PLAYING_UI;
1462
+ }
1463
+ } else {
1464
+ this._targetSeekPlayingState = TargetPlayingState.PAUSED;
1465
+ }
1466
1466
 
1467
1467
  // The platform could be currently syncing audio/video using playback rate. Reset when performing seek.
1468
1468
  if (this._videoElement) {
@@ -1529,11 +1529,13 @@ class RemotePlayer extends EventTarget {
1529
1529
 
1530
1530
  // If in TargetPlayingState.PAUSE, no need to resume.
1531
1531
  // Resume without awaiting to avoid blocking the seek process anymore
1532
- // In case where we aborted, we don't want to resume playback.
1532
+ // In case where we aborted (new load or unload called), we don't want to resume playback.
1533
1533
  if (!this._abortSeeking) {
1534
1534
  if (this._targetSeekPlayingState === TargetPlayingState.PLAYING_UI) {
1535
1535
  this._play();
1536
1536
  } else if (this._targetSeekPlayingState === TargetPlayingState.PLAYING_ABR) {
1537
+ // When moving back to background, we need to put the remote player back into play mode
1538
+ this._changePlayMode(true);
1537
1539
  lifecycle._moveToBackground();
1538
1540
  }
1539
1541
  }