senza-sdk 4.2.51-d3779b1.0 → 4.2.52
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/lifecycle.js +23 -18
- package/src/remotePlayer.js +24 -287
- package/src/utils.js +0 -18
package/package.json
CHANGED
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
|
-
*
|
|
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.
|
|
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
|
-
*
|
|
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
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
package/src/remotePlayer.js
CHANGED
|
@@ -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";
|
|
@@ -260,6 +258,7 @@ class RemotePlayer extends EventTarget {
|
|
|
260
258
|
}
|
|
261
259
|
const previousCurrentTime = this._videoElement.currentTime;
|
|
262
260
|
this._isSeekingByPlatform = true;
|
|
261
|
+
this._videoElement.playbackRate = 1.0;
|
|
263
262
|
this._videoElement.currentTime += event.detail; // event.detail contains the diff between the video and the audio
|
|
264
263
|
sdkLogger.info(`Adding ${event.detail} seconds, previousTime=${previousCurrentTime} currentTime=${this._videoElement.currentTime}`);
|
|
265
264
|
});
|
|
@@ -892,8 +891,6 @@ class RemotePlayer extends EventTarget {
|
|
|
892
891
|
if (this._loadMode === this.LoadMode.LOADING || this._loadMode === this.LoadMode.UNLOADING) {
|
|
893
892
|
throw new RemotePlayerError(6501, "Cannot call load() while previous load/unload is still in progress");
|
|
894
893
|
}
|
|
895
|
-
this._abortSetAudioLanguage = true;
|
|
896
|
-
this._abortSetSubtitleLanguage = true;
|
|
897
894
|
this._abortSeeking = true;
|
|
898
895
|
if (reset) {
|
|
899
896
|
this._reset();
|
|
@@ -1067,18 +1064,6 @@ class RemotePlayer extends EventTarget {
|
|
|
1067
1064
|
}
|
|
1068
1065
|
}
|
|
1069
1066
|
|
|
1070
|
-
if (this._isSetAudioByApplication) {
|
|
1071
|
-
sdkLogger.info("application requesting play during setAudioLanguage");
|
|
1072
|
-
this._targetSetAudioPlayingState = TargetPlayingState.PLAYING_UI;
|
|
1073
|
-
return Promise.resolve(true);
|
|
1074
|
-
}
|
|
1075
|
-
|
|
1076
|
-
if (this._isSetSubtitleByApplication) {
|
|
1077
|
-
sdkLogger.info("application requesting play during setSubtitleLanguage");
|
|
1078
|
-
this._targetSetSubtitlePlayingState = TargetPlayingState.PLAYING_UI;
|
|
1079
|
-
return Promise.resolve(true);
|
|
1080
|
-
}
|
|
1081
|
-
|
|
1082
1067
|
// If seeking in progress, wait for seek to complete before playing
|
|
1083
1068
|
if (this._isSeekingByApplication) {
|
|
1084
1069
|
sdkLogger.info("application requesting play during seek");
|
|
@@ -1118,16 +1103,6 @@ class RemotePlayer extends EventTarget {
|
|
|
1118
1103
|
this._targetSeekPlayingState = TargetPlayingState.PAUSED;
|
|
1119
1104
|
return Promise.resolve(true);
|
|
1120
1105
|
}
|
|
1121
|
-
if (this._isSetAudioByApplication) {
|
|
1122
|
-
sdkLogger.info("application requesting pause during setAudioLanguage");
|
|
1123
|
-
this._targetSetAudioPlayingState = TargetPlayingState.PAUSED;
|
|
1124
|
-
return Promise.resolve(true);
|
|
1125
|
-
}
|
|
1126
|
-
if (this._isSetSubtitleByApplication) {
|
|
1127
|
-
sdkLogger.info("application requesting pause during setSubtitleLanguage");
|
|
1128
|
-
this._targetSetSubtitlePlayingState = TargetPlayingState.PAUSED;
|
|
1129
|
-
return Promise.resolve(true);
|
|
1130
|
-
}
|
|
1131
1106
|
return this._pause();
|
|
1132
1107
|
}
|
|
1133
1108
|
|
|
@@ -1215,6 +1190,7 @@ class RemotePlayer extends EventTarget {
|
|
|
1215
1190
|
const prevSelectedAudioTrack = this._selectedAudioTrack;
|
|
1216
1191
|
for (const track of this.getAudioTracks()) {
|
|
1217
1192
|
if (track.id === audioTrackId) {
|
|
1193
|
+
this._selectedAudioTrack = audioTrackId;
|
|
1218
1194
|
found = true;
|
|
1219
1195
|
break;
|
|
1220
1196
|
}
|
|
@@ -1223,34 +1199,19 @@ class RemotePlayer extends EventTarget {
|
|
|
1223
1199
|
sdkLogger.warn(`Invalid audioTrackId ${audioTrackId}`);
|
|
1224
1200
|
return Promise.resolve();
|
|
1225
1201
|
}
|
|
1226
|
-
if (this.
|
|
1202
|
+
if (this._remotePlayerApiVersion < 2) {
|
|
1203
|
+
return Promise.resolve(); // Resolve immediately for older versions
|
|
1204
|
+
}
|
|
1205
|
+
if (prevSelectedAudioTrack === this._selectedAudioTrack) {
|
|
1227
1206
|
return Promise.resolve(); // Audio language already selected
|
|
1228
1207
|
}
|
|
1229
1208
|
|
|
1230
|
-
|
|
1231
|
-
case 0:
|
|
1232
|
-
case 1:
|
|
1233
|
-
this._selectedAudioTrack = audioTrackId;
|
|
1234
|
-
return Promise.resolve(); // Resolve immediately for older versions
|
|
1235
|
-
case 2:
|
|
1236
|
-
return this._selectAudioTrackV2(audioTrackId, prevSelectedAudioTrack);
|
|
1237
|
-
default:
|
|
1238
|
-
this._pendingAudioLanguage = audioTrackId;
|
|
1239
|
-
return this._atomicSetAudioLanguage();
|
|
1240
|
-
}
|
|
1209
|
+
return this._selectAudioTrack(audioTrackId, prevSelectedAudioTrack);
|
|
1241
1210
|
}
|
|
1242
1211
|
|
|
1243
|
-
|
|
1244
|
-
* Handles the asynchronous selection of an audio track.
|
|
1245
|
-
* If the player is playing, it pauses before changing the track and resumes playback if necessary.
|
|
1246
|
-
*
|
|
1247
|
-
* @param {string} audioTrackId - The ID of the audio track to select.
|
|
1248
|
-
* @param {string} prevSelectedAudioTrack - The previously selected audio track ID.
|
|
1249
|
-
* @returns {Promise<void>} Resolves when the operation is complete.
|
|
1250
|
-
* */
|
|
1251
|
-
async _selectAudioTrackV2(audioTrackId, prevSelectedAudioTrack) {
|
|
1212
|
+
async _selectAudioTrack(audioTrackId, prevSelectedAudioTrack) {
|
|
1252
1213
|
const prevIsPlaying = this._isPlaying;
|
|
1253
|
-
sdkLogger.log(`remotePlayer
|
|
1214
|
+
sdkLogger.log(`remotePlayer _selectAudioTrack: prevAudioTrack=${prevSelectedAudioTrack} audioTrackId=${audioTrackId} isPlaying=${this._isPlaying}`);
|
|
1254
1215
|
try {
|
|
1255
1216
|
if (this._isPlaying) await this.pause();
|
|
1256
1217
|
let position = this.currentTime;
|
|
@@ -1258,9 +1219,9 @@ class RemotePlayer extends EventTarget {
|
|
|
1258
1219
|
position = this._videoElement.currentTime;
|
|
1259
1220
|
}
|
|
1260
1221
|
await this._load(this._loadedUrl, position, audioTrackId, undefined, false);
|
|
1261
|
-
this._selectedAudioTrack = audioTrackId;
|
|
1262
1222
|
} catch (e) {
|
|
1263
|
-
// Do NOT reject - just log
|
|
1223
|
+
// Do NOT reject - just log and revert selection
|
|
1224
|
+
this._selectedAudioTrack = prevSelectedAudioTrack;
|
|
1264
1225
|
sdkLogger.warn(`Failed to select audio track ${audioTrackId}: ${e.message}`);
|
|
1265
1226
|
return;
|
|
1266
1227
|
}
|
|
@@ -1277,63 +1238,6 @@ class RemotePlayer extends EventTarget {
|
|
|
1277
1238
|
}
|
|
1278
1239
|
}
|
|
1279
1240
|
|
|
1280
|
-
/**
|
|
1281
|
-
* Handles the asynchronous selection of an audio track.
|
|
1282
|
-
* If the player is playing, it stops subtitle streamType before changing the track and resumes subtitle streamType playback if necessary.
|
|
1283
|
-
* Available only from v3 and on
|
|
1284
|
-
*
|
|
1285
|
-
* @param {string} audioTrackId - The ID of the audio track to select.
|
|
1286
|
-
* @param {string} prevSelectedAudioTrack - The previously selected audio track ID.
|
|
1287
|
-
* @returns {Promise<void>} Resolves when the operation is complete.
|
|
1288
|
-
* */
|
|
1289
|
-
async _selectAudioTrackV3(audioTrackId, prevSelectedAudioTrack) {
|
|
1290
|
-
sdkLogger.log(`remotePlayer _selectAudioTrackV3: prevAudioTrack=${prevSelectedAudioTrack} audioTrackId=${audioTrackId} isPlaying=${this._isPlaying}`);
|
|
1291
|
-
if (window.cefQuery) {
|
|
1292
|
-
const FCID = getFCID();
|
|
1293
|
-
const logger = sdkLogger.withFields({ FCID });
|
|
1294
|
-
logger.log("remotePlayer _selectAudioTrackV3: sending setAudioLanguage action");
|
|
1295
|
-
const message = {
|
|
1296
|
-
type: "remotePlayer.setAudioLanguage",
|
|
1297
|
-
class: "remotePlayer",
|
|
1298
|
-
action: "setAudioLanguage",
|
|
1299
|
-
fcid: FCID,
|
|
1300
|
-
language: audioTrackId,
|
|
1301
|
-
};
|
|
1302
|
-
const request = { target: "TC", waitForResponse: true, message: JSON.stringify(message) };
|
|
1303
|
-
return new Promise((resolve, reject) => {
|
|
1304
|
-
let timerId = 0;
|
|
1305
|
-
const timeBeforeSendingRequest = Date.now();
|
|
1306
|
-
const queryId = window.cefQuery({
|
|
1307
|
-
request: JSON.stringify(request),
|
|
1308
|
-
persistent: false,
|
|
1309
|
-
onSuccess: () => {
|
|
1310
|
-
this._selectedAudioTrack = audioTrackId;
|
|
1311
|
-
const duration = Date.now() - timeBeforeSendingRequest;
|
|
1312
|
-
logger.withFields({ duration }).log(`setAudioLanguage completed successfully after ${duration} ms`);
|
|
1313
|
-
timerId = clearTimer(timerId);
|
|
1314
|
-
resolve();
|
|
1315
|
-
},
|
|
1316
|
-
onFailure: (code, msg) => {
|
|
1317
|
-
const duration = Date.now() - timeBeforeSendingRequest;
|
|
1318
|
-
logger.withFields({ duration }).log(`setAudioLanguage failed after ${duration} ms. Error code: ${code}, error message: ${msg}`);
|
|
1319
|
-
timerId = clearTimer(timerId);
|
|
1320
|
-
reject(new RemotePlayerError(code, msg));
|
|
1321
|
-
}
|
|
1322
|
-
});
|
|
1323
|
-
logger.log(`window.cefQuery for setAudioLanguage returned query id ${queryId}`);
|
|
1324
|
-
const timeout = this._remotePlayerConfirmationTimeout + 1000;
|
|
1325
|
-
timerId = setTimeout(() => {
|
|
1326
|
-
logger.log(`setAudioLanguage reached timeout of ${timeout} ms, canceling query id ${queryId}`);
|
|
1327
|
-
window.cefQueryCancel(queryId);
|
|
1328
|
-
reject(new RemotePlayerError(6000, `setAudioLanguage reached timeout of ${timeout} ms`));
|
|
1329
|
-
}, timeout, queryId);
|
|
1330
|
-
});
|
|
1331
|
-
}
|
|
1332
|
-
|
|
1333
|
-
sdkLogger.error("remotePlayer _selectAudioTrackV3: window.cefQuery is undefined");
|
|
1334
|
-
return Promise.resolve(undefined);
|
|
1335
|
-
}
|
|
1336
|
-
|
|
1337
1241
|
/** Select a specific text (subtitle) track.
|
|
1338
1242
|
* Track id should come from a call to getTextTracks.
|
|
1339
1243
|
* If no tracks exist - this is a no-op.
|
|
@@ -1353,6 +1257,7 @@ class RemotePlayer extends EventTarget {
|
|
|
1353
1257
|
const prevSelectedTextTrack = this._selectedSubtitlesTrack;
|
|
1354
1258
|
for (const track of this.getTextTracks()) {
|
|
1355
1259
|
if (track.id === textTrackId) {
|
|
1260
|
+
this._selectedSubtitlesTrack = textTrackId;
|
|
1356
1261
|
found = true;
|
|
1357
1262
|
break;
|
|
1358
1263
|
}
|
|
@@ -1361,21 +1266,14 @@ class RemotePlayer extends EventTarget {
|
|
|
1361
1266
|
sdkLogger.warn(`Invalid textTrackId ${textTrackId}`);
|
|
1362
1267
|
return Promise.resolve();
|
|
1363
1268
|
}
|
|
1364
|
-
if (this.
|
|
1269
|
+
if (this._remotePlayerApiVersion < 2) {
|
|
1270
|
+
return Promise.resolve(); // Resolve immediately for older versions
|
|
1271
|
+
}
|
|
1272
|
+
if (prevSelectedTextTrack === this._selectedSubtitlesTrack) {
|
|
1365
1273
|
return Promise.resolve(); // Subtitle language already selected
|
|
1366
1274
|
}
|
|
1367
1275
|
|
|
1368
|
-
|
|
1369
|
-
case 0:
|
|
1370
|
-
case 1:
|
|
1371
|
-
this._selectedSubtitlesTrack = textTrackId;
|
|
1372
|
-
return Promise.resolve(); // Resolve immediately for older versions
|
|
1373
|
-
case 2:
|
|
1374
|
-
return this._selectTextTrackV2(textTrackId, prevSelectedTextTrack);
|
|
1375
|
-
default:
|
|
1376
|
-
this._pendingSubtitleLanguage = textTrackId;
|
|
1377
|
-
return this._atomicSetSubtitleLanguage();
|
|
1378
|
-
}
|
|
1276
|
+
return this._selectTextTrack(textTrackId, prevSelectedTextTrack);
|
|
1379
1277
|
}
|
|
1380
1278
|
|
|
1381
1279
|
/**
|
|
@@ -1386,9 +1284,9 @@ class RemotePlayer extends EventTarget {
|
|
|
1386
1284
|
* @param {string} prevSelectedTextTrack - The previously selected text track ID.
|
|
1387
1285
|
* @returns {Promise<void>} Resolves when the operation is complete.
|
|
1388
1286
|
* */
|
|
1389
|
-
async
|
|
1287
|
+
async _selectTextTrack(textTrackId, prevSelectedTextTrack) {
|
|
1390
1288
|
const prevIsPlaying = this._isPlaying;
|
|
1391
|
-
sdkLogger.log(`remotePlayer
|
|
1289
|
+
sdkLogger.log(`remotePlayer _selectTextTrack: prevTextTrack=${prevSelectedTextTrack} textTrackId=${textTrackId} isPlaying=${this._isPlaying}`);
|
|
1392
1290
|
try {
|
|
1393
1291
|
if (this._isPlaying) await this.pause();
|
|
1394
1292
|
let position = this.currentTime;
|
|
@@ -1396,9 +1294,9 @@ class RemotePlayer extends EventTarget {
|
|
|
1396
1294
|
position = this._videoElement.currentTime;
|
|
1397
1295
|
}
|
|
1398
1296
|
await this._load(this._loadedUrl, position, undefined, textTrackId, false);
|
|
1399
|
-
this._selectedSubtitlesTrack = textTrackId;
|
|
1400
1297
|
} catch (e) {
|
|
1401
|
-
// Do NOT reject - just log
|
|
1298
|
+
// Do NOT reject - just log and revert selection
|
|
1299
|
+
this._selectedSubtitlesTrack = prevSelectedTextTrack;
|
|
1402
1300
|
sdkLogger.warn(`Failed to select text track ${textTrackId}: ${e.message}`);
|
|
1403
1301
|
return;
|
|
1404
1302
|
}
|
|
@@ -1415,65 +1313,6 @@ class RemotePlayer extends EventTarget {
|
|
|
1415
1313
|
}
|
|
1416
1314
|
}
|
|
1417
1315
|
|
|
1418
|
-
/**
|
|
1419
|
-
* Handles the asynchronous selection of a text track.
|
|
1420
|
-
* If the player is playing, it stops subtitle streamType before changing the track and resumes subtitle streamType playback if necessary.
|
|
1421
|
-
* Available only from v3 and on
|
|
1422
|
-
*
|
|
1423
|
-
* @param {string} textTrackId - The ID of the text track to select.
|
|
1424
|
-
* @param {string} prevSelectedTextTrack - The previously selected text track ID.
|
|
1425
|
-
* @returns {Promise<void>} Resolves when the operation is complete.
|
|
1426
|
-
* */
|
|
1427
|
-
async _selectTextTrackV3(textTrackId, prevSelectedTextTrack) {
|
|
1428
|
-
sdkLogger.log(`remotePlayer _selectTextTrackV3: prevAudioTrack=${prevSelectedTextTrack} textTrackId=${textTrackId} isPlaying=${this._isPlaying}`);
|
|
1429
|
-
if (window.cefQuery) {
|
|
1430
|
-
const FCID = getFCID();
|
|
1431
|
-
const logger = sdkLogger.withFields({ FCID });
|
|
1432
|
-
logger.log("remotePlayer _selectTextTrackV3: sending setSubtitleLanguage action");
|
|
1433
|
-
const message = {
|
|
1434
|
-
type: "remotePlayer.setSubtitleLanguage",
|
|
1435
|
-
class: "remotePlayer",
|
|
1436
|
-
action: "setSubtitleLanguage",
|
|
1437
|
-
fcid: FCID,
|
|
1438
|
-
language: textTrackId,
|
|
1439
|
-
};
|
|
1440
|
-
const request = { target: "TC", waitForResponse: true, message: JSON.stringify(message) };
|
|
1441
|
-
return new Promise((resolve, reject) => {
|
|
1442
|
-
let timerId = 0;
|
|
1443
|
-
const timeBeforeSendingRequest = Date.now();
|
|
1444
|
-
const queryId = window.cefQuery({
|
|
1445
|
-
request: JSON.stringify(request),
|
|
1446
|
-
persistent: false,
|
|
1447
|
-
onSuccess: () => {
|
|
1448
|
-
this._selectedSubtitlesTrack = textTrackId;
|
|
1449
|
-
const duration = Date.now() - timeBeforeSendingRequest;
|
|
1450
|
-
logger.withFields({ duration }).log(`setSubtitleLanguage completed successfully after ${duration} ms`);
|
|
1451
|
-
timerId = clearTimer(timerId);
|
|
1452
|
-
resolve();
|
|
1453
|
-
},
|
|
1454
|
-
onFailure: (code, msg) => {
|
|
1455
|
-
const duration = Date.now() - timeBeforeSendingRequest;
|
|
1456
|
-
logger.withFields({ duration }).log(`setSubtitleLanguage failed after ${duration} ms. Error code: ${code}, error message: ${msg}`);
|
|
1457
|
-
timerId = clearTimer(timerId);
|
|
1458
|
-
reject(new RemotePlayerError(code, msg));
|
|
1459
|
-
}
|
|
1460
|
-
});
|
|
1461
|
-
logger.log(`window.cefQuery for setSubtitleLanguage returned query id ${queryId}`);
|
|
1462
|
-
const timeout = this._remotePlayerConfirmationTimeout + 1000;
|
|
1463
|
-
timerId = setTimeout(() => {
|
|
1464
|
-
logger.log(`setSubtitleLanguage reached timeout of ${timeout} ms, canceling query id ${queryId}`);
|
|
1465
|
-
window.cefQueryCancel(queryId);
|
|
1466
|
-
reject(new RemotePlayerError(6000, `setSubtitleLanguage reached timeout of ${timeout} ms`));
|
|
1467
|
-
}, timeout, queryId);
|
|
1468
|
-
});
|
|
1469
|
-
}
|
|
1470
|
-
sdkLogger.error("remotePlayer _selectAudioTrackV3: window.cefQuery is undefined");
|
|
1471
|
-
return Promise.resolve(undefined);
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
}
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
1316
|
/**
|
|
1478
1317
|
* Enable or disable the subtitles.
|
|
1479
1318
|
* If the player is in an unloaded state, the request will be applied next time content is played.
|
|
@@ -1628,6 +1467,8 @@ class RemotePlayer extends EventTarget {
|
|
|
1628
1467
|
// The platform could be currently syncing audio/video using playback rate. Reset when performing seek.
|
|
1629
1468
|
if (this._videoElement) {
|
|
1630
1469
|
this._videoElement.playbackRate = 1.0;
|
|
1470
|
+
// For local seek, we need to reset any ongoing sync operation
|
|
1471
|
+
this._ptsSessionId++;
|
|
1631
1472
|
}
|
|
1632
1473
|
|
|
1633
1474
|
// Seeking is in progress
|
|
@@ -1700,110 +1541,6 @@ class RemotePlayer extends EventTarget {
|
|
|
1700
1541
|
this._isSeekingByApplication = false;
|
|
1701
1542
|
sdkLogger.info("Seeking: local video element seeking end");
|
|
1702
1543
|
}
|
|
1703
|
-
|
|
1704
|
-
async _atomicSetSubtitleLanguage() {
|
|
1705
|
-
sdkLogger.info("SetSubtitleLanguage: local video element set start while isPLaying=", this._isPlaying);
|
|
1706
|
-
|
|
1707
|
-
this._targetSeekPlayingState = this._isPlaying ? TargetPlayingState.PLAYING_UI : TargetPlayingState.PAUSED;
|
|
1708
|
-
this._abortSetSubtitleLanguage = false;
|
|
1709
|
-
this._isSetSubtitleByApplication = true;
|
|
1710
|
-
|
|
1711
|
-
let state = SetSubtitleLanguageState.INIT;
|
|
1712
|
-
|
|
1713
|
-
let previousPendingSubtitleLanguage = this._pendingSubtitleLanguage;
|
|
1714
|
-
let initialSubtitleLanguage= this._pendingSubtitleLanguage;
|
|
1715
|
-
let res;
|
|
1716
|
-
|
|
1717
|
-
while (!this._abortSetSubtitleLanguage && state !== SetSubtitleLanguageState.DONE) {
|
|
1718
|
-
try {
|
|
1719
|
-
// TODO - Implement the logic for setting audio language
|
|
1720
|
-
switch(state) {
|
|
1721
|
-
case SetSubtitleLanguageState.INIT:
|
|
1722
|
-
state = this._isPlaying ? SetSubtitleLanguageState.STOPPED : SetSubtitleLanguageState.SET;
|
|
1723
|
-
break;
|
|
1724
|
-
case SetSubtitleLanguageState.STOPPED:
|
|
1725
|
-
await lifecycle.moveToForeground();
|
|
1726
|
-
state = SetSubtitleLanguageState.SET;
|
|
1727
|
-
break;
|
|
1728
|
-
case SetSubtitleLanguageState.SET:
|
|
1729
|
-
initialSubtitleLanguage = this._pendingSubtitleLanguage;
|
|
1730
|
-
previousPendingSubtitleLanguage = this._selectedSubtitleTrack;
|
|
1731
|
-
res = await this._selectTextTrackV3(initialSubtitleLanguage, previousPendingSubtitleLanguage);
|
|
1732
|
-
state = SetSubtitleLanguageState.DONE;
|
|
1733
|
-
break;
|
|
1734
|
-
}
|
|
1735
|
-
} catch (error) {
|
|
1736
|
-
sdkLogger.error(`Error during set subtitle process: ${error.message}`);
|
|
1737
|
-
state = SetSubtitleLanguageState.DONE;
|
|
1738
|
-
res = Promise.reject(error);
|
|
1739
|
-
} finally {
|
|
1740
|
-
if (!this._abortSetSubtitleLanguage) {
|
|
1741
|
-
if (this._targetSeekPlayingState === TargetPlayingState.PLAYING_UI) {
|
|
1742
|
-
console.log("BEFORE PLAY AFTER SET SUBTITLE");
|
|
1743
|
-
await this._play();
|
|
1744
|
-
} else if (this._targetSeekPlayingState === TargetPlayingState.PLAYING_ABR) {
|
|
1745
|
-
console.log("BEFORE MOVE_TO_BACKGROUND AFTER SET SUBTITLE");
|
|
1746
|
-
await lifecycle._moveToBackground();
|
|
1747
|
-
}
|
|
1748
|
-
}
|
|
1749
|
-
this._isSetSubtitleByApplication = false;
|
|
1750
|
-
sdkLogger.info("SetSubtitleLanguage: local video element set subtitle end");
|
|
1751
|
-
}
|
|
1752
|
-
}
|
|
1753
|
-
return res
|
|
1754
|
-
}
|
|
1755
|
-
|
|
1756
|
-
async _atomicSetAudioLanguage() {
|
|
1757
|
-
sdkLogger.info("SetAudioLanguage: local video element set start while isPLaying=", this._isPlaying);
|
|
1758
|
-
|
|
1759
|
-
this._targetSeekPlayingState = this._isPlaying ? TargetPlayingState.PLAYING_UI : TargetPlayingState.PAUSED;
|
|
1760
|
-
this._abortSetAudioLanguage = false;
|
|
1761
|
-
this._isSetAudioByApplication = true;
|
|
1762
|
-
|
|
1763
|
-
let state = SetAudioLanguageState.INIT;
|
|
1764
|
-
|
|
1765
|
-
let previousPendingAudioLanguage = this._pendingAudioLanguage;
|
|
1766
|
-
let initialAudioLanguage= this._pendingAudioLanguage;
|
|
1767
|
-
let res;
|
|
1768
|
-
|
|
1769
|
-
while (!this._abortSetAudioLanguage && state !== SetAudioLanguageState.DONE) {
|
|
1770
|
-
try {
|
|
1771
|
-
// TODO - Implement the logic for setting audio language
|
|
1772
|
-
switch(state) {
|
|
1773
|
-
case SetAudioLanguageState.INIT:
|
|
1774
|
-
state = this._isPlaying ? SetAudioLanguageState.STOPPED : SetAudioLanguageState.SET;
|
|
1775
|
-
break;
|
|
1776
|
-
case SetAudioLanguageState.STOPPED:
|
|
1777
|
-
await lifecycle.moveToForeground();
|
|
1778
|
-
state = SetAudioLanguageState.SET;
|
|
1779
|
-
break;
|
|
1780
|
-
case SetAudioLanguageState.SET:
|
|
1781
|
-
initialAudioLanguage = this._pendingAudioLanguage;
|
|
1782
|
-
previousPendingAudioLanguage = this._selectedAudioTrack;
|
|
1783
|
-
res = await this._selectAudioTrackV3(initialAudioLanguage, previousPendingAudioLanguage);
|
|
1784
|
-
state = SetAudioLanguageState.DONE;
|
|
1785
|
-
break;
|
|
1786
|
-
}
|
|
1787
|
-
} catch (error) {
|
|
1788
|
-
sdkLogger.error(`Error during set audio process: ${error.message}`);
|
|
1789
|
-
state = SetAudioLanguageState.DONE;
|
|
1790
|
-
res = Promise.reject(error);
|
|
1791
|
-
} finally {
|
|
1792
|
-
if (!this._abortSetAudioLanguage) {
|
|
1793
|
-
if (this._targetSeekPlayingState === TargetPlayingState.PLAYING_UI) {
|
|
1794
|
-
console.log("BEFORE PLAY AFTER SET AUDIO");
|
|
1795
|
-
await this._play();
|
|
1796
|
-
} else if (this._targetSeekPlayingState === TargetPlayingState.PLAYING_ABR) {
|
|
1797
|
-
console.log("BEFORE MOVE_TO_BACKGROUND AFTER SET AUDIO");
|
|
1798
|
-
await lifecycle._moveToBackground();
|
|
1799
|
-
}
|
|
1800
|
-
}
|
|
1801
|
-
this._isSetAudioByApplication = false;
|
|
1802
|
-
sdkLogger.info("SetAudioLanguage: local video element set audio end");
|
|
1803
|
-
}
|
|
1804
|
-
}
|
|
1805
|
-
return res
|
|
1806
|
-
}
|
|
1807
1544
|
}
|
|
1808
1545
|
/**
|
|
1809
1546
|
*
|
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",
|