senza-sdk 4.2.51-60558b6.0 → 4.2.51-77d7fb8.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 +1 -1
- package/src/remotePlayer.js +118 -93
- package/src/utils.js +2 -4
package/package.json
CHANGED
package/src/remotePlayer.js
CHANGED
|
@@ -695,7 +695,7 @@ class RemotePlayer extends EventTarget {
|
|
|
695
695
|
return Promise.resolve(undefined);
|
|
696
696
|
}
|
|
697
697
|
|
|
698
|
-
_play() {
|
|
698
|
+
_play(streamType = StreamType.AUDIO) {
|
|
699
699
|
if (window.cefQuery) {
|
|
700
700
|
const FCID = getFCID();
|
|
701
701
|
const logger = sdkLogger.withFields({ FCID });
|
|
@@ -719,7 +719,7 @@ class RemotePlayer extends EventTarget {
|
|
|
719
719
|
if (this._remotePlayerApiVersion >= 2) {
|
|
720
720
|
if (this._isAudioSyncEnabled()) {
|
|
721
721
|
message.switchMode = SwitchMode.SEAMLESS;
|
|
722
|
-
message.streamType =
|
|
722
|
+
message.streamType = streamType;
|
|
723
723
|
waitForResponse = true;
|
|
724
724
|
} else {
|
|
725
725
|
logger.log("remotePlayer play request ignored and will be sent with the lifecycle.moveToBackground()");
|
|
@@ -817,6 +817,52 @@ class RemotePlayer extends EventTarget {
|
|
|
817
817
|
return Promise.resolve(undefined);
|
|
818
818
|
}
|
|
819
819
|
|
|
820
|
+
_stop(streamType = StreamType.AUDIO) {
|
|
821
|
+
if (window.cefQuery) {
|
|
822
|
+
this._changePlayMode(false);
|
|
823
|
+
const FCID = getFCID();
|
|
824
|
+
const logger = sdkLogger.withFields({ FCID });
|
|
825
|
+
logger.log(`remotePlayer stop: sending stop action for streamType ${streamType}`);
|
|
826
|
+
const message = {
|
|
827
|
+
type: "remotePlayer.stop",
|
|
828
|
+
class: "remotePlayer",
|
|
829
|
+
action: "stop",
|
|
830
|
+
streamType: streamType,
|
|
831
|
+
fcid: FCID
|
|
832
|
+
};
|
|
833
|
+
const request = { target: "TC", waitForResponse: true, message: JSON.stringify(message) };
|
|
834
|
+
return new Promise((resolve, reject) => {
|
|
835
|
+
let timerId = 0;
|
|
836
|
+
const timeBeforeSendingRequest = Date.now();
|
|
837
|
+
const queryId = window.cefQuery({
|
|
838
|
+
request: JSON.stringify(request),
|
|
839
|
+
persistent: false,
|
|
840
|
+
onSuccess: () => {
|
|
841
|
+
const duration = Date.now() - timeBeforeSendingRequest;
|
|
842
|
+
logger.withFields({ duration }).log(`stop completed successfully after ${duration} ms`);
|
|
843
|
+
timerId = clearTimer(timerId);
|
|
844
|
+
resolve();
|
|
845
|
+
},
|
|
846
|
+
onFailure: (code, msg) => {
|
|
847
|
+
const duration = Date.now() - timeBeforeSendingRequest;
|
|
848
|
+
logger.withFields({ duration }).log(`stop failed after ${duration} ms. Error code: ${code}, error message: ${msg}`);
|
|
849
|
+
timerId = clearTimer(timerId);
|
|
850
|
+
reject(new RemotePlayerError(code, msg));
|
|
851
|
+
}
|
|
852
|
+
});
|
|
853
|
+
logger.log(`window.cefQuery for stop returned query id ${queryId}`);
|
|
854
|
+
const timeout = this._remotePlayerConfirmationTimeout + 1000;
|
|
855
|
+
timerId = setTimeout(() => {
|
|
856
|
+
logger.log(`stop reached timeout of ${timeout} ms, canceling query id ${queryId}`);
|
|
857
|
+
window.cefQueryCancel(queryId);
|
|
858
|
+
reject(new RemotePlayerError(6000, `stop reached timeout of ${timeout} ms`));
|
|
859
|
+
}, timeout, queryId);
|
|
860
|
+
});
|
|
861
|
+
}
|
|
862
|
+
sdkLogger.error("remotePlayer play: window.cefQuery is undefined");
|
|
863
|
+
return Promise.resolve(undefined);
|
|
864
|
+
}
|
|
865
|
+
|
|
820
866
|
/** In order to support a seamless switch between the video in the UI and ABR, the web application must
|
|
821
867
|
* register the video element being used for the currently played video before calling the load and play apis.
|
|
822
868
|
* @param {object} video The video element currently playing video in the web application
|
|
@@ -1235,8 +1281,7 @@ class RemotePlayer extends EventTarget {
|
|
|
1235
1281
|
case 2:
|
|
1236
1282
|
return this._selectAudioTrackV2(audioTrackId, prevSelectedAudioTrack);
|
|
1237
1283
|
default:
|
|
1238
|
-
this.
|
|
1239
|
-
return this._atomicSetAudioLanguage();
|
|
1284
|
+
return this._atomicSetAudioLanguage(audioTrackId, prevSelectedAudioTrack);
|
|
1240
1285
|
}
|
|
1241
1286
|
}
|
|
1242
1287
|
|
|
@@ -1283,11 +1328,10 @@ class RemotePlayer extends EventTarget {
|
|
|
1283
1328
|
* Available only from v3 and on
|
|
1284
1329
|
*
|
|
1285
1330
|
* @param {string} audioTrackId - The ID of the audio track to select.
|
|
1286
|
-
* @param {string} prevSelectedAudioTrack - The previously selected audio track ID.
|
|
1287
1331
|
* @returns {Promise<void>} Resolves when the operation is complete.
|
|
1288
1332
|
* */
|
|
1289
|
-
async _selectAudioTrackV3(audioTrackId
|
|
1290
|
-
sdkLogger.log(`remotePlayer _selectAudioTrackV3:
|
|
1333
|
+
async _selectAudioTrackV3(audioTrackId) {
|
|
1334
|
+
sdkLogger.log(`remotePlayer _selectAudioTrackV3: audioTrackId=${audioTrackId} isPlaying=${this._isPlaying}`);
|
|
1291
1335
|
if (window.cefQuery) {
|
|
1292
1336
|
const FCID = getFCID();
|
|
1293
1337
|
const logger = sdkLogger.withFields({ FCID });
|
|
@@ -1373,8 +1417,7 @@ class RemotePlayer extends EventTarget {
|
|
|
1373
1417
|
case 2:
|
|
1374
1418
|
return this._selectTextTrackV2(textTrackId, prevSelectedTextTrack);
|
|
1375
1419
|
default:
|
|
1376
|
-
this.
|
|
1377
|
-
return this._atomicSetSubtitleLanguage();
|
|
1420
|
+
return this._atomicSetSubtitleLanguage(textTrackId, prevSelectedTextTrack);
|
|
1378
1421
|
}
|
|
1379
1422
|
}
|
|
1380
1423
|
|
|
@@ -1421,11 +1464,9 @@ class RemotePlayer extends EventTarget {
|
|
|
1421
1464
|
* Available only from v3 and on
|
|
1422
1465
|
*
|
|
1423
1466
|
* @param {string} textTrackId - The ID of the text track to select.
|
|
1424
|
-
* @param {string} prevSelectedTextTrack - The previously selected text track ID.
|
|
1425
1467
|
* @returns {Promise<void>} Resolves when the operation is complete.
|
|
1426
1468
|
* */
|
|
1427
|
-
async _selectTextTrackV3(textTrackId
|
|
1428
|
-
sdkLogger.log(`remotePlayer _selectTextTrackV3: prevAudioTrack=${prevSelectedTextTrack} textTrackId=${textTrackId} isPlaying=${this._isPlaying}`);
|
|
1469
|
+
async _selectTextTrackV3(textTrackId) {
|
|
1429
1470
|
if (window.cefQuery) {
|
|
1430
1471
|
const FCID = getFCID();
|
|
1431
1472
|
const logger = sdkLogger.withFields({ FCID });
|
|
@@ -1435,7 +1476,7 @@ class RemotePlayer extends EventTarget {
|
|
|
1435
1476
|
class: "remotePlayer",
|
|
1436
1477
|
action: "setSubtitleLanguage",
|
|
1437
1478
|
fcid: FCID,
|
|
1438
|
-
language: textTrackId
|
|
1479
|
+
language: textTrackId
|
|
1439
1480
|
};
|
|
1440
1481
|
const request = { target: "TC", waitForResponse: true, message: JSON.stringify(message) };
|
|
1441
1482
|
return new Promise((resolve, reject) => {
|
|
@@ -1701,117 +1742,101 @@ class RemotePlayer extends EventTarget {
|
|
|
1701
1742
|
sdkLogger.info("Seeking: local video element seeking end");
|
|
1702
1743
|
}
|
|
1703
1744
|
|
|
1704
|
-
async
|
|
1705
|
-
|
|
1745
|
+
async _atomicSetAudioLanguage(audioTrackId, prevSelectedAudioTrack) {
|
|
1746
|
+
this._targetSetAudioPlayingState = this._isPlaying ? TargetPlayingState.PLAYING_UI : TargetPlayingState.PAUSED;
|
|
1706
1747
|
|
|
1707
|
-
|
|
1708
|
-
this._abortSetSubtitleLanguage = false;
|
|
1709
|
-
this._isSetSubtitleByApplication = true;
|
|
1748
|
+
sdkLogger.log(`remotePlayer _atomicSetAudioLanguage: prevAudioTrack=${prevSelectedAudioTrack} audioTrackId=${audioTrackId} isPlaying=${this._isPlaying} targetState=${this._targetSetAudioPlayingState}`);
|
|
1710
1749
|
|
|
1711
|
-
|
|
1750
|
+
this._abortSetAudioLanguage = false;
|
|
1751
|
+
this._isSetAudioByApplication = true;
|
|
1712
1752
|
|
|
1713
|
-
let
|
|
1714
|
-
let initialSubtitleLanguage= this._pendingSubtitleLanguage;
|
|
1753
|
+
let state = SetAudioLanguageState.INIT;
|
|
1715
1754
|
let res;
|
|
1716
1755
|
|
|
1717
|
-
while (!this.
|
|
1756
|
+
while (!this._abortSetAudioLanguage && state !== SetAudioLanguageState.DONE) {
|
|
1718
1757
|
try {
|
|
1719
|
-
// TODO - Implement the logic for setting audio language
|
|
1720
1758
|
switch(state) {
|
|
1721
|
-
case
|
|
1722
|
-
|
|
1759
|
+
case SetAudioLanguageState.INIT:
|
|
1760
|
+
// always stop stream before changing language to flush current segments
|
|
1761
|
+
// because we cannot differentiate if player is paused/stopped
|
|
1762
|
+
state = SetAudioLanguageState.STOPPED;
|
|
1723
1763
|
break;
|
|
1724
|
-
case
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
sdkLogger.error("AFTER STOP BEFORE SET SUBTITLE");
|
|
1728
|
-
state = SetSubtitleLanguageState.SET;
|
|
1764
|
+
case SetAudioLanguageState.STOPPED:
|
|
1765
|
+
await this._stop(StreamType.AUDIO);
|
|
1766
|
+
state = SetAudioLanguageState.SET;
|
|
1729
1767
|
break;
|
|
1730
|
-
case
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
sdkLogger.
|
|
1735
|
-
|
|
1768
|
+
case SetAudioLanguageState.SET:
|
|
1769
|
+
res = await this._selectAudioTrackV3(audioTrackId);
|
|
1770
|
+
// check if we need to resume playback or leave player state as is
|
|
1771
|
+
state = this._targetSetAudioPlayingState !== TargetPlayingState.PAUSED ? SetAudioLanguageState.PLAYING: SetAudioLanguageState.DONE;
|
|
1772
|
+
sdkLogger.log(`remotePlayer _atomicSetAudioLanguage: audioTrackId=${audioTrackId} isPlaying=${this._isPlaying} targetState=${this._targetSetAudioPlayingState}`);
|
|
1773
|
+
break;
|
|
1774
|
+
case SetAudioLanguageState.PLAYING:
|
|
1775
|
+
if (!this._abortSetAudioLanguage) {
|
|
1776
|
+
await this._play(StreamType.AUDIO);
|
|
1777
|
+
}
|
|
1778
|
+
state = SetAudioLanguageState.DONE;
|
|
1736
1779
|
break;
|
|
1737
1780
|
}
|
|
1738
1781
|
} catch (error) {
|
|
1739
|
-
sdkLogger.error(`
|
|
1740
|
-
state =
|
|
1782
|
+
sdkLogger.error(`remotePlayer _atomicSetAudioLanguage: audioTrackId=${audioTrackId} failed with error ${error.message}.`);
|
|
1783
|
+
state = SetAudioLanguageState.DONE;
|
|
1741
1784
|
res = Promise.reject(error);
|
|
1742
|
-
} finally {
|
|
1743
|
-
sdkLogger.error("ABORT SET SUBTITLE", this._abortSetSubtitleLanguage);
|
|
1744
|
-
if (!this._abortSetSubtitleLanguage) {
|
|
1745
|
-
sdkLogger.error("TARGET PLAYING STATE", this._targetSetSubtitlePlayingState);
|
|
1746
|
-
if (this._targetSetSubtitlePlayingState === TargetPlayingState.PLAYING_UI) {
|
|
1747
|
-
sdkLogger.error("BEFORE PLAY AFTER SET SUBTITLE 2");
|
|
1748
|
-
this._play();
|
|
1749
|
-
} else if (this._targetSetSubtitlePlayingState === TargetPlayingState.PLAYING_ABR) {
|
|
1750
|
-
sdkLogger.error("BEFORE MOVE_TO_BACKGROUND AFTER SET SUBTITLE");
|
|
1751
|
-
lifecycle._moveToBackground();
|
|
1752
|
-
}
|
|
1753
|
-
}
|
|
1754
|
-
this._isSetSubtitleByApplication = false;
|
|
1755
|
-
sdkLogger.info("SetSubtitleLanguage: local video element set subtitle end");
|
|
1756
1785
|
}
|
|
1757
1786
|
}
|
|
1758
|
-
return res
|
|
1759
|
-
}
|
|
1760
1787
|
|
|
1761
|
-
|
|
1762
|
-
sdkLogger.
|
|
1788
|
+
this._isSetAudioByApplication = false;
|
|
1789
|
+
sdkLogger.log(`remotePlayer _atomicSetAudioLanguage: audioTrackId=${audioTrackId} ended.`);
|
|
1790
|
+
return res;
|
|
1791
|
+
}
|
|
1763
1792
|
|
|
1764
|
-
|
|
1765
|
-
this.
|
|
1766
|
-
this.
|
|
1793
|
+
async _atomicSetSubtitleLanguage(textTrackId, prevSelectedTextTrack) {
|
|
1794
|
+
this._targetSetSubtitlePlayingState = this._isPlaying ? TargetPlayingState.PLAYING_UI : TargetPlayingState.PAUSED;
|
|
1795
|
+
sdkLogger.log(`remotePlayer _atomicSetSubtitleLanguage: prevTextTrack=${prevSelectedTextTrack} textTrackId=${textTrackId} isPlaying=${this._isPlaying} targetState=${this._targetSetSubtitlePlayingState}`);
|
|
1767
1796
|
|
|
1768
|
-
|
|
1797
|
+
this._abortSetSubtitleLanguage = false;
|
|
1798
|
+
this._isSetSubtitleByApplication = true;
|
|
1769
1799
|
|
|
1770
|
-
let
|
|
1771
|
-
let initialAudioLanguage= this._pendingAudioLanguage;
|
|
1800
|
+
let state = SetSubtitleLanguageState.INIT;
|
|
1772
1801
|
let res;
|
|
1773
|
-
|
|
1774
|
-
while (!this.
|
|
1802
|
+
|
|
1803
|
+
while (!this._abortSetSubtitleLanguage && state !== SetSubtitleLanguageState.DONE) {
|
|
1775
1804
|
try {
|
|
1776
|
-
// TODO - Implement the logic for setting audio language
|
|
1777
1805
|
switch(state) {
|
|
1778
|
-
case
|
|
1779
|
-
|
|
1806
|
+
case SetSubtitleLanguageState.INIT:
|
|
1807
|
+
// always stop stream before changing language to flush current segments
|
|
1808
|
+
// because we cannot differentiate if player is paused/stopped
|
|
1809
|
+
state = SetSubtitleLanguageState.STOPPED;
|
|
1780
1810
|
break;
|
|
1781
|
-
case
|
|
1782
|
-
await
|
|
1783
|
-
state =
|
|
1811
|
+
case SetSubtitleLanguageState.STOPPED:
|
|
1812
|
+
await this._stop(StreamType.SUBTITLE);
|
|
1813
|
+
state = SetSubtitleLanguageState.SET;
|
|
1784
1814
|
break;
|
|
1785
|
-
case
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
sdkLogger.
|
|
1790
|
-
|
|
1815
|
+
case SetSubtitleLanguageState.SET:
|
|
1816
|
+
res = await this._selectTextTrackV3(textTrackId);
|
|
1817
|
+
// check if we need to resume playback or leave player state as is
|
|
1818
|
+
state = this._targetSetSubtitlePlayingState !== TargetPlayingState.PAUSED ? SetSubtitleLanguageState.PLAYING: SetSubtitleLanguageState.DONE;
|
|
1819
|
+
sdkLogger.log(`remotePlayer _atomicSetSubtitleLanguage: textTrackId=${textTrackId} isPlaying=${this._isPlaying} targetState=${this._targetSetSubtitlePlayingState}`);
|
|
1820
|
+
break;
|
|
1821
|
+
case SetSubtitleLanguageState.PLAYING:
|
|
1822
|
+
if (!this._abortSetSubtitleLanguage) {
|
|
1823
|
+
await this._play(StreamType.SUBTITLE | StreamType.AUDIO);
|
|
1824
|
+
}
|
|
1825
|
+
state = SetSubtitleLanguageState.DONE;
|
|
1791
1826
|
break;
|
|
1792
1827
|
}
|
|
1793
1828
|
} catch (error) {
|
|
1794
|
-
sdkLogger.error(`
|
|
1795
|
-
state =
|
|
1829
|
+
sdkLogger.error(`remotePlayer _atomicSetSubtitleLanguage: textTrackId=${textTrackId} failed with error ${error.message}.`);
|
|
1830
|
+
state = SetSubtitleLanguageState.DONE;
|
|
1796
1831
|
res = Promise.reject(error);
|
|
1797
|
-
} finally {
|
|
1798
|
-
sdkLogger.error("ABORT SET AUDIO", this._abortSetAudioLanguage);
|
|
1799
|
-
if (!this._abortSetAudioLanguage) {
|
|
1800
|
-
sdkLogger.error("TARGET PLAYING STATE", this._targetSetAudioPlayingState);
|
|
1801
|
-
if (this._targetSetAudioPlayingState === TargetPlayingState.PLAYING_UI) {
|
|
1802
|
-
sdkLogger.error("BEFORE PLAY AFTER SET AUDIO 2");
|
|
1803
|
-
this._play();
|
|
1804
|
-
} else if (this._targetSetAudioPlayingState === TargetPlayingState.PLAYING_ABR) {
|
|
1805
|
-
sdkLogger.error("BEFORE MOVE_TO_BACKGROUND AFTER SET AUDIO");
|
|
1806
|
-
lifecycle._moveToBackground();
|
|
1807
|
-
}
|
|
1808
|
-
}
|
|
1809
|
-
this._isSetAudioByApplication = false;
|
|
1810
|
-
sdkLogger.info("SetAudioLanguage: local video element set audio end");
|
|
1811
1832
|
}
|
|
1812
1833
|
}
|
|
1813
|
-
|
|
1834
|
+
|
|
1835
|
+
this._isSetSubtitleByApplication = false;
|
|
1836
|
+
sdkLogger.log(`remotePlayer _atomicSetSubtitleLanguage: textTrackId=${textTrackId} ended.`);
|
|
1837
|
+
return res;
|
|
1814
1838
|
}
|
|
1839
|
+
|
|
1815
1840
|
}
|
|
1816
1841
|
/**
|
|
1817
1842
|
*
|
package/src/utils.js
CHANGED
|
@@ -159,8 +159,7 @@ export const SetAudioLanguageState = Object.freeze({
|
|
|
159
159
|
INIT: "init",
|
|
160
160
|
STOPPED: "stopped",
|
|
161
161
|
SET: "set",
|
|
162
|
-
|
|
163
|
-
WAITING: "waiting",
|
|
162
|
+
PLAYING: "playing",
|
|
164
163
|
DONE: "done"
|
|
165
164
|
});
|
|
166
165
|
|
|
@@ -168,8 +167,7 @@ export const SetSubtitleLanguageState = Object.freeze({
|
|
|
168
167
|
INIT: "init",
|
|
169
168
|
STOPPED: "stopped",
|
|
170
169
|
SET: "set",
|
|
171
|
-
|
|
172
|
-
WAITING: "waiting",
|
|
170
|
+
PLAYING: "playing",
|
|
173
171
|
DONE: "done"
|
|
174
172
|
});
|
|
175
173
|
|