senza-sdk 4.2.55-fb0c331.0 → 4.2.55

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.55-fb0c331.0",
3
+ "version": "4.2.55",
4
4
  "main": "./src/api.js",
5
5
  "description": "API for Senza application",
6
6
  "license": "MIT",
package/src/lifecycle.js CHANGED
@@ -710,24 +710,15 @@ class Lifecycle extends EventTarget {
710
710
  * Failure to process the moveToBackground command will result in the promise being rejected.
711
711
  */
712
712
  moveToBackground() {
713
- if (window.cefQuery) {
714
- if (this._inTransition || this._state === this.UiState.BACKGROUND || this._state === this.UiState.IN_TRANSITION_TO_BACKGROUND) {
715
- sdkLogger.warn(`lifecycle moveToBackground: No need to transition to background, state: ${this._state} transition: ${this._inTransition}`);
716
- return Promise.resolve(false);
717
- }
718
-
719
- if (remotePlayer._isSeekingByApplication) {
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
+ }
720
719
  remotePlayer._targetSeekPlayingState = TargetPlayingState.PLAYING_ABR;
721
720
  return Promise.resolve(true);
722
721
  }
723
- if (remotePlayer._isSetSubtitlesInProgress) {
724
- remotePlayer._targetSetSubtitlePlayingState = TargetPlayingState.PLAYING_ABR;
725
- return Promise.resolve(true);
726
- }
727
- if (remotePlayer._isSetAudioInProgress) {
728
- remotePlayer._targetSetAudioPlayingState = TargetPlayingState.PLAYING_ABR;
729
- return Promise.resolve(true);
730
- }
731
722
  }
732
723
  return this._moveToBackground();
733
724
  }
@@ -694,7 +694,7 @@ class RemotePlayer extends EventTarget {
694
694
  return Promise.resolve(undefined);
695
695
  }
696
696
 
697
- _play(streamType) {
697
+ _play() {
698
698
  if (window.cefQuery) {
699
699
  const FCID = getFCID();
700
700
  const logger = sdkLogger.withFields({ FCID });
@@ -714,10 +714,16 @@ class RemotePlayer extends EventTarget {
714
714
  playbackPosition: this.currentTime
715
715
  };
716
716
  let waitForResponse = false;
717
+ this._changePlayMode(true);
717
718
  if (this._remotePlayerApiVersion >= 2) {
718
- message.switchMode = this._isAudioSyncEnabled() ? SwitchMode.SEAMLESS : SwitchMode.NON_SEAMLESS;
719
- message.streamType = streamType;
720
- waitForResponse = true;
719
+ if (this._isAudioSyncEnabled()) {
720
+ message.switchMode = SwitchMode.SEAMLESS;
721
+ message.streamType = StreamType.AUDIO;
722
+ waitForResponse = true;
723
+ } else {
724
+ logger.log("remotePlayer play request ignored and will be sent with the lifecycle.moveToBackground()");
725
+ return Promise.resolve();
726
+ }
721
727
  }
722
728
  const request = { target: "TC", waitForResponse: waitForResponse, message: JSON.stringify(message) };
723
729
  return new Promise((resolve, reject) => {
@@ -756,6 +762,7 @@ class RemotePlayer extends EventTarget {
756
762
 
757
763
  _pause() {
758
764
  if (window.cefQuery) {
765
+ this._changePlayMode(false);
759
766
  const isForegroundState = lifecycle.state === lifecycle.UiState.FOREGROUND || lifecycle.state === lifecycle.UiState.IN_TRANSITION_TO_FOREGROUND;
760
767
  if (this._remotePlayerApiVersion >= 2 && !this._isAudioSyncEnabled() && isForegroundState) {
761
768
  sdkLogger.info("remotePlayer pause: application in foreground, remote player is not playing.");
@@ -809,51 +816,6 @@ class RemotePlayer extends EventTarget {
809
816
  return Promise.resolve(undefined);
810
817
  }
811
818
 
812
- _stop(streamType) {
813
- if (window.cefQuery) {
814
- const FCID = getFCID();
815
- const logger = sdkLogger.withFields({ FCID });
816
- logger.log(`remotePlayer stop: sending stop action for streamType ${streamType}`);
817
- const message = {
818
- type: "remotePlayer.stop",
819
- class: "remotePlayer",
820
- action: "stop",
821
- streamType: streamType,
822
- fcid: FCID
823
- };
824
- const request = { target: "TC", waitForResponse: true, message: JSON.stringify(message) };
825
- return new Promise((resolve, reject) => {
826
- let timerId = 0;
827
- const timeBeforeSendingRequest = Date.now();
828
- const queryId = window.cefQuery({
829
- request: JSON.stringify(request),
830
- persistent: false,
831
- onSuccess: () => {
832
- const duration = Date.now() - timeBeforeSendingRequest;
833
- logger.withFields({ duration }).log(`stop completed successfully after ${duration} ms`);
834
- timerId = clearTimer(timerId);
835
- resolve();
836
- },
837
- onFailure: (code, msg) => {
838
- const duration = Date.now() - timeBeforeSendingRequest;
839
- logger.withFields({ duration }).log(`stop failed after ${duration} ms. Error code: ${code}, error message: ${msg}`);
840
- timerId = clearTimer(timerId);
841
- reject(new RemotePlayerError(code, msg));
842
- }
843
- });
844
- logger.log(`window.cefQuery for stop returned query id ${queryId}`);
845
- const timeout = this._remotePlayerConfirmationTimeout + 1000;
846
- timerId = setTimeout(() => {
847
- logger.log(`stop reached timeout of ${timeout} ms, canceling query id ${queryId}`);
848
- window.cefQueryCancel(queryId);
849
- reject(new RemotePlayerError(6000, `stop reached timeout of ${timeout} ms`));
850
- }, timeout, queryId);
851
- });
852
- }
853
- sdkLogger.error("remotePlayer stop: window.cefQuery is undefined");
854
- return Promise.resolve(undefined);
855
- }
856
-
857
819
  /** In order to support a seamless switch between the video in the UI and ABR, the web application must
858
820
  * register the video element being used for the currently played video before calling the load and play apis.
859
821
  * @param {object} video The video element currently playing video in the web application
@@ -929,8 +891,6 @@ class RemotePlayer extends EventTarget {
929
891
  if (this._loadMode === this.LoadMode.LOADING || this._loadMode === this.LoadMode.UNLOADING) {
930
892
  throw new RemotePlayerError(6501, "Cannot call load() while previous load/unload is still in progress");
931
893
  }
932
- this._abortSetAudioLanguage = true;
933
- this._abortSetSubtitleLanguage = true;
934
894
  this._abortSeeking = true;
935
895
  if (reset) {
936
896
  this._reset();
@@ -1104,20 +1064,6 @@ class RemotePlayer extends EventTarget {
1104
1064
  }
1105
1065
  }
1106
1066
 
1107
- this._changePlayMode(true);
1108
-
1109
- if (this._isSetAudioInProgress) {
1110
- sdkLogger.info("application requesting play during setAudioLanguage");
1111
- this._targetSetAudioPlayingState = TargetPlayingState.PLAYING_UI;
1112
- return Promise.resolve(true);
1113
- }
1114
-
1115
- if (this._isSetSubtitlesInProgress) {
1116
- sdkLogger.info("application requesting play during setSubtitleLanguage");
1117
- this._targetSetSubtitlePlayingState = TargetPlayingState.PLAYING_UI;
1118
- return Promise.resolve(true);
1119
- }
1120
-
1121
1067
  // If seeking in progress, wait for seek to complete before playing
1122
1068
  if (this._isSeekingByApplication) {
1123
1069
  sdkLogger.info("application requesting play during seek");
@@ -1132,13 +1078,7 @@ class RemotePlayer extends EventTarget {
1132
1078
  this._seek(this._videoElement.currentTime, false);
1133
1079
  }
1134
1080
  }*/
1135
-
1136
- if (this._remotePlayerApiVersion >= 2 && !this._isAudioSyncEnabled()) {
1137
- sdkLogger.info("play was called but _isAudioSyncEnabled is disabled, ignoring.");
1138
- return Promise.resolve(true);
1139
- }
1140
-
1141
- return this._play(StreamType.AUDIO);
1081
+ return this._play();
1142
1082
  }
1143
1083
 
1144
1084
  /** Pauses the currently playing audio or video
@@ -1158,24 +1098,11 @@ class RemotePlayer extends EventTarget {
1158
1098
  throw new RemotePlayerError(6001, "Cannot call pause() if player is not loaded");
1159
1099
  }
1160
1100
  }
1161
-
1162
- this._changePlayMode(false);
1163
-
1164
1101
  if (this._isSeekingByApplication) {
1165
1102
  sdkLogger.info("application requesting pause during seek");
1166
1103
  this._targetSeekPlayingState = TargetPlayingState.PAUSED;
1167
1104
  return Promise.resolve(true);
1168
1105
  }
1169
- if (this._isSetAudioInProgress) {
1170
- sdkLogger.info("application requesting pause during setAudioLanguage");
1171
- this._targetSetAudioPlayingState = TargetPlayingState.PAUSED;
1172
- return Promise.resolve(true);
1173
- }
1174
- if (this._isSetSubtitlesInProgress) {
1175
- sdkLogger.info("application requesting pause during setSubtitleLanguage");
1176
- this._targetSetSubtitlePlayingState = TargetPlayingState.PAUSED;
1177
- return Promise.resolve(true);
1178
- }
1179
1106
  return this._pause();
1180
1107
  }
1181
1108
 
@@ -1263,6 +1190,7 @@ class RemotePlayer extends EventTarget {
1263
1190
  const prevSelectedAudioTrack = this._selectedAudioTrack;
1264
1191
  for (const track of this.getAudioTracks()) {
1265
1192
  if (track.id === audioTrackId) {
1193
+ this._selectedAudioTrack = audioTrackId;
1266
1194
  found = true;
1267
1195
  break;
1268
1196
  }
@@ -1271,33 +1199,19 @@ class RemotePlayer extends EventTarget {
1271
1199
  sdkLogger.warn(`Invalid audioTrackId ${audioTrackId}`);
1272
1200
  return Promise.resolve();
1273
1201
  }
1274
- if (this._selectedAudioTrack === audioTrackId) {
1202
+ if (this._remotePlayerApiVersion < 2) {
1203
+ return Promise.resolve(); // Resolve immediately for older versions
1204
+ }
1205
+ if (prevSelectedAudioTrack === this._selectedAudioTrack) {
1275
1206
  return Promise.resolve(); // Audio language already selected
1276
1207
  }
1277
1208
 
1278
- switch (this._remotePlayerApiVersion) {
1279
- case 0:
1280
- case 1:
1281
- this._selectedAudioTrack = audioTrackId;
1282
- return Promise.resolve(); // Resolve immediately for older versions
1283
- case 2:
1284
- return this._selectAudioTrackV2(audioTrackId, prevSelectedAudioTrack);
1285
- default:
1286
- return this._atomicSetAudioLanguage(audioTrackId, prevSelectedAudioTrack);
1287
- }
1209
+ return this._selectAudioTrack(audioTrackId, prevSelectedAudioTrack);
1288
1210
  }
1289
1211
 
1290
- /**
1291
- * Handles the asynchronous selection of an audio track.
1292
- * If the player is playing, it pauses before changing the track and resumes playback if necessary.
1293
- *
1294
- * @param {string} audioTrackId - The ID of the audio track to select.
1295
- * @param {string} prevSelectedAudioTrack - The previously selected audio track ID.
1296
- * @returns {Promise<void>} Resolves when the operation is complete.
1297
- * */
1298
- async _selectAudioTrackV2(audioTrackId, prevSelectedAudioTrack) {
1212
+ async _selectAudioTrack(audioTrackId, prevSelectedAudioTrack) {
1299
1213
  const prevIsPlaying = this._isPlaying;
1300
- sdkLogger.log(`remotePlayer _selectAudioTrackV2: prevAudioTrack=${prevSelectedAudioTrack} audioTrackId=${audioTrackId} isPlaying=${this._isPlaying}`);
1214
+ sdkLogger.log(`remotePlayer _selectAudioTrack: prevAudioTrack=${prevSelectedAudioTrack} audioTrackId=${audioTrackId} isPlaying=${this._isPlaying}`);
1301
1215
  try {
1302
1216
  if (this._isPlaying) await this.pause();
1303
1217
  let position = this.currentTime;
@@ -1305,9 +1219,9 @@ class RemotePlayer extends EventTarget {
1305
1219
  position = this._videoElement.currentTime;
1306
1220
  }
1307
1221
  await this._load(this._loadedUrl, position, audioTrackId, undefined, false);
1308
- this._selectedAudioTrack = audioTrackId;
1309
1222
  } catch (e) {
1310
- // Do NOT reject - just log
1223
+ // Do NOT reject - just log and revert selection
1224
+ this._selectedAudioTrack = prevSelectedAudioTrack;
1311
1225
  sdkLogger.warn(`Failed to select audio track ${audioTrackId}: ${e.message}`);
1312
1226
  return;
1313
1227
  }
@@ -1324,62 +1238,6 @@ class RemotePlayer extends EventTarget {
1324
1238
  }
1325
1239
  }
1326
1240
 
1327
- /**
1328
- * Handles the asynchronous selection of an audio track.
1329
- * If the player is playing, it stops audio streamType before changing the track and resumes audio streamType playback if necessary.
1330
- * Available only from v3 and on
1331
- *
1332
- * @param {string} audioTrackId - The ID of the audio track to select.
1333
- * @returns {Promise<void>} Resolves when the operation is complete.
1334
- * */
1335
- async _selectAudioTrackV3(audioTrackId) {
1336
- sdkLogger.log(`remotePlayer _selectAudioTrackV3: audioTrackId=${audioTrackId} isPlaying=${this._isPlaying}`);
1337
- if (window.cefQuery) {
1338
- const FCID = getFCID();
1339
- const logger = sdkLogger.withFields({ FCID });
1340
- logger.log("remotePlayer _selectAudioTrackV3: sending setAudioLanguage action");
1341
- const message = {
1342
- type: "remotePlayer.setAudioLanguage",
1343
- class: "remotePlayer",
1344
- action: "setAudioLanguage",
1345
- fcid: FCID,
1346
- language: audioTrackId
1347
- };
1348
- const request = { target: "TC", waitForResponse: true, message: JSON.stringify(message) };
1349
- return new Promise((resolve, reject) => {
1350
- let timerId = 0;
1351
- const timeBeforeSendingRequest = Date.now();
1352
- const queryId = window.cefQuery({
1353
- request: JSON.stringify(request),
1354
- persistent: false,
1355
- onSuccess: () => {
1356
- this._selectedAudioTrack = audioTrackId;
1357
- const duration = Date.now() - timeBeforeSendingRequest;
1358
- logger.withFields({ duration }).log(`setAudioLanguage completed successfully after ${duration} ms`);
1359
- timerId = clearTimer(timerId);
1360
- resolve();
1361
- },
1362
- onFailure: (code, msg) => {
1363
- const duration = Date.now() - timeBeforeSendingRequest;
1364
- logger.withFields({ duration }).log(`setAudioLanguage failed after ${duration} ms. Error code: ${code}, error message: ${msg}`);
1365
- timerId = clearTimer(timerId);
1366
- reject(new RemotePlayerError(code, msg));
1367
- }
1368
- });
1369
- logger.log(`window.cefQuery for setAudioLanguage returned query id ${queryId}`);
1370
- const timeout = this._remotePlayerConfirmationTimeout + 1000;
1371
- timerId = setTimeout(() => {
1372
- logger.log(`setAudioLanguage reached timeout of ${timeout} ms, canceling query id ${queryId}`);
1373
- window.cefQueryCancel(queryId);
1374
- reject(new RemotePlayerError(6000, `setAudioLanguage reached timeout of ${timeout} ms`));
1375
- }, timeout, queryId);
1376
- });
1377
- }
1378
-
1379
- sdkLogger.error("remotePlayer _selectAudioTrackV3: window.cefQuery is undefined");
1380
- return Promise.resolve(undefined);
1381
- }
1382
-
1383
1241
  /** Select a specific text (subtitle) track.
1384
1242
  * Track id should come from a call to getTextTracks.
1385
1243
  * If no tracks exist - this is a no-op.
@@ -1399,6 +1257,7 @@ class RemotePlayer extends EventTarget {
1399
1257
  const prevSelectedTextTrack = this._selectedSubtitlesTrack;
1400
1258
  for (const track of this.getTextTracks()) {
1401
1259
  if (track.id === textTrackId) {
1260
+ this._selectedSubtitlesTrack = textTrackId;
1402
1261
  found = true;
1403
1262
  break;
1404
1263
  }
@@ -1407,20 +1266,14 @@ class RemotePlayer extends EventTarget {
1407
1266
  sdkLogger.warn(`Invalid textTrackId ${textTrackId}`);
1408
1267
  return Promise.resolve();
1409
1268
  }
1410
- if (this._selectedSubtitlesTrack === textTrackId) {
1269
+ if (this._remotePlayerApiVersion < 2) {
1270
+ return Promise.resolve(); // Resolve immediately for older versions
1271
+ }
1272
+ if (prevSelectedTextTrack === this._selectedSubtitlesTrack) {
1411
1273
  return Promise.resolve(); // Subtitle language already selected
1412
1274
  }
1413
1275
 
1414
- switch (this._remotePlayerApiVersion) {
1415
- case 0:
1416
- case 1:
1417
- this._selectedSubtitlesTrack = textTrackId;
1418
- return Promise.resolve(); // Resolve immediately for older versions
1419
- case 2:
1420
- return this._selectTextTrackV2(textTrackId, prevSelectedTextTrack);
1421
- default:
1422
- return this._atomicSetSubtitleLanguage(textTrackId, prevSelectedTextTrack);
1423
- }
1276
+ return this._selectTextTrack(textTrackId, prevSelectedTextTrack);
1424
1277
  }
1425
1278
 
1426
1279
  /**
@@ -1431,9 +1284,9 @@ class RemotePlayer extends EventTarget {
1431
1284
  * @param {string} prevSelectedTextTrack - The previously selected text track ID.
1432
1285
  * @returns {Promise<void>} Resolves when the operation is complete.
1433
1286
  * */
1434
- async _selectTextTrackV2(textTrackId, prevSelectedTextTrack) {
1287
+ async _selectTextTrack(textTrackId, prevSelectedTextTrack) {
1435
1288
  const prevIsPlaying = this._isPlaying;
1436
- sdkLogger.log(`remotePlayer _selectTextTrackV2: prevTextTrack=${prevSelectedTextTrack} textTrackId=${textTrackId} isPlaying=${this._isPlaying}`);
1289
+ sdkLogger.log(`remotePlayer _selectTextTrack: prevTextTrack=${prevSelectedTextTrack} textTrackId=${textTrackId} isPlaying=${this._isPlaying}`);
1437
1290
  try {
1438
1291
  if (this._isPlaying) await this.pause();
1439
1292
  let position = this.currentTime;
@@ -1441,9 +1294,9 @@ class RemotePlayer extends EventTarget {
1441
1294
  position = this._videoElement.currentTime;
1442
1295
  }
1443
1296
  await this._load(this._loadedUrl, position, undefined, textTrackId, false);
1444
- this._selectedSubtitlesTrack = textTrackId;
1445
1297
  } catch (e) {
1446
- // Do NOT reject - just log
1298
+ // Do NOT reject - just log and revert selection
1299
+ this._selectedSubtitlesTrack = prevSelectedTextTrack;
1447
1300
  sdkLogger.warn(`Failed to select text track ${textTrackId}: ${e.message}`);
1448
1301
  return;
1449
1302
  }
@@ -1460,60 +1313,6 @@ class RemotePlayer extends EventTarget {
1460
1313
  }
1461
1314
  }
1462
1315
 
1463
- /**
1464
- * Handles the asynchronous selection of a text track.
1465
- * If the player is playing, it stops subtitle streamType before changing the track and resumes subtitle streamType playback if necessary.
1466
- * Available only from v3 and on
1467
- *
1468
- * @param {string} textTrackId - The ID of the text track to select.
1469
- * @returns {Promise<void>} Resolves when the operation is complete.
1470
- * */
1471
- async _selectTextTrackV3(textTrackId) {
1472
- if (window.cefQuery) {
1473
- const FCID = getFCID();
1474
- const logger = sdkLogger.withFields({ FCID });
1475
- logger.log("remotePlayer _selectTextTrackV3: sending setSubtitleLanguage action");
1476
- const message = {
1477
- type: "remotePlayer.setSubtitleLanguage",
1478
- class: "remotePlayer",
1479
- action: "setSubtitleLanguage",
1480
- fcid: FCID,
1481
- language: textTrackId
1482
- };
1483
- const request = { target: "TC", waitForResponse: true, message: JSON.stringify(message) };
1484
- return new Promise((resolve, reject) => {
1485
- let timerId = 0;
1486
- const timeBeforeSendingRequest = Date.now();
1487
- const queryId = window.cefQuery({
1488
- request: JSON.stringify(request),
1489
- persistent: false,
1490
- onSuccess: () => {
1491
- this._selectedSubtitlesTrack = textTrackId;
1492
- const duration = Date.now() - timeBeforeSendingRequest;
1493
- logger.withFields({ duration }).log(`setSubtitleLanguage completed successfully after ${duration} ms`);
1494
- timerId = clearTimer(timerId);
1495
- resolve();
1496
- },
1497
- onFailure: (code, msg) => {
1498
- const duration = Date.now() - timeBeforeSendingRequest;
1499
- logger.withFields({ duration }).log(`setSubtitleLanguage failed after ${duration} ms. Error code: ${code}, error message: ${msg}`);
1500
- timerId = clearTimer(timerId);
1501
- reject(new RemotePlayerError(code, msg));
1502
- }
1503
- });
1504
- logger.log(`window.cefQuery for setSubtitleLanguage returned query id ${queryId}`);
1505
- const timeout = this._remotePlayerConfirmationTimeout + 1000;
1506
- timerId = setTimeout(() => {
1507
- logger.log(`setSubtitleLanguage reached timeout of ${timeout} ms, canceling query id ${queryId}`);
1508
- window.cefQueryCancel(queryId);
1509
- reject(new RemotePlayerError(6000, `setSubtitleLanguage reached timeout of ${timeout} ms`));
1510
- }, timeout, queryId);
1511
- });
1512
- }
1513
- sdkLogger.error("remotePlayer _selectTextTrackV3: window.cefQuery is undefined");
1514
- return Promise.resolve(undefined);
1515
- }
1516
-
1517
1316
  /**
1518
1317
  * Enable or disable the subtitles.
1519
1318
  * If the player is in an unloaded state, the request will be applied next time content is played.
@@ -1624,11 +1423,6 @@ class RemotePlayer extends EventTarget {
1624
1423
  * @private
1625
1424
  */
1626
1425
  async _startSeeking(playbackPosition) {
1627
- if (this._isSetAudioInProgress || this._isSetSubtitlesInProgress) {
1628
- sdkLogger.info("Seeking not supported while setAudioLanguage or setSubtitleLanguage are in progress.");
1629
- return;
1630
- }
1631
-
1632
1426
  if (!this._isSeekingByPlatform) {
1633
1427
  this._pendingSeekPosition = playbackPosition;
1634
1428
 
@@ -1740,11 +1534,7 @@ class RemotePlayer extends EventTarget {
1740
1534
  // In case where we aborted, we don't want to resume playback.
1741
1535
  if (!this._abortSeeking) {
1742
1536
  if (this._targetSeekPlayingState === TargetPlayingState.PLAYING_UI) {
1743
- if (!this._isAudioSyncEnabled()) {
1744
- return Promise.resolve(true);
1745
- }
1746
- // resume audio play only if _isAudioSyncEnabled
1747
- this._play(StreamType.AUDIO);
1537
+ this._play();
1748
1538
  } else if (this._targetSeekPlayingState === TargetPlayingState.PLAYING_ABR) {
1749
1539
  lifecycle._moveToBackground();
1750
1540
  }
@@ -1753,144 +1543,6 @@ class RemotePlayer extends EventTarget {
1753
1543
  this._isSeekingByApplication = false;
1754
1544
  sdkLogger.info("Seeking: local video element seeking end");
1755
1545
  }
1756
-
1757
- async _atomicSetAudioLanguage(audioTrackId, prevSelectedAudioTrack) {
1758
- if (this._isSetAudioInProgress) {
1759
- sdkLogger.warn(`remotePlayer _atomicSetAudioLanguage: audioTrackId=${audioTrackId} already in progress, ignoring.`);
1760
- return Promise.resolve();
1761
- }
1762
- if (this._isSeekingByApplication) {
1763
- sdkLogger.warn(`remotePlayer _atomicSetAudioLanguage: audioTrackId=${audioTrackId} ignored. seeking is already in progress.`);
1764
- return Promise.resolve();
1765
- }
1766
-
1767
- this._targetSetAudioPlayingState = this._isPlaying ? TargetPlayingState.PLAYING_UI : TargetPlayingState.PAUSED;
1768
- sdkLogger.log(`remotePlayer _atomicSetAudioLanguage: prevAudioTrack=${prevSelectedAudioTrack} audioTrackId=${audioTrackId} isPlaying=${this._isPlaying} targetState=${this._targetSetAudioPlayingState}`);
1769
-
1770
- this._abortSetAudioLanguage = false;
1771
- this._isSetAudioInProgress = true;
1772
-
1773
- let setLanguageError;
1774
- try {
1775
- await this._stop(StreamType.AUDIO);
1776
- } catch (error) {
1777
- sdkLogger.warn(`remotePlayer _atomicSetAudioLanguage: audioTrackId=${audioTrackId} failed on stop with error ${error.message}.`);
1778
- if (!this._abortSetAudioLanguage) {
1779
- setLanguageError = error;
1780
- }
1781
- }
1782
-
1783
- // check if load/unload were called
1784
- if (this._abortSetAudioLanguage) {
1785
- this._isSetAudioInProgress = false;
1786
- sdkLogger.warn(`remotePlayer _atomicSetAudioLanguage: audioTrackId=${audioTrackId} aborted right after stop.`);
1787
- return Promise.resolve();
1788
- }
1789
-
1790
- try {
1791
- await this._selectAudioTrackV3(audioTrackId);
1792
- } catch (error) {
1793
- sdkLogger.error(`remotePlayer _atomicSetAudioLanguage: audioTrackId=${audioTrackId} _selectAudioTrackV3 failed with error ${error.message}.`);
1794
- if (!this._abortSetAudioLanguage) {
1795
- setLanguageError = error;
1796
- }
1797
- }
1798
-
1799
- // check if load/unload were called
1800
- if (this._abortSetAudioLanguage) {
1801
- this._isSetAudioInProgress = false;
1802
- sdkLogger.warn(`remotePlayer _atomicSetAudioLanguage: audioTrackId=${audioTrackId} aborted right after _selectAudioTrackV3.`);
1803
- return Promise.resolve();
1804
- }
1805
-
1806
- try {
1807
- if (this._targetSetAudioPlayingState === TargetPlayingState.PLAYING_UI) {
1808
- if (!this._isAudioSyncEnabled()) {
1809
- this._isSetAudioInProgress = false;
1810
- return Promise.resolve(true);
1811
- }
1812
- // resume audio play only if _isAudioSyncEnabled
1813
- await this._play(StreamType.AUDIO);
1814
- } else if (this._targetSetAudioPlayingState === TargetPlayingState.PLAYING_ABR) {
1815
- await lifecycle._moveToBackground();
1816
- }
1817
- } catch (error) {
1818
- sdkLogger.error(`remotePlayer _atomicSetAudioLanguage: audioTrackId=${audioTrackId} play failed with error ${error.message}.`);
1819
- }
1820
-
1821
- this._isSetAudioInProgress = false;
1822
- sdkLogger.log(`remotePlayer _atomicSetAudioLanguage: audioTrackId=${audioTrackId} ended.`);
1823
- return setLanguageError ? Promise.reject(setLanguageError) : Promise.resolve();
1824
- }
1825
-
1826
- async _atomicSetSubtitleLanguage(textTrackId, prevSelectedTextTrack) {
1827
- if (this._isSetSubtitlesInProgress) {
1828
- sdkLogger.warn(`remotePlayer _atomicSetSubtitleLanguage: textTrackId=${textTrackId} already in progress, ignoring.`);
1829
- return Promise.resolve();
1830
- }
1831
- if (this._isSeekingByApplication) {
1832
- sdkLogger.warn(`remotePlayer _atomicSetSubtitleLanguage: textTrackId=${textTrackId} ignored. seeking is already in progress.`);
1833
- return Promise.resolve();
1834
- }
1835
-
1836
- this._targetSetSubtitlePlayingState = this._isPlaying ? TargetPlayingState.PLAYING_UI : TargetPlayingState.PAUSED;
1837
- sdkLogger.log(`remotePlayer _atomicSetSubtitleLanguage: prevTextTrack=${prevSelectedTextTrack} textTrackId=${textTrackId} isPlaying=${this._isPlaying} targetState=${this._targetSetSubtitlePlayingState}`);
1838
-
1839
- this._abortSetSubtitleLanguage = false;
1840
- this._isSetSubtitlesInProgress = true;
1841
-
1842
- let setLanguageError;
1843
- try {
1844
- await this._stop(StreamType.SUBTITLE);
1845
- } catch (error) {
1846
- sdkLogger.warn(`remotePlayer _atomicSetSubtitleLanguage: textTrackId=${textTrackId} stop failed with error ${error.message}.`);
1847
- if (!this._abortSetSubtitleLanguage) {
1848
- setLanguageError = error;
1849
- }
1850
- }
1851
-
1852
- // check if load/unload were called
1853
- if (this._abortSetSubtitleLanguage) {
1854
- this._isSetSubtitlesInProgress = false;
1855
- sdkLogger.warn(`remotePlayer _atomicSetSubtitleLanguage: textTrackId=${textTrackId} aborted right after stop.`);
1856
- return Promise.resolve();
1857
- }
1858
-
1859
- try {
1860
- await this._selectTextTrackV3(textTrackId);
1861
- } catch (error) {
1862
- sdkLogger.error(`remotePlayer _atomicSetSubtitleLanguage: textTrackId=${textTrackId} _selectTextTrackV3 failed with error ${error.message}.`);
1863
- if (!this._abortSetSubtitleLanguage) {
1864
- setLanguageError = error;
1865
- }
1866
- }
1867
-
1868
- // check if load/unload were called
1869
- if (this._abortSetSubtitleLanguage) {
1870
- this._isSetSubtitlesInProgress = false;
1871
- sdkLogger.warn(`remotePlayer _atomicSetSubtitleLanguage: textTrackId=${textTrackId} aborted right after _selectTextTrackV3.`);
1872
- return Promise.resolve();
1873
- }
1874
-
1875
- try {
1876
- if (this._targetSetSubtitlePlayingState === TargetPlayingState.PLAYING_UI) {
1877
- if (!this._isAudioSyncEnabled()) {
1878
- this._isSetSubtitlesInProgress = false;
1879
- return Promise.resolve(true);
1880
- }
1881
- // resume audio play only if _isAudioSyncEnabled
1882
- await this._play(StreamType.AUDIO);
1883
- } else if (this._targetSetSubtitlePlayingState === TargetPlayingState.PLAYING_ABR) {
1884
- await lifecycle._moveToBackground();
1885
- }
1886
- } catch (error) {
1887
- sdkLogger.error(`remotePlayer _atomicSetSubtitleLanguage: textTrackId=${textTrackId} play failed with error ${error.message}.`);
1888
- }
1889
-
1890
- this._isSetSubtitlesInProgress = false;
1891
- sdkLogger.log(`remotePlayer _atomicSetSubtitleLanguage: textTrackId=${textTrackId} ended.`);
1892
- return setLanguageError ? Promise.reject(setLanguageError) : Promise.resolve();
1893
- }
1894
1546
  }
1895
1547
  /**
1896
1548
  *