senza-sdk 4.2.51-9f586bc.0 → 4.2.51

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.51-9f586bc.0",
3
+ "version": "4.2.51",
4
4
  "main": "./src/api.js",
5
5
  "description": "API for Senza application",
6
6
  "license": "MIT",
package/src/lifecycle.js CHANGED
@@ -87,7 +87,7 @@ class Lifecycle extends EventTarget {
87
87
  /**
88
88
  * @event Lifecycle#userdisconnected
89
89
  * @description Fired when the user session ends .
90
- * This event is useful for cleaning up application state or saving data before the application closes.
90
+ * This event is useful for cleaning up application state or saving data before the application closes. Event callback should return promise to ensure that the event is handled before the application is terminated
91
91
  * @example
92
92
  * lifecycle.addEventListener("userdisconnected", () => {
93
93
  * console.log("User session ended, cleaning up application state");
@@ -410,12 +410,12 @@ class Lifecycle extends EventTarget {
410
410
  }
411
411
 
412
412
  /**
413
- * Controls the autoBackground feature<br>
413
+ * @deprecated Use `lifecycle.configure()` instead.
414
+ * Controls the autoBackground feature.<br>
414
415
  * When enabled, the application will automatically move to the background state after a configurable
415
- * period of inactivity. The delay depends on whether video is playing ({@link Lifecycle#autoBackgroundDelay})
416
- * or the UI is idle ({@link Lifecycle#autoBackgroundOnUIDelay}).
417
- * The application will return to the foreground state when a key is pressed.
416
+ * period of inactivity. Use the `configure` method to set timeouts for video playback and UI states.
418
417
  * @type {boolean}
418
+ * @see {@link Lifecycle#configure}
419
419
  */
420
420
  set autoBackground(enabled) {
421
421
  this._autoBackground = enabled;
@@ -431,10 +431,12 @@ class Lifecycle extends EventTarget {
431
431
  }
432
432
 
433
433
  /**
434
+ * @deprecated Use `lifecycle.configure()` instead.
434
435
  * The number of seconds of user inactivity before the application moves to the background state while playing video.
435
- * This setting is used when remotePlayer is in playing state.
436
+ * Use the `configure` method to set this timeout.
436
437
  * @type {integer}
437
438
  * @default 30
439
+ * @see {@link Lifecycle#configure}
438
440
  */
439
441
  set autoBackgroundDelay(delay) {
440
442
  this._autoBackgroundOnVideoDelay = delay;
@@ -444,12 +446,18 @@ class Lifecycle extends EventTarget {
444
446
  }
445
447
  }
446
448
 
449
+ get autoBackgroundDelay() {
450
+ return this._autoBackgroundOnVideoDelay;
451
+ }
452
+
447
453
  /**
448
- * The number of seconds of user inactivity before the application moves to the background state while in the UI (not playing).
449
- * This setting is used when remotePlayer is not in playing state.
450
- * @type {integer}
451
- * @default 30
452
- */
454
+ * @deprecated Use `lifecycle.configure()` instead.
455
+ * The number of seconds of user inactivity before the application moves to the background state while in the UI (not playing).
456
+ * Use the `configure` method to set this timeout.
457
+ * @type {integer}
458
+ * @default -1
459
+ * @see {@link Lifecycle#configure}
460
+ */
453
461
  set autoBackgroundOnUIDelay(delay) {
454
462
  this._autoBackgroundOnUIDelay = delay;
455
463
 
@@ -458,13 +466,10 @@ class Lifecycle extends EventTarget {
458
466
  }
459
467
  }
460
468
 
461
- get autoBackgroundDelay() {
462
- return this._autoBackgroundOnVideoDelay;
463
- }
464
-
465
469
  get autoBackgroundOnUIDelay() {
466
470
  return this._autoBackgroundOnUIDelay;
467
471
  }
472
+
468
473
  /**
469
474
  * @private
470
475
  */
@@ -824,9 +829,9 @@ class Lifecycle extends EventTarget {
824
829
  }
825
830
 
826
831
  /**
827
- * Override addEventListener to handle "userdisconnected" event specially
832
+ * Add event listener for lifecycle events
828
833
  * @param {string} type - The event type to listen for
829
- * @param {Function} listener - The callback function
834
+ * @param {Function} listener - The callback function. Listeners for 'userdisconnected' events should return a promise to ensure the event is processed before the application exits.
830
835
  * @param {Object} options - Event listener options
831
836
  */
832
837
  addEventListener(type, listener, options) {
@@ -840,7 +845,7 @@ class Lifecycle extends EventTarget {
840
845
  }
841
846
 
842
847
  /**
843
- * Override removeEventListener to handle "userdisconnected" event specially
848
+ * Remove event listener
844
849
  * @param {string} type - The event type
845
850
  * @param {Function} listener - The callback function to remove
846
851
  * @param {Object} options - Event listener options
@@ -9,9 +9,7 @@ import {
9
9
  SeekState,
10
10
  TargetPlayingState,
11
11
  isSubtitlesTranslationAllowed,
12
- isSubtitlesTranslationPattern,
13
- SetAudioLanguageState,
14
- SetSubtitleLanguageState
12
+ isSubtitlesTranslationPattern
15
13
  } from "./utils";
16
14
  import { lifecycle } from "./lifecycle";
17
15
  import { writeLicenseResponse } from "./api";
@@ -892,8 +890,6 @@ class RemotePlayer extends EventTarget {
892
890
  if (this._loadMode === this.LoadMode.LOADING || this._loadMode === this.LoadMode.UNLOADING) {
893
891
  throw new RemotePlayerError(6501, "Cannot call load() while previous load/unload is still in progress");
894
892
  }
895
- this._abortSetAudioLanguage = true;
896
- this._abortSetSubtitleLanguage = true;
897
893
  this._abortSeeking = true;
898
894
  if (reset) {
899
895
  this._reset();
@@ -1193,6 +1189,7 @@ class RemotePlayer extends EventTarget {
1193
1189
  const prevSelectedAudioTrack = this._selectedAudioTrack;
1194
1190
  for (const track of this.getAudioTracks()) {
1195
1191
  if (track.id === audioTrackId) {
1192
+ this._selectedAudioTrack = audioTrackId;
1196
1193
  found = true;
1197
1194
  break;
1198
1195
  }
@@ -1201,34 +1198,19 @@ class RemotePlayer extends EventTarget {
1201
1198
  sdkLogger.warn(`Invalid audioTrackId ${audioTrackId}`);
1202
1199
  return Promise.resolve();
1203
1200
  }
1204
- if (this._selectedAudioTrack === audioTrackId) {
1201
+ if (this._remotePlayerApiVersion < 2) {
1202
+ return Promise.resolve(); // Resolve immediately for older versions
1203
+ }
1204
+ if (prevSelectedAudioTrack === this._selectedAudioTrack) {
1205
1205
  return Promise.resolve(); // Audio language already selected
1206
1206
  }
1207
1207
 
1208
- switch (this._remotePlayerApiVersion) {
1209
- case 0:
1210
- case 1:
1211
- this._selectedAudioTrack = audioTrackId;
1212
- return Promise.resolve(); // Resolve immediately for older versions
1213
- case 2:
1214
- return this._selectAudioTrackV2(audioTrackId, prevSelectedAudioTrack);
1215
- default:
1216
- this._pendingAudioLanguage = audioTrackId;
1217
- return this._atomicSetAudioLanguage();
1218
- }
1208
+ return this._selectAudioTrack(audioTrackId, prevSelectedAudioTrack);
1219
1209
  }
1220
1210
 
1221
- /**
1222
- * Handles the asynchronous selection of an audio track.
1223
- * If the player is playing, it pauses before changing the track and resumes playback if necessary.
1224
- *
1225
- * @param {string} audioTrackId - The ID of the audio track to select.
1226
- * @param {string} prevSelectedAudioTrack - The previously selected audio track ID.
1227
- * @returns {Promise<void>} Resolves when the operation is complete.
1228
- * */
1229
- async _selectAudioTrackV2(audioTrackId, prevSelectedAudioTrack) {
1211
+ async _selectAudioTrack(audioTrackId, prevSelectedAudioTrack) {
1230
1212
  const prevIsPlaying = this._isPlaying;
1231
- sdkLogger.log(`remotePlayer _selectAudioTrackV2: prevAudioTrack=${prevSelectedAudioTrack} audioTrackId=${audioTrackId} isPlaying=${this._isPlaying}`);
1213
+ sdkLogger.log(`remotePlayer _selectAudioTrack: prevAudioTrack=${prevSelectedAudioTrack} audioTrackId=${audioTrackId} isPlaying=${this._isPlaying}`);
1232
1214
  try {
1233
1215
  if (this._isPlaying) await this.pause();
1234
1216
  let position = this.currentTime;
@@ -1236,9 +1218,9 @@ class RemotePlayer extends EventTarget {
1236
1218
  position = this._videoElement.currentTime;
1237
1219
  }
1238
1220
  await this._load(this._loadedUrl, position, audioTrackId, undefined, false);
1239
- this._selectedAudioTrack = audioTrackId;
1240
1221
  } catch (e) {
1241
- // Do NOT reject - just log
1222
+ // Do NOT reject - just log and revert selection
1223
+ this._selectedAudioTrack = prevSelectedAudioTrack;
1242
1224
  sdkLogger.warn(`Failed to select audio track ${audioTrackId}: ${e.message}`);
1243
1225
  return;
1244
1226
  }
@@ -1255,63 +1237,6 @@ class RemotePlayer extends EventTarget {
1255
1237
  }
1256
1238
  }
1257
1239
 
1258
- /**
1259
- * Handles the asynchronous selection of an audio track.
1260
- * If the player is playing, it stops subtitle streamType before changing the track and resumes subtitle streamType playback if necessary.
1261
- * Available only from v3 and on
1262
- *
1263
- * @param {string} audioTrackId - The ID of the audio track to select.
1264
- * @param {string} prevSelectedAudioTrack - The previously selected audio track ID.
1265
- * @returns {Promise<void>} Resolves when the operation is complete.
1266
- * */
1267
- async _selectAudioTrackV3(audioTrackId, prevSelectedAudioTrack) {
1268
- sdkLogger.log(`remotePlayer _selectAudioTrackV3: prevAudioTrack=${prevSelectedAudioTrack} audioTrackId=${audioTrackId} isPlaying=${this._isPlaying}`);
1269
- if (window.cefQuery) {
1270
- const FCID = getFCID();
1271
- const logger = sdkLogger.withFields({ FCID });
1272
- logger.log("remotePlayer _selectAudioTrackV3: sending setAudioLanguage action");
1273
- const message = {
1274
- type: "remotePlayer.setAudioLanguage",
1275
- class: "remotePlayer",
1276
- action: "setAudioLanguage",
1277
- fcid: FCID,
1278
- language: audioTrackId,
1279
- };
1280
- const request = { target: "TC", waitForResponse: true, message: JSON.stringify(message) };
1281
- return new Promise((resolve, reject) => {
1282
- let timerId = 0;
1283
- const timeBeforeSendingRequest = Date.now();
1284
- const queryId = window.cefQuery({
1285
- request: JSON.stringify(request),
1286
- persistent: false,
1287
- onSuccess: () => {
1288
- this._selectedAudioTrack = audioTrackId;
1289
- const duration = Date.now() - timeBeforeSendingRequest;
1290
- logger.withFields({ duration }).log(`setAudioLanguage completed successfully after ${duration} ms`);
1291
- timerId = clearTimer(timerId);
1292
- resolve();
1293
- },
1294
- onFailure: (code, msg) => {
1295
- const duration = Date.now() - timeBeforeSendingRequest;
1296
- logger.withFields({ duration }).log(`setAudioLanguage failed after ${duration} ms. Error code: ${code}, error message: ${msg}`);
1297
- timerId = clearTimer(timerId);
1298
- reject(new RemotePlayerError(code, msg));
1299
- }
1300
- });
1301
- logger.log(`window.cefQuery for setAudioLanguage returned query id ${queryId}`);
1302
- const timeout = this._remotePlayerConfirmationTimeout + 1000;
1303
- timerId = setTimeout(() => {
1304
- logger.log(`setAudioLanguage reached timeout of ${timeout} ms, canceling query id ${queryId}`);
1305
- window.cefQueryCancel(queryId);
1306
- reject(new RemotePlayerError(6000, `setAudioLanguage reached timeout of ${timeout} ms`));
1307
- }, timeout, queryId);
1308
- });
1309
- }
1310
-
1311
- sdkLogger.error("remotePlayer _selectAudioTrackV3: window.cefQuery is undefined");
1312
- return Promise.resolve(undefined);
1313
- }
1314
-
1315
1240
  /** Select a specific text (subtitle) track.
1316
1241
  * Track id should come from a call to getTextTracks.
1317
1242
  * If no tracks exist - this is a no-op.
@@ -1331,6 +1256,7 @@ class RemotePlayer extends EventTarget {
1331
1256
  const prevSelectedTextTrack = this._selectedSubtitlesTrack;
1332
1257
  for (const track of this.getTextTracks()) {
1333
1258
  if (track.id === textTrackId) {
1259
+ this._selectedSubtitlesTrack = textTrackId;
1334
1260
  found = true;
1335
1261
  break;
1336
1262
  }
@@ -1339,21 +1265,14 @@ class RemotePlayer extends EventTarget {
1339
1265
  sdkLogger.warn(`Invalid textTrackId ${textTrackId}`);
1340
1266
  return Promise.resolve();
1341
1267
  }
1342
- if (this._selectedSubtitlesTrack === textTrackId) {
1268
+ if (this._remotePlayerApiVersion < 2) {
1269
+ return Promise.resolve(); // Resolve immediately for older versions
1270
+ }
1271
+ if (prevSelectedTextTrack === this._selectedSubtitlesTrack) {
1343
1272
  return Promise.resolve(); // Subtitle language already selected
1344
1273
  }
1345
1274
 
1346
- switch (this._remotePlayerApiVersion) {
1347
- case 0:
1348
- case 1:
1349
- this._selectedSubtitlesTrack = textTrackId;
1350
- return Promise.resolve(); // Resolve immediately for older versions
1351
- case 2:
1352
- return this._selectTextTrackV2(textTrackId, prevSelectedTextTrack);
1353
- default:
1354
- this._pendingSubtitleLanguage = textTrackId;
1355
- return this._atomicSetSubtitleLanguage();
1356
- }
1275
+ return this._selectTextTrack(textTrackId, prevSelectedTextTrack);
1357
1276
  }
1358
1277
 
1359
1278
  /**
@@ -1364,9 +1283,9 @@ class RemotePlayer extends EventTarget {
1364
1283
  * @param {string} prevSelectedTextTrack - The previously selected text track ID.
1365
1284
  * @returns {Promise<void>} Resolves when the operation is complete.
1366
1285
  * */
1367
- async _selectTextTrackV2(textTrackId, prevSelectedTextTrack) {
1286
+ async _selectTextTrack(textTrackId, prevSelectedTextTrack) {
1368
1287
  const prevIsPlaying = this._isPlaying;
1369
- sdkLogger.log(`remotePlayer _selectTextTrackV2: prevTextTrack=${prevSelectedTextTrack} textTrackId=${textTrackId} isPlaying=${this._isPlaying}`);
1288
+ sdkLogger.log(`remotePlayer _selectTextTrack: prevTextTrack=${prevSelectedTextTrack} textTrackId=${textTrackId} isPlaying=${this._isPlaying}`);
1370
1289
  try {
1371
1290
  if (this._isPlaying) await this.pause();
1372
1291
  let position = this.currentTime;
@@ -1374,9 +1293,9 @@ class RemotePlayer extends EventTarget {
1374
1293
  position = this._videoElement.currentTime;
1375
1294
  }
1376
1295
  await this._load(this._loadedUrl, position, undefined, textTrackId, false);
1377
- this._selectedSubtitlesTrack = textTrackId;
1378
1296
  } catch (e) {
1379
- // Do NOT reject - just log
1297
+ // Do NOT reject - just log and revert selection
1298
+ this._selectedSubtitlesTrack = prevSelectedTextTrack;
1380
1299
  sdkLogger.warn(`Failed to select text track ${textTrackId}: ${e.message}`);
1381
1300
  return;
1382
1301
  }
@@ -1393,65 +1312,6 @@ class RemotePlayer extends EventTarget {
1393
1312
  }
1394
1313
  }
1395
1314
 
1396
- /**
1397
- * Handles the asynchronous selection of a text track.
1398
- * If the player is playing, it stops subtitle streamType before changing the track and resumes subtitle streamType playback if necessary.
1399
- * Available only from v3 and on
1400
- *
1401
- * @param {string} textTrackId - The ID of the text track to select.
1402
- * @param {string} prevSelectedTextTrack - The previously selected text track ID.
1403
- * @returns {Promise<void>} Resolves when the operation is complete.
1404
- * */
1405
- async _selectTextTrackV3(textTrackId, prevSelectedTextTrack) {
1406
- sdkLogger.log(`remotePlayer _selectTextTrackV3: prevAudioTrack=${prevSelectedTextTrack} textTrackId=${textTrackId} isPlaying=${this._isPlaying}`);
1407
- if (window.cefQuery) {
1408
- const FCID = getFCID();
1409
- const logger = sdkLogger.withFields({ FCID });
1410
- logger.log("remotePlayer _selectTextTrackV3: sending setSubtitleLanguage action");
1411
- const message = {
1412
- type: "remotePlayer.setSubtitleLanguage",
1413
- class: "remotePlayer",
1414
- action: "setSubtitleLanguage",
1415
- fcid: FCID,
1416
- language: textTrackId,
1417
- };
1418
- const request = { target: "TC", waitForResponse: true, message: JSON.stringify(message) };
1419
- return new Promise((resolve, reject) => {
1420
- let timerId = 0;
1421
- const timeBeforeSendingRequest = Date.now();
1422
- const queryId = window.cefQuery({
1423
- request: JSON.stringify(request),
1424
- persistent: false,
1425
- onSuccess: () => {
1426
- this._selectedSubtitlesTrack = textTrackId;
1427
- const duration = Date.now() - timeBeforeSendingRequest;
1428
- logger.withFields({ duration }).log(`setSubtitleLanguage completed successfully after ${duration} ms`);
1429
- timerId = clearTimer(timerId);
1430
- resolve();
1431
- },
1432
- onFailure: (code, msg) => {
1433
- const duration = Date.now() - timeBeforeSendingRequest;
1434
- logger.withFields({ duration }).log(`setSubtitleLanguage failed after ${duration} ms. Error code: ${code}, error message: ${msg}`);
1435
- timerId = clearTimer(timerId);
1436
- reject(new RemotePlayerError(code, msg));
1437
- }
1438
- });
1439
- logger.log(`window.cefQuery for setSubtitleLanguage returned query id ${queryId}`);
1440
- const timeout = this._remotePlayerConfirmationTimeout + 1000;
1441
- timerId = setTimeout(() => {
1442
- logger.log(`setSubtitleLanguage reached timeout of ${timeout} ms, canceling query id ${queryId}`);
1443
- window.cefQueryCancel(queryId);
1444
- reject(new RemotePlayerError(6000, `setSubtitleLanguage reached timeout of ${timeout} ms`));
1445
- }, timeout, queryId);
1446
- });
1447
- }
1448
- sdkLogger.error("remotePlayer _selectAudioTrackV3: window.cefQuery is undefined");
1449
- return Promise.resolve(undefined);
1450
-
1451
-
1452
- }
1453
-
1454
-
1455
1315
  /**
1456
1316
  * Enable or disable the subtitles.
1457
1317
  * If the player is in an unloaded state, the request will be applied next time content is played.
@@ -1606,6 +1466,8 @@ class RemotePlayer extends EventTarget {
1606
1466
  // The platform could be currently syncing audio/video using playback rate. Reset when performing seek.
1607
1467
  if (this._videoElement) {
1608
1468
  this._videoElement.playbackRate = 1.0;
1469
+ // on seek we need to reset any on going sync operation
1470
+ this._ptsSessionId++;
1609
1471
  }
1610
1472
 
1611
1473
  // Seeking is in progress
@@ -1678,96 +1540,6 @@ class RemotePlayer extends EventTarget {
1678
1540
  this._isSeekingByApplication = false;
1679
1541
  sdkLogger.info("Seeking: local video element seeking end");
1680
1542
  }
1681
-
1682
- async _atomicSetSubtitleLanguage() {
1683
- sdkLogger.info("SetSubtitleLanguage: local video element set start while isPLaying=", this._isPlaying);
1684
-
1685
- this._abortSetSubtitleLanguage = false;
1686
- this._isSetSubtitleByApplication = true;
1687
-
1688
- let state = SetSubtitleLanguageState.INIT;
1689
-
1690
- let previousPendingSubtitleLanguage = this._pendingSubtitleLanguage;
1691
- let initialSubtitleLanguage= this._pendingSubtitleLanguage;
1692
- let res;
1693
-
1694
- while (!this._abortSetSubtitleLanguage && state !== SetSubtitleLanguageState.DONE) {
1695
- try {
1696
- // TODO - Implement the logic for setting audio language
1697
- switch(state) {
1698
- case SetSubtitleLanguageState.INIT:
1699
- state = this._isPlaying ? SetSubtitleLanguageState.STOPPED : SetSubtitleLanguageState.SET;
1700
- break;
1701
- case SetSubtitleLanguageState.STOPPED:
1702
- await lifecycle.moveToForeground();
1703
- state = SetSubtitleLanguageState.SET;
1704
- break;
1705
- case SetSubtitleLanguageState.SET:
1706
- initialSubtitleLanguage = this._pendingSubtitleLanguage;
1707
- previousPendingSubtitleLanguage = this._selectedSubtitleTrack;
1708
- res = await this._selectTextTrackV3(initialSubtitleLanguage, previousPendingSubtitleLanguage);
1709
- state = SetSubtitleLanguageState.DONE;
1710
- break;
1711
- }
1712
- } catch (error) {
1713
- sdkLogger.error(`Error during set subtitle process: ${error.message}`);
1714
- state = SetSubtitleLanguageState.DONE;
1715
- res = Promise.reject(error);
1716
- } finally {
1717
- if (!this._abortSetSubtitleLanguage) {
1718
- this._play();
1719
- }
1720
- this._isSetSubtitleByApplication = false;
1721
- sdkLogger.info("SetSubtitleLanguage: local video element set subtitle end");
1722
- }
1723
- }
1724
- return res
1725
- }
1726
-
1727
- async _atomicSetAudioLanguage() {
1728
- sdkLogger.info("SetAudioLanguage: local video element set start while isPLaying=", this._isPlaying);
1729
-
1730
- this._abortSetAudioLanguage = false;
1731
- this._isSetAudioByApplication = true;
1732
-
1733
- let state = SetAudioLanguageState.INIT;
1734
-
1735
- let previousPendingAudioLanguage = this._pendingAudioLanguage;
1736
- let initialAudioLanguage= this._pendingAudioLanguage;
1737
- let res;
1738
-
1739
- while (!this._abortSetAudioLanguage && state !== SetAudioLanguageState.DONE) {
1740
- try {
1741
- // TODO - Implement the logic for setting audio language
1742
- switch(state) {
1743
- case SetAudioLanguageState.INIT:
1744
- state = this._isPlaying ? SetAudioLanguageState.STOPPED : SetAudioLanguageState.SET;
1745
- break;
1746
- case SetAudioLanguageState.STOPPED:
1747
- await lifecycle.moveToForeground();
1748
- state = SetAudioLanguageState.SET;
1749
- break;
1750
- case SetAudioLanguageState.SET:
1751
- initialAudioLanguage = this._pendingAudioLanguage;
1752
- previousPendingAudioLanguage = this._selectedAudioTrack;
1753
- res = await this._selectAudioTrackV3(initialAudioLanguage, previousPendingAudioLanguage);
1754
- state = SetAudioLanguageState.DONE;
1755
- break;
1756
- }
1757
- } catch (error) {
1758
- sdkLogger.error(`Error during set audio process: ${error.message}`);
1759
- state = SetAudioLanguageState.DONE;
1760
- res = Promise.reject(error);
1761
- } finally {
1762
- if (!this._abortSetAudioLanguage) {
1763
- this._play();
1764
- }
1765
- this._isSetAudioByApplication = false;
1766
- sdkLogger.info("SetAudioLanguage: local video element set audio end");
1767
- }
1768
- }
1769
- return res
1770
- }
1771
1543
  }
1772
1544
  /**
1773
1545
  *
package/src/utils.js CHANGED
@@ -155,24 +155,6 @@ export const TargetPlayingState = Object.freeze({
155
155
  PLAYING_ABR: "playingAbr"
156
156
  });
157
157
 
158
- export const SetAudioLanguageState = Object.freeze({
159
- INIT: "init",
160
- STOPPED: "stopped",
161
- SET: "set",
162
- MULTI_SET: "multiSet",
163
- WAITING: "waiting",
164
- DONE: "done"
165
- });
166
-
167
- export const SetSubtitleLanguageState = Object.freeze({
168
- INIT: "init",
169
- STOPPED: "stopped",
170
- SET: "set",
171
- MULTI_SET: "multiSet",
172
- WAITING: "waiting",
173
- DONE: "done"
174
- });
175
-
176
158
  export const iso6393to1 = {
177
159
  "aar": "aa",
178
160
  "abk": "ab",