eyevinn-channel-engine 4.3.7 → 4.3.8
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/engine/session.d.ts +5 -0
- package/dist/engine/session.js +143 -110
- package/dist/package.json +1 -1
- package/engine/session.js +76 -40
- package/package.json +1 -1
- package/spec/engine/session_spec.js +104 -8
package/dist/engine/session.d.ts
CHANGED
|
@@ -123,4 +123,9 @@ declare class Session {
|
|
|
123
123
|
_getLastDuration(manifest: any): Promise<any>;
|
|
124
124
|
_getPlayheadDiffCompensationValue(diffMs: any, thresholdMs: any): number;
|
|
125
125
|
_isOldVod(refTs: any, vodDur: any): boolean;
|
|
126
|
+
_determineExtraMediaIncrement(_extraType: any, _currentPosVideo: any, _extraSeqFinalIndex: any, _vodMediaSeqExtra: any, _getExtraPlayheadPositionAsyncFn: any): Promise<{
|
|
127
|
+
increment: number;
|
|
128
|
+
position: number;
|
|
129
|
+
diff: string;
|
|
130
|
+
}>;
|
|
126
131
|
}
|
package/dist/engine/session.js
CHANGED
|
@@ -1087,24 +1087,24 @@ var Session = /** @class */ (function () {
|
|
|
1087
1087
|
};
|
|
1088
1088
|
Session.prototype.incrementAsync = function () {
|
|
1089
1089
|
return __awaiter(this, void 0, void 0, function () {
|
|
1090
|
-
var isLeader, sessionState, playheadState, currentVod, _a, isOldVod, nextState, leaderAction, leaderState, _b, m3u8_4, _c,
|
|
1091
|
-
return __generator(this, function (
|
|
1092
|
-
switch (
|
|
1090
|
+
var isLeader, sessionState, playheadState, currentVod, _a, isOldVod, nextState, leaderAction, leaderState, _b, m3u8_4, _c, playheadPosVideoMs, playheadAudio, playheadSubtitle, audioSeqLastIdx, sessionStateObj, _d, playheadPosVideo, _e, subtitleSeqLastIdx, sessionStateObj, _f, newSessionState, updatedValues, updatedPlayhead, mediaSequenceValue, audioInfo, mediaSequenceValueAudio, diffMs, m3u8;
|
|
1091
|
+
return __generator(this, function (_g) {
|
|
1092
|
+
switch (_g.label) {
|
|
1093
1093
|
case 0: return [4 /*yield*/, this._tickAsync()];
|
|
1094
1094
|
case 1:
|
|
1095
|
-
|
|
1095
|
+
_g.sent();
|
|
1096
1096
|
return [4 /*yield*/, this._sessionStateStore.isLeader(this._instanceId)];
|
|
1097
1097
|
case 2:
|
|
1098
|
-
isLeader =
|
|
1098
|
+
isLeader = _g.sent();
|
|
1099
1099
|
return [4 /*yield*/, this._sessionState.getValues(["state", "mediaSeq", "mediaSeqAudio", "mediaSeqSubtitle", "discSeq", "discSeqAudio", "discSeqSubtitle", "vodMediaSeqVideo", "vodMediaSeqAudio", "vodMediaSeqSubtitle"])];
|
|
1100
1100
|
case 3:
|
|
1101
|
-
sessionState =
|
|
1101
|
+
sessionState = _g.sent();
|
|
1102
1102
|
return [4 /*yield*/, this._playheadState.getValues(["mediaSeq", "mediaSeqAudio", "mediaSeqSubtitle", "vodMediaSeqVideo", "vodMediaSeqAudio", "vodMediaSubtitle", "playheadRef"])];
|
|
1103
1103
|
case 4:
|
|
1104
|
-
playheadState =
|
|
1104
|
+
playheadState = _g.sent();
|
|
1105
1105
|
return [4 /*yield*/, this._sessionState.getCurrentVod()];
|
|
1106
1106
|
case 5:
|
|
1107
|
-
currentVod =
|
|
1107
|
+
currentVod = _g.sent();
|
|
1108
1108
|
if (!(!currentVod ||
|
|
1109
1109
|
sessionState.vodMediaSeqVideo === null ||
|
|
1110
1110
|
sessionState.vodMediaSeqAudio === null ||
|
|
@@ -1116,14 +1116,14 @@ var Session = /** @class */ (function () {
|
|
|
1116
1116
|
debug(sessionState);
|
|
1117
1117
|
return [4 /*yield*/, this._sessionState.clearCurrentVodCache()];
|
|
1118
1118
|
case 6:
|
|
1119
|
-
|
|
1119
|
+
_g.sent();
|
|
1120
1120
|
if (!isLeader) return [3 /*break*/, 8];
|
|
1121
1121
|
debug("[".concat(this._sessionId, "]: I am the leader, trying to initiate the session"));
|
|
1122
1122
|
_a = sessionState;
|
|
1123
1123
|
return [4 /*yield*/, this._sessionState.set("state", SessionState.VOD_INIT)];
|
|
1124
1124
|
case 7:
|
|
1125
|
-
_a.state =
|
|
1126
|
-
|
|
1125
|
+
_a.state = _g.sent();
|
|
1126
|
+
_g.label = 8;
|
|
1127
1127
|
case 8: return [2 /*return*/, null];
|
|
1128
1128
|
case 9:
|
|
1129
1129
|
if (!(sessionState.state === SessionState.VOD_NEXT_INITIATING || sessionState.state === SessionState.VOD_RELOAD_INITIATING)) return [3 /*break*/, 14];
|
|
@@ -1139,13 +1139,13 @@ var Session = /** @class */ (function () {
|
|
|
1139
1139
|
_b = sessionState;
|
|
1140
1140
|
return [4 /*yield*/, this._sessionState.set("state", nextState)];
|
|
1141
1141
|
case 10:
|
|
1142
|
-
_b.state =
|
|
1142
|
+
_b.state = _g.sent();
|
|
1143
1143
|
return [3 /*break*/, 13];
|
|
1144
1144
|
case 11:
|
|
1145
1145
|
debug("[".concat(this._sessionId, "]: Return the last generated m3u8 to give the leader some time"));
|
|
1146
1146
|
return [4 /*yield*/, this._playheadState.getLastM3u8()];
|
|
1147
1147
|
case 12:
|
|
1148
|
-
m3u8_4 =
|
|
1148
|
+
m3u8_4 = _g.sent();
|
|
1149
1149
|
if (m3u8_4) {
|
|
1150
1150
|
return [2 /*return*/, m3u8_4];
|
|
1151
1151
|
}
|
|
@@ -1153,78 +1153,65 @@ var Session = /** @class */ (function () {
|
|
|
1153
1153
|
debug("[".concat(this._sessionId, "]: We don't have any previously generated m3u8"));
|
|
1154
1154
|
}
|
|
1155
1155
|
this.isAllowedToClearVodCache = true;
|
|
1156
|
-
|
|
1157
|
-
case 13: return [3 /*break*/,
|
|
1156
|
+
_g.label = 13;
|
|
1157
|
+
case 13: return [3 /*break*/, 28];
|
|
1158
1158
|
case 14:
|
|
1159
1159
|
_c = sessionState;
|
|
1160
1160
|
return [4 /*yield*/, this._sessionState.increment("vodMediaSeqVideo", 1)];
|
|
1161
1161
|
case 15:
|
|
1162
|
-
_c.vodMediaSeqVideo =
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1162
|
+
_c.vodMediaSeqVideo = _g.sent();
|
|
1163
|
+
playheadPosVideoMs = void 0;
|
|
1164
|
+
playheadAudio = void 0;
|
|
1165
|
+
playheadSubtitle = void 0;
|
|
1166
|
+
if (!(this.use_demuxed_audio || this.use_vtt_subtitles)) return [3 /*break*/, 17];
|
|
1167
1167
|
return [4 /*yield*/, this._getCurrentPlayheadPosition()];
|
|
1168
1168
|
case 16:
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
return [4 /*yield*/, this._sessionState.getCurrentVod()];
|
|
1169
|
+
playheadPosVideoMs = (_g.sent()) * 1000;
|
|
1170
|
+
_g.label = 17;
|
|
1172
1171
|
case 17:
|
|
1173
|
-
|
|
1172
|
+
if (!this.use_demuxed_audio) return [3 /*break*/, 21];
|
|
1173
|
+
audioSeqLastIdx = currentVod.getLiveMediaSequencesCount("audio") - 1;
|
|
1174
1174
|
return [4 /*yield*/, this._sessionState.getValues(["vodMediaSeqAudio"])];
|
|
1175
1175
|
case 18:
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
_f.label = 19;
|
|
1185
|
-
case 19: return [4 /*yield*/, this._getAudioPlayheadPosition(sessionState_1.vodMediaSeqAudio + index)];
|
|
1176
|
+
sessionStateObj = _g.sent();
|
|
1177
|
+
return [4 /*yield*/, this._determineExtraMediaIncrement("audio", playheadPosVideoMs, audioSeqLastIdx, sessionStateObj.vodMediaSeqAudio, this._getAudioPlayheadPosition.bind(this))];
|
|
1178
|
+
case 19:
|
|
1179
|
+
playheadAudio = _g.sent();
|
|
1180
|
+
// Perform the Increment
|
|
1181
|
+
debug("[".concat(this._sessionId, "]: Will increment audio with ").concat(playheadAudio.increment));
|
|
1182
|
+
_d = sessionState;
|
|
1183
|
+
return [4 /*yield*/, this._sessionState.increment("vodMediaSeqAudio", playheadAudio.increment)];
|
|
1186
1184
|
case 20:
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
posDiff = (positionV - positionA).toFixed(3);
|
|
1190
|
-
debug("[".concat(this._sessionId, "]: positionV=").concat(positionV, ";positionA=").concat(positionA, ";posDiff=").concat(posDiff));
|
|
1191
|
-
if (posDiff <= maxAcceptableDiff) {
|
|
1192
|
-
return [3 /*break*/, 22];
|
|
1193
|
-
}
|
|
1194
|
-
if (posDiff > thresh) {
|
|
1195
|
-
index++;
|
|
1196
|
-
incrementValue++;
|
|
1197
|
-
}
|
|
1198
|
-
else if (posDiff > maxAcceptableDiff) {
|
|
1199
|
-
index = incrementValue;
|
|
1200
|
-
debug("[".concat(this._sessionId, "]: Audio Stepping index set to = ").concat(index));
|
|
1201
|
-
return [3 /*break*/, 22];
|
|
1202
|
-
}
|
|
1203
|
-
if (sessionState_1.vodMediaSeqAudio + index > audioSeqLastIdx) {
|
|
1204
|
-
return [3 /*break*/, 22];
|
|
1205
|
-
}
|
|
1206
|
-
_f.label = 21;
|
|
1185
|
+
_d.vodMediaSeqAudio = _g.sent();
|
|
1186
|
+
_g.label = 21;
|
|
1207
1187
|
case 21:
|
|
1208
|
-
if (!
|
|
1209
|
-
|
|
1188
|
+
if (!this.use_vtt_subtitles) return [3 /*break*/, 27];
|
|
1189
|
+
_e = playheadPosVideo;
|
|
1190
|
+
if (_e) return [3 /*break*/, 23];
|
|
1191
|
+
return [4 /*yield*/, this._getCurrentPlayheadPosition()];
|
|
1210
1192
|
case 22:
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
_f.label = 23;
|
|
1193
|
+
_e = (_g.sent()) * 1000;
|
|
1194
|
+
_g.label = 23;
|
|
1214
1195
|
case 23:
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
return [4 /*yield*/, this._sessionState.
|
|
1196
|
+
playheadPosVideo = _e;
|
|
1197
|
+
subtitleSeqLastIdx = currentVod.getLiveMediaSequencesCount("subtitle") - 1;
|
|
1198
|
+
return [4 /*yield*/, this._sessionState.getValues(["vodMediaSeqSubtitle"])];
|
|
1218
1199
|
case 24:
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
debug("[".concat(this._sessionId, "]: Will increment subtitle with 1"));
|
|
1222
|
-
_e = sessionState;
|
|
1223
|
-
return [4 /*yield*/, this._sessionState.increment("vodMediaSeqSubtitle", 1)];
|
|
1200
|
+
sessionStateObj = _g.sent();
|
|
1201
|
+
return [4 /*yield*/, this._determineExtraMediaIncrement("subtitle", playheadPosVideoMs, subtitleSeqLastIdx, sessionStateObj.vodMediaSeqSubtitle, this._getSubtitlePlayheadPosition.bind(this))];
|
|
1224
1202
|
case 25:
|
|
1225
|
-
|
|
1226
|
-
|
|
1203
|
+
playheadSubtitle = _g.sent();
|
|
1204
|
+
// Perform the Increment
|
|
1205
|
+
debug("[".concat(this._sessionId, "]: Will increment subtitle with ").concat(playheadSubtitle.increment));
|
|
1206
|
+
_f = sessionState;
|
|
1207
|
+
return [4 /*yield*/, this._sessionState.increment("vodMediaSeqSubtitle", playheadSubtitle.increment)];
|
|
1227
1208
|
case 26:
|
|
1209
|
+
_f.vodMediaSeqSubtitle = _g.sent();
|
|
1210
|
+
_g.label = 27;
|
|
1211
|
+
case 27:
|
|
1212
|
+
debug("[".concat(this._sessionId, "]: Current VOD Playhead Positions are to be V[").concat((playheadPosVideoMs / 1000).toFixed(3), "]").concat(playheadAudio ? "A[".concat((playheadAudio.position).toFixed(3), "]") : "").concat(playheadSubtitle ? "S[".concat((playheadSubtitle.position).toFixed(3), ")]") : "").concat(playheadAudio ? " (".concat(playheadAudio.diff, ")") : "").concat(playheadSubtitle ? " (".concat(playheadSubtitle.diff, ")") : ""));
|
|
1213
|
+
_g.label = 28;
|
|
1214
|
+
case 28:
|
|
1228
1215
|
newSessionState = {};
|
|
1229
1216
|
if (sessionState.vodMediaSeqVideo >= currentVod.getLiveMediaSequencesCount() - 1) {
|
|
1230
1217
|
newSessionState.vodMediaSeqVideo = currentVod.getLiveMediaSequencesCount() - 1;
|
|
@@ -1241,8 +1228,8 @@ var Session = /** @class */ (function () {
|
|
|
1241
1228
|
this.isSwitchingBackToV2L = false;
|
|
1242
1229
|
}
|
|
1243
1230
|
return [4 /*yield*/, this._sessionState.setValues(newSessionState)];
|
|
1244
|
-
case
|
|
1245
|
-
updatedValues =
|
|
1231
|
+
case 29:
|
|
1232
|
+
updatedValues = _g.sent();
|
|
1246
1233
|
sessionState = __assign(__assign({}, sessionState), updatedValues);
|
|
1247
1234
|
if (isLeader) {
|
|
1248
1235
|
debug("[".concat(this._sessionId, "]: I am the leader, updating PlayheadState values"));
|
|
@@ -1255,8 +1242,8 @@ var Session = /** @class */ (function () {
|
|
|
1255
1242
|
"vodMediaSeqAudio": sessionState.vodMediaSeqAudio,
|
|
1256
1243
|
"vodMediaSeqSubtitle": sessionState.vodMediaSeqSubtitle
|
|
1257
1244
|
}, isLeader)];
|
|
1258
|
-
case
|
|
1259
|
-
updatedPlayhead =
|
|
1245
|
+
case 30:
|
|
1246
|
+
updatedPlayhead = _g.sent();
|
|
1260
1247
|
playheadState = __assign(__assign({}, playheadState), updatedPlayhead);
|
|
1261
1248
|
if (currentVod.sequenceAlwaysContainNewSegments) {
|
|
1262
1249
|
mediaSequenceValue = currentVod.mediaSequenceValues[playheadState.vodMediaSeqVideo];
|
|
@@ -1268,23 +1255,23 @@ var Session = /** @class */ (function () {
|
|
|
1268
1255
|
debug("[".concat(this._sessionId, "]: Session can now serve mseq[V]={").concat(playheadState.mediaSeq + mediaSequenceValue, "}") + audioInfo);
|
|
1269
1256
|
}
|
|
1270
1257
|
debug("[".concat(this._sessionId, "]: INCREMENT (mseq=").concat(playheadState.mediaSeq + playheadState.vodMediaSeqVideo, ") vodMediaSeq=(").concat(playheadState.vodMediaSeqVideo, "_").concat(playheadState.vodMediaSeqAudio, " of ").concat(currentVod.getLiveMediaSequencesCount(), "_").concat(currentVod.getLiveMediaSequencesCount("audio"), ")"));
|
|
1271
|
-
if (!(playheadState.vodMediaSeqVideo < 2 || playheadState.mediaSeq !== this.prevMediaSeqOffset.video)) return [3 /*break*/,
|
|
1258
|
+
if (!(playheadState.vodMediaSeqVideo < 2 || playheadState.mediaSeq !== this.prevMediaSeqOffset.video)) return [3 /*break*/, 35];
|
|
1272
1259
|
debug("[".concat(this._sessionId, "]: current[").concat(playheadState.vodMediaSeqVideo, "]_prev[").concat(this.prevVodMediaSeq.video, "]"));
|
|
1273
1260
|
debug("[".concat(this._sessionId, "]: current-offset[").concat(playheadState.mediaSeq, "]_prev-offset[").concat(this.prevMediaSeqOffset.video, "]"));
|
|
1274
1261
|
if (playheadState.vodMediaSeqVideo < this.prevVodMediaSeq.video || playheadState.mediaSeq !== this.prevMediaSeqOffset.video) {
|
|
1275
1262
|
this.isAllowedToClearVodCache = true;
|
|
1276
1263
|
}
|
|
1277
|
-
if (!(!isLeader && this.isAllowedToClearVodCache)) return [3 /*break*/,
|
|
1264
|
+
if (!(!isLeader && this.isAllowedToClearVodCache)) return [3 /*break*/, 34];
|
|
1278
1265
|
debug("[".concat(this._sessionId, "]: Not a leader and have just set 'playheadState.vodMediaSeqVideo' to 0|1. Invalidate cache to ensure having the correct VOD."));
|
|
1279
1266
|
return [4 /*yield*/, this._sessionState.clearCurrentVodCache()];
|
|
1280
|
-
case
|
|
1281
|
-
|
|
1267
|
+
case 31:
|
|
1268
|
+
_g.sent();
|
|
1282
1269
|
return [4 /*yield*/, this._sessionState.getCurrentVod()];
|
|
1283
|
-
case
|
|
1284
|
-
currentVod =
|
|
1270
|
+
case 32:
|
|
1271
|
+
currentVod = _g.sent();
|
|
1285
1272
|
return [4 /*yield*/, this._playheadState.get("diffCompensation")];
|
|
1286
|
-
case
|
|
1287
|
-
diffMs =
|
|
1273
|
+
case 33:
|
|
1274
|
+
diffMs = _g.sent();
|
|
1288
1275
|
if (diffMs) {
|
|
1289
1276
|
this.diffCompensation = diffMs;
|
|
1290
1277
|
debug("[".concat(this._sessionId, "]: Setting diffCompensation->").concat(this.diffCompensation));
|
|
@@ -1297,12 +1284,12 @@ var Session = /** @class */ (function () {
|
|
|
1297
1284
|
}
|
|
1298
1285
|
}
|
|
1299
1286
|
this.isAllowedToClearVodCache = false;
|
|
1300
|
-
|
|
1301
|
-
case
|
|
1302
|
-
case
|
|
1287
|
+
_g.label = 34;
|
|
1288
|
+
case 34: return [3 /*break*/, 36];
|
|
1289
|
+
case 35:
|
|
1303
1290
|
this.isAllowedToClearVodCache = true;
|
|
1304
|
-
|
|
1305
|
-
case
|
|
1291
|
+
_g.label = 36;
|
|
1292
|
+
case 36:
|
|
1306
1293
|
// Update Value for Previous Sequence
|
|
1307
1294
|
this.prevVodMediaSeq.video = playheadState.vodMediaSeqVideo;
|
|
1308
1295
|
this.prevMediaSeqOffset.video = playheadState.mediaSeq;
|
|
@@ -1316,8 +1303,8 @@ var Session = /** @class */ (function () {
|
|
|
1316
1303
|
}
|
|
1317
1304
|
m3u8 = currentVod.getLiveMediaSequences(playheadState.mediaSeq, 180000, playheadState.vodMediaSeqVideo, sessionState.discSeq);
|
|
1318
1305
|
return [4 /*yield*/, this._playheadState.setLastM3u8(m3u8)];
|
|
1319
|
-
case
|
|
1320
|
-
|
|
1306
|
+
case 37:
|
|
1307
|
+
_g.sent();
|
|
1321
1308
|
return [2 /*return*/, m3u8];
|
|
1322
1309
|
}
|
|
1323
1310
|
});
|
|
@@ -1325,7 +1312,7 @@ var Session = /** @class */ (function () {
|
|
|
1325
1312
|
};
|
|
1326
1313
|
Session.prototype.getMediaManifestAsync = function (bw, opts) {
|
|
1327
1314
|
return __awaiter(this, void 0, void 0, function () {
|
|
1328
|
-
var tsLastRequestVideo, timeSinceLastRequest, sessionState, currentVod, _a, sequencesToIncrement, _b, _c, _d, m3u8, lastM3u8, _e, _f, _g, tsLastRequestVideo_1, timeSinceLastRequest_1,
|
|
1315
|
+
var tsLastRequestVideo, timeSinceLastRequest, sessionState, currentVod, _a, sequencesToIncrement, _b, _c, _d, m3u8, lastM3u8, _e, _f, _g, tsLastRequestVideo_1, timeSinceLastRequest_1, sessionState_1, _h, lastM3u8_1, _j, _k, _l;
|
|
1329
1316
|
return __generator(this, function (_m) {
|
|
1330
1317
|
switch (_m.label) {
|
|
1331
1318
|
case 0: // this function is no longer used and should be removed comment added 5/5-2023
|
|
@@ -1407,38 +1394,38 @@ var Session = /** @class */ (function () {
|
|
|
1407
1394
|
timeSinceLastRequest_1 = (tsLastRequestVideo_1 === null) ? 0 : Date.now() - tsLastRequestVideo_1;
|
|
1408
1395
|
return [4 /*yield*/, this._sessionState.getValues(["state", "vodMediaSeqVideo", "mediaSeq", "discSeq", "lastM3u8"])];
|
|
1409
1396
|
case 17:
|
|
1410
|
-
|
|
1411
|
-
if (!(
|
|
1412
|
-
_h =
|
|
1397
|
+
sessionState_1 = _m.sent();
|
|
1398
|
+
if (!(sessionState_1.state === SessionState.VOD_NEXT_INITIATING)) return [3 /*break*/, 19];
|
|
1399
|
+
_h = sessionState_1;
|
|
1413
1400
|
return [4 /*yield*/, this._sessionState.set("state", SessionState.VOD_PLAYING)];
|
|
1414
1401
|
case 18:
|
|
1415
1402
|
_h.state = _m.sent();
|
|
1416
1403
|
_m.label = 19;
|
|
1417
1404
|
case 19:
|
|
1418
|
-
debug("[".concat(this._sessionId, "]: VIDEO ").concat(timeSinceLastRequest_1, " (").concat(this.averageSegmentDuration, ") bandwidth=").concat(bw, " vodMediaSeq=(").concat(
|
|
1405
|
+
debug("[".concat(this._sessionId, "]: VIDEO ").concat(timeSinceLastRequest_1, " (").concat(this.averageSegmentDuration, ") bandwidth=").concat(bw, " vodMediaSeq=(").concat(sessionState_1.vodMediaSeqVideo, "_").concat(sessionState_1.vodMediaSeqAudio, ")"));
|
|
1419
1406
|
try {
|
|
1420
|
-
m3u8 = currentVod.getLiveMediaSequences(
|
|
1407
|
+
m3u8 = currentVod.getLiveMediaSequences(sessionState_1.mediaSeq, bw, sessionState_1.vodMediaSeqVideo, sessionState_1.discSeq);
|
|
1421
1408
|
}
|
|
1422
1409
|
catch (exc) {
|
|
1423
|
-
if (
|
|
1424
|
-
m3u8 =
|
|
1410
|
+
if (sessionState_1.lastM3u8[bw]) {
|
|
1411
|
+
m3u8 = sessionState_1.lastM3u8[bw];
|
|
1425
1412
|
}
|
|
1426
1413
|
else {
|
|
1427
1414
|
logerror(this._sessionId, exc);
|
|
1428
1415
|
throw new Error('Failed to generate media manifest');
|
|
1429
1416
|
}
|
|
1430
1417
|
}
|
|
1431
|
-
lastM3u8_1 =
|
|
1418
|
+
lastM3u8_1 = sessionState_1.lastM3u8;
|
|
1432
1419
|
lastM3u8_1[bw] = m3u8;
|
|
1433
|
-
_j =
|
|
1420
|
+
_j = sessionState_1;
|
|
1434
1421
|
return [4 /*yield*/, this._sessionState.set("lastM3u8", lastM3u8_1)];
|
|
1435
1422
|
case 20:
|
|
1436
1423
|
_j.lastM3u8 = _m.sent();
|
|
1437
|
-
_k =
|
|
1424
|
+
_k = sessionState_1;
|
|
1438
1425
|
return [4 /*yield*/, this._sessionState.set("lastServedM3u8", m3u8)];
|
|
1439
1426
|
case 21:
|
|
1440
1427
|
_k.lastServedM3u8 = _m.sent();
|
|
1441
|
-
_l =
|
|
1428
|
+
_l = sessionState_1;
|
|
1442
1429
|
return [4 /*yield*/, this._sessionState.set("tsLastRequestVideo", Date.now())];
|
|
1443
1430
|
case 22:
|
|
1444
1431
|
_l.tsLastRequestVideo = _m.sent();
|
|
@@ -1764,7 +1751,7 @@ var Session = /** @class */ (function () {
|
|
|
1764
1751
|
};
|
|
1765
1752
|
Session.prototype._tickAsync = function () {
|
|
1766
1753
|
return __awaiter(this, void 0, void 0, function () {
|
|
1767
|
-
var newVod, sessionState, isLeader, currentVod, vodResponse, _a, nextVodPromise, nextVodStart, _b, loadPromise, hlsOpts, _c, mediaManifestLoader, audioManifestLoader, loadStart, updatedSessionState, _d, _e, _f, _g, err_7, _h, length_1, endMseqValue, endMseqValueAudio, endMseqValueSubtitle, lastDiscontinuity, lastDiscontinuityAudio, lastDiscontinuitySubtitle, _j, vodPromise, gracePeriod, nextVodStart, _k, loadPromise, hlsOpts, _l, mediaManifestLoader, audioManifestLoader, loadStart, _m, _o, updatedSessionState, _p, _q, diffMs, err_8, startTS, _r, mSeq,
|
|
1754
|
+
var newVod, sessionState, isLeader, currentVod, vodResponse, _a, nextVodPromise, nextVodStart, _b, loadPromise, hlsOpts, _c, mediaManifestLoader, audioManifestLoader, loadStart, updatedSessionState, _d, _e, _f, _g, err_7, _h, length_1, endMseqValue, endMseqValueAudio, endMseqValueSubtitle, lastDiscontinuity, lastDiscontinuityAudio, lastDiscontinuitySubtitle, _j, vodPromise, gracePeriod, nextVodStart, _k, loadPromise, hlsOpts, _l, mediaManifestLoader, audioManifestLoader, loadStart, _m, _o, updatedSessionState, _p, _q, diffMs, err_8, startTS, _r, mSeq, currentVod_1, dSeq, mSeqOffset, reloadBehind, segments, playheadState, nextMseq, _s, _t, err_9;
|
|
1768
1755
|
var _this = this;
|
|
1769
1756
|
return __generator(this, function (_u) {
|
|
1770
1757
|
switch (_u.label) {
|
|
@@ -1870,6 +1857,7 @@ var Session = /** @class */ (function () {
|
|
|
1870
1857
|
debug("[".concat(this._sessionId, "]: ").concat(currentVod.getDeltaTimes()));
|
|
1871
1858
|
debug("[".concat(this._sessionId, "]: playhead positions [V]=").concat(currentVod.getPlayheadPositions("video")));
|
|
1872
1859
|
debug("[".concat(this._sessionId, "]: playhead positions [A]=").concat(currentVod.getPlayheadPositions("audio")));
|
|
1860
|
+
debug("[".concat(this._sessionId, "]: playhead positions [S]=").concat(currentVod.getPlayheadPositions("subtitle")));
|
|
1873
1861
|
return [4 /*yield*/, this._sessionState.setValues({
|
|
1874
1862
|
"mediaSeq": 0,
|
|
1875
1863
|
"mediaSeqAudio": 0,
|
|
@@ -2110,6 +2098,7 @@ var Session = /** @class */ (function () {
|
|
|
2110
2098
|
debug("[".concat(this._sessionId, "]: next VOD loaded (").concat(newVod.getDeltaTimes(), ")"));
|
|
2111
2099
|
debug("[".concat(this._sessionId, "]: playhead positions [V]=").concat(newVod.getPlayheadPositions("video")));
|
|
2112
2100
|
debug("[".concat(this._sessionId, "]: playhead positions [A]=").concat(newVod.getPlayheadPositions("audio")));
|
|
2101
|
+
debug("[".concat(this._sessionId, "]: playhead positions [S]=").concat(newVod.getPlayheadPositions("subtitle")));
|
|
2113
2102
|
currentVod = newVod;
|
|
2114
2103
|
debug("[".concat(this._sessionId, "]: msequences=").concat(currentVod.getLiveMediaSequencesCount(), "; audio msequences=").concat(currentVod.getLiveMediaSequencesCount("audio"), "; subtitle msequences=").concat(currentVod.getLiveMediaSequencesCount("subtitle")));
|
|
2115
2104
|
_m = sessionState;
|
|
@@ -2216,8 +2205,8 @@ var Session = /** @class */ (function () {
|
|
|
2216
2205
|
mSeq = this.switchDataForSession.mediaSeq;
|
|
2217
2206
|
return [4 /*yield*/, this._sessionState.getCurrentVod()];
|
|
2218
2207
|
case 63:
|
|
2219
|
-
|
|
2220
|
-
if (
|
|
2208
|
+
currentVod_1 = _u.sent();
|
|
2209
|
+
if (currentVod_1.sequenceAlwaysContainNewSegments) {
|
|
2221
2210
|
// (!) will need to compensate if using this setting on HLSVod Object.
|
|
2222
2211
|
Object.keys(this.switchDataForSession.transitionSegments).forEach(function (bw) {
|
|
2223
2212
|
var shiftedSeg = _this.switchDataForSession.transitionSegments[bw].shift();
|
|
@@ -2251,19 +2240,19 @@ var Session = /** @class */ (function () {
|
|
|
2251
2240
|
case 67:
|
|
2252
2241
|
playheadState = _u.sent();
|
|
2253
2242
|
nextMseq = playheadState.vodMediaSeqVideo + 1;
|
|
2254
|
-
if (nextMseq >
|
|
2255
|
-
nextMseq =
|
|
2243
|
+
if (nextMseq > currentVod_1.getLiveMediaSequencesCount() - 1) {
|
|
2244
|
+
nextMseq = currentVod_1.getLiveMediaSequencesCount() - 1;
|
|
2256
2245
|
}
|
|
2257
2246
|
// ---------------------------------------------------.
|
|
2258
2247
|
// TODO: Support reloading with audioSegments and SubtitleSegments as well |
|
|
2259
2248
|
// ---------------------------------------------------'
|
|
2260
|
-
return [4 /*yield*/,
|
|
2249
|
+
return [4 /*yield*/, currentVod_1.reload(nextMseq, segments, null, reloadBehind)];
|
|
2261
2250
|
case 68:
|
|
2262
2251
|
// ---------------------------------------------------.
|
|
2263
2252
|
// TODO: Support reloading with audioSegments and SubtitleSegments as well |
|
|
2264
2253
|
// ---------------------------------------------------'
|
|
2265
2254
|
_u.sent();
|
|
2266
|
-
return [4 /*yield*/, this._sessionState.setCurrentVod(
|
|
2255
|
+
return [4 /*yield*/, this._sessionState.setCurrentVod(currentVod_1, { ttl: currentVod_1.getDuration() * 1000 })];
|
|
2267
2256
|
case 69:
|
|
2268
2257
|
_u.sent();
|
|
2269
2258
|
return [4 /*yield*/, this._sessionState.set("vodReloaded", 1)];
|
|
@@ -2293,9 +2282,9 @@ var Session = /** @class */ (function () {
|
|
|
2293
2282
|
_s.currentPlayheadRef = _u.sent();
|
|
2294
2283
|
// 4) Log to debug and cloudwatch
|
|
2295
2284
|
debug("[".concat(this._sessionId, "]: LEADER: Set new Reloaded VOD and vodMediaSeq counts in store."));
|
|
2296
|
-
debug("[".concat(this._sessionId, "]: next VOD Reloaded (").concat(
|
|
2297
|
-
debug("[".concat(this._sessionId, "]: ").concat(
|
|
2298
|
-
debug("[".concat(this._sessionId, "]: msequences=").concat(
|
|
2285
|
+
debug("[".concat(this._sessionId, "]: next VOD Reloaded (").concat(currentVod_1.getDeltaTimes(), ")"));
|
|
2286
|
+
debug("[".concat(this._sessionId, "]: ").concat(currentVod_1.getPlayheadPositions()));
|
|
2287
|
+
debug("[".concat(this._sessionId, "]: msequences=").concat(currentVod_1.getLiveMediaSequencesCount()));
|
|
2299
2288
|
cloudWatchLog(!this.cloudWatchLogging, "engine-session", { event: "switchback", channel: this._sessionId, reqTimeMs: Date.now() - startTS });
|
|
2300
2289
|
return [2 /*return*/];
|
|
2301
2290
|
case 78:
|
|
@@ -2727,6 +2716,50 @@ var Session = /** @class */ (function () {
|
|
|
2727
2716
|
}
|
|
2728
2717
|
return false;
|
|
2729
2718
|
};
|
|
2719
|
+
Session.prototype._determineExtraMediaIncrement = function (_extraType, _currentPosVideo, _extraSeqFinalIndex, _vodMediaSeqExtra, _getExtraPlayheadPositionAsyncFn) {
|
|
2720
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
2721
|
+
var extraMediaIncrement, positionV, positionX, posDiff, threshold, currentPosExtraMedia, difference;
|
|
2722
|
+
return __generator(this, function (_a) {
|
|
2723
|
+
switch (_a.label) {
|
|
2724
|
+
case 0:
|
|
2725
|
+
debug("[".concat(this._sessionId, "]: About to determine ").concat(_extraType, " increment. Video increment has already been executed."));
|
|
2726
|
+
extraMediaIncrement = 0;
|
|
2727
|
+
positionV = _currentPosVideo ? _currentPosVideo / 1000 : 0;
|
|
2728
|
+
threshold = 0.250;
|
|
2729
|
+
_a.label = 1;
|
|
2730
|
+
case 1:
|
|
2731
|
+
if (!(extraMediaIncrement < _extraSeqFinalIndex)) return [3 /*break*/, 3];
|
|
2732
|
+
return [4 /*yield*/, _getExtraPlayheadPositionAsyncFn(_vodMediaSeqExtra + extraMediaIncrement)];
|
|
2733
|
+
case 2:
|
|
2734
|
+
currentPosExtraMedia = (_a.sent()) * 1000;
|
|
2735
|
+
positionX = currentPosExtraMedia ? currentPosExtraMedia / 1000 : 0;
|
|
2736
|
+
posDiff = (positionV - positionX).toFixed(3);
|
|
2737
|
+
debug("[".concat(this._sessionId, "]: positionV=").concat(positionV, ";position").concat(_extraType === "audio" ? "A" : "S", "=").concat(positionX, ";posDiff=").concat(posDiff));
|
|
2738
|
+
if (isNaN(posDiff)) {
|
|
2739
|
+
return [3 /*break*/, 3];
|
|
2740
|
+
}
|
|
2741
|
+
if (positionX >= positionV) {
|
|
2742
|
+
return [3 /*break*/, 3];
|
|
2743
|
+
}
|
|
2744
|
+
difference = Math.abs(posDiff);
|
|
2745
|
+
if (difference > threshold && difference > Number.EPSILON) {
|
|
2746
|
+
// Video position ahead of audio|sub position, further increment needed...
|
|
2747
|
+
extraMediaIncrement++;
|
|
2748
|
+
}
|
|
2749
|
+
else {
|
|
2750
|
+
debug("[".concat(this._sessionId, "]: Difference(").concat(difference, ") is acceptable; IncrementValue=").concat(extraMediaIncrement));
|
|
2751
|
+
return [3 /*break*/, 3];
|
|
2752
|
+
}
|
|
2753
|
+
return [3 /*break*/, 1];
|
|
2754
|
+
case 3: return [2 /*return*/, {
|
|
2755
|
+
increment: extraMediaIncrement,
|
|
2756
|
+
position: positionX,
|
|
2757
|
+
diff: posDiff
|
|
2758
|
+
}];
|
|
2759
|
+
}
|
|
2760
|
+
});
|
|
2761
|
+
});
|
|
2762
|
+
};
|
|
2730
2763
|
return Session;
|
|
2731
2764
|
}());
|
|
2732
2765
|
module.exports = Session;
|
package/dist/package.json
CHANGED
package/engine/session.js
CHANGED
|
@@ -834,51 +834,51 @@ class Session {
|
|
|
834
834
|
}
|
|
835
835
|
} else {
|
|
836
836
|
sessionState.vodMediaSeqVideo = await this._sessionState.increment("vodMediaSeqVideo", 1);
|
|
837
|
-
let
|
|
837
|
+
let playheadPosVideoMs;
|
|
838
|
+
let playheadAudio;
|
|
839
|
+
let playheadSubtitle;
|
|
840
|
+
if (this.use_demuxed_audio || this.use_vtt_subtitles) {
|
|
841
|
+
playheadPosVideoMs = (await this._getCurrentPlayheadPosition()) * 1000;
|
|
842
|
+
}
|
|
843
|
+
|
|
838
844
|
if (this.use_demuxed_audio) {
|
|
839
|
-
let positionV = 0;
|
|
840
|
-
let positionA = 0;
|
|
841
|
-
const position = (await this._getCurrentPlayheadPosition()) * 1000;
|
|
842
|
-
positionV = position ? position / 1000 : 0;
|
|
843
|
-
let currentVod = await this._sessionState.getCurrentVod();
|
|
844
|
-
const sessionState = await this._sessionState.getValues(["vodMediaSeqAudio"]);
|
|
845
|
-
let posDiff;
|
|
846
|
-
let incrementValue = 1;
|
|
847
|
-
let index = 0;
|
|
848
845
|
const audioSeqLastIdx = currentVod.getLiveMediaSequencesCount("audio") - 1;
|
|
849
|
-
const
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
if (posDiff > thresh) {
|
|
861
|
-
index++;
|
|
862
|
-
incrementValue++;
|
|
863
|
-
} else if (posDiff > maxAcceptableDiff) {
|
|
864
|
-
index = incrementValue;
|
|
865
|
-
debug(`[${this._sessionId}]: Audio Stepping index set to = ${index}`);
|
|
866
|
-
break;
|
|
867
|
-
}
|
|
868
|
-
if (sessionState.vodMediaSeqAudio + index > audioSeqLastIdx) {
|
|
869
|
-
break;
|
|
870
|
-
}
|
|
871
|
-
} while (!(-thresh < posDiff && posDiff < thresh) && !isNaN(posDiff));
|
|
872
|
-
audioIncrement = index;
|
|
873
|
-
debug(`[${this._sessionId}]: Current VOD Playhead Positions are to be: [${positionV.toFixed(3)}][${positionA.toFixed(3)}] (${posDiff})`);
|
|
846
|
+
const sessionStateObj = await this._sessionState.getValues(["vodMediaSeqAudio"]);
|
|
847
|
+
playheadAudio = await this._determineExtraMediaIncrement(
|
|
848
|
+
"audio",
|
|
849
|
+
playheadPosVideoMs,
|
|
850
|
+
audioSeqLastIdx,
|
|
851
|
+
sessionStateObj.vodMediaSeqAudio,
|
|
852
|
+
this._getAudioPlayheadPosition.bind(this)
|
|
853
|
+
);
|
|
854
|
+
// Perform the Increment
|
|
855
|
+
debug(`[${this._sessionId}]: Will increment audio with ${playheadAudio.increment}`);
|
|
856
|
+
sessionState.vodMediaSeqAudio = await this._sessionState.increment("vodMediaSeqAudio", playheadAudio.increment);
|
|
874
857
|
}
|
|
875
|
-
debug(`[${this._sessionId}]: Will increment audio with ${audioIncrement}`);
|
|
876
|
-
sessionState.vodMediaSeqAudio = await this._sessionState.increment("vodMediaSeqAudio", audioIncrement);
|
|
877
|
-
|
|
878
858
|
if (this.use_vtt_subtitles) {
|
|
879
|
-
|
|
880
|
-
|
|
859
|
+
const playheadPosVideo = playheadPosVideo || (await this._getCurrentPlayheadPosition()) * 1000;
|
|
860
|
+
const subtitleSeqLastIdx = currentVod.getLiveMediaSequencesCount("subtitle") - 1;
|
|
861
|
+
const sessionStateObj = await this._sessionState.getValues(["vodMediaSeqSubtitle"]);
|
|
862
|
+
playheadSubtitle = await this._determineExtraMediaIncrement(
|
|
863
|
+
"subtitle",
|
|
864
|
+
playheadPosVideoMs,
|
|
865
|
+
subtitleSeqLastIdx,
|
|
866
|
+
sessionStateObj.vodMediaSeqSubtitle,
|
|
867
|
+
this._getSubtitlePlayheadPosition.bind(this)
|
|
868
|
+
);
|
|
869
|
+
// Perform the Increment
|
|
870
|
+
debug(`[${this._sessionId}]: Will increment subtitle with ${playheadSubtitle.increment}`);
|
|
871
|
+
sessionState.vodMediaSeqSubtitle = await this._sessionState.increment("vodMediaSeqSubtitle", playheadSubtitle.increment);
|
|
881
872
|
}
|
|
873
|
+
debug(`[${this._sessionId}]: Current VOD Playhead Positions are to be V[${(playheadPosVideoMs/1000).toFixed(3)}]${
|
|
874
|
+
playheadAudio ? `A[${(playheadAudio.position).toFixed(3)}]` : ""
|
|
875
|
+
}${
|
|
876
|
+
playheadSubtitle ? `S[${(playheadSubtitle.position).toFixed(3)})]` : ""
|
|
877
|
+
}${
|
|
878
|
+
playheadAudio ? ` (${playheadAudio.diff})` : ""
|
|
879
|
+
}${
|
|
880
|
+
playheadSubtitle ? ` (${playheadSubtitle.diff})` : ""
|
|
881
|
+
}`);
|
|
882
882
|
}
|
|
883
883
|
|
|
884
884
|
let newSessionState = {};
|
|
@@ -1388,6 +1388,7 @@ class Session {
|
|
|
1388
1388
|
debug(`[${this._sessionId}]: ${currentVod.getDeltaTimes()}`);
|
|
1389
1389
|
debug(`[${this._sessionId}]: playhead positions [V]=${currentVod.getPlayheadPositions("video")}`);
|
|
1390
1390
|
debug(`[${this._sessionId}]: playhead positions [A]=${currentVod.getPlayheadPositions("audio")}`);
|
|
1391
|
+
debug(`[${this._sessionId}]: playhead positions [S]=${currentVod.getPlayheadPositions("subtitle")}`);
|
|
1391
1392
|
//debug(newVod);
|
|
1392
1393
|
const updatedSessionState = await this._sessionState.setValues({
|
|
1393
1394
|
"mediaSeq": 0,
|
|
@@ -1584,6 +1585,7 @@ class Session {
|
|
|
1584
1585
|
debug(`[${this._sessionId}]: next VOD loaded (${newVod.getDeltaTimes()})`);
|
|
1585
1586
|
debug(`[${this._sessionId}]: playhead positions [V]=${newVod.getPlayheadPositions("video")}`);
|
|
1586
1587
|
debug(`[${this._sessionId}]: playhead positions [A]=${newVod.getPlayheadPositions("audio")}`);
|
|
1588
|
+
debug(`[${this._sessionId}]: playhead positions [S]=${newVod.getPlayheadPositions("subtitle")}`);
|
|
1587
1589
|
currentVod = newVod;
|
|
1588
1590
|
debug(`[${this._sessionId}]: msequences=${currentVod.getLiveMediaSequencesCount()}; audio msequences=${currentVod.getLiveMediaSequencesCount("audio")}; subtitle msequences=${currentVod.getLiveMediaSequencesCount("subtitle")}`);
|
|
1589
1591
|
sessionState.currentVod = await this._sessionState.setCurrentVod(currentVod, { ttl: currentVod.getDuration() * 1000 });
|
|
@@ -2089,6 +2091,40 @@ class Session {
|
|
|
2089
2091
|
}
|
|
2090
2092
|
return false;
|
|
2091
2093
|
}
|
|
2094
|
+
|
|
2095
|
+
async _determineExtraMediaIncrement(_extraType, _currentPosVideo, _extraSeqFinalIndex, _vodMediaSeqExtra, _getExtraPlayheadPositionAsyncFn) {
|
|
2096
|
+
debug(`[${this._sessionId}]: About to determine ${_extraType} increment. Video increment has already been executed.`);
|
|
2097
|
+
let extraMediaIncrement = 0;
|
|
2098
|
+
let positionV = _currentPosVideo ? _currentPosVideo / 1000 : 0;
|
|
2099
|
+
let positionX;
|
|
2100
|
+
let posDiff;
|
|
2101
|
+
const threshold = 0.250;
|
|
2102
|
+
while (extraMediaIncrement < _extraSeqFinalIndex) {
|
|
2103
|
+
const currentPosExtraMedia = (await _getExtraPlayheadPositionAsyncFn(_vodMediaSeqExtra + extraMediaIncrement)) * 1000;
|
|
2104
|
+
positionX = currentPosExtraMedia ? currentPosExtraMedia / 1000 : 0;
|
|
2105
|
+
posDiff = (positionV - positionX).toFixed(3);
|
|
2106
|
+
debug(`[${this._sessionId}]: positionV=${positionV};position${_extraType === "audio" ? "A" : "S"}=${positionX};posDiff=${posDiff}`);
|
|
2107
|
+
if (isNaN(posDiff)) {
|
|
2108
|
+
break;
|
|
2109
|
+
}
|
|
2110
|
+
if (positionX >= positionV) {
|
|
2111
|
+
break;
|
|
2112
|
+
}
|
|
2113
|
+
const difference = Math.abs(posDiff);
|
|
2114
|
+
if (difference > threshold && difference > Number.EPSILON) {
|
|
2115
|
+
// Video position ahead of audio|sub position, further increment needed...
|
|
2116
|
+
extraMediaIncrement++;
|
|
2117
|
+
} else {
|
|
2118
|
+
debug(`[${this._sessionId}]: Difference(${difference}) is acceptable; IncrementValue=${extraMediaIncrement}`);
|
|
2119
|
+
break;
|
|
2120
|
+
}
|
|
2121
|
+
}
|
|
2122
|
+
return {
|
|
2123
|
+
increment: extraMediaIncrement,
|
|
2124
|
+
position: positionX,
|
|
2125
|
+
diff: posDiff
|
|
2126
|
+
};
|
|
2127
|
+
}
|
|
2092
2128
|
}
|
|
2093
2129
|
|
|
2094
2130
|
module.exports = Session;
|
package/package.json
CHANGED
|
@@ -1,20 +1,116 @@
|
|
|
1
|
-
const Session = require(
|
|
1
|
+
const Session = require("../../engine/session.js");
|
|
2
2
|
|
|
3
|
-
const { SessionStateStore } = require(
|
|
4
|
-
const { PlayheadStateStore } = require(
|
|
3
|
+
const { SessionStateStore } = require("../../engine/session_state.js");
|
|
4
|
+
const { PlayheadStateStore } = require("../../engine/playhead_state.js");
|
|
5
5
|
|
|
6
6
|
describe("Session", () => {
|
|
7
7
|
let sessionLiveStore = undefined;
|
|
8
8
|
beforeEach(() => {
|
|
9
9
|
sessionLiveStore = {
|
|
10
10
|
sessionStateStore: new SessionStateStore(),
|
|
11
|
-
playheadStateStore: new PlayheadStateStore()
|
|
12
|
-
};
|
|
11
|
+
playheadStateStore: new PlayheadStateStore(),
|
|
12
|
+
};
|
|
13
13
|
});
|
|
14
14
|
|
|
15
15
|
it("creates a unique session ID", () => {
|
|
16
|
-
const id1 = new Session(
|
|
17
|
-
const id2 = new Session(
|
|
16
|
+
const id1 = new Session("dummy", null, sessionLiveStore).sessionId;
|
|
17
|
+
const id2 = new Session("dummy", null, sessionLiveStore).sessionId;
|
|
18
18
|
expect(id1).not.toEqual(id2);
|
|
19
19
|
});
|
|
20
|
-
|
|
20
|
+
|
|
21
|
+
it("for demuxed, returns the appropriate audio increment value when desync is within acceptable limit, case I", async () => {
|
|
22
|
+
const session = new Session("dummy", null, sessionLiveStore);
|
|
23
|
+
const mockFinalAudioIdx = 50; // current Vod has 50 media sequences to serve.
|
|
24
|
+
const mockCurrentVideoPosition = 200.0 * 1000; // Video is 200s deep into its content.
|
|
25
|
+
const mockMseqAudio = 25; // current mseq for audio on vod, 25 out of 50.
|
|
26
|
+
const mock_getAudioPlayheadPosition = async (pos_n_current) => {
|
|
27
|
+
const mockPositions = [196.0, 199.84, 203.68, 207.52];
|
|
28
|
+
return mockPositions[pos_n_current - mockMseqAudio];
|
|
29
|
+
};
|
|
30
|
+
const output = await session._determineExtraMediaIncrement(
|
|
31
|
+
"audio",
|
|
32
|
+
mockCurrentVideoPosition,
|
|
33
|
+
mockFinalAudioIdx,
|
|
34
|
+
mockMseqAudio,
|
|
35
|
+
mock_getAudioPlayheadPosition,
|
|
36
|
+
24
|
|
37
|
+
);
|
|
38
|
+
expect(output.increment).toBe(1);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it("for demuxed, returns the appropriate audio increment value when desync is within acceptable limit, case II", async () => {
|
|
42
|
+
const session = new Session("dummy", null, sessionLiveStore);
|
|
43
|
+
const mockFinalAudioIdx = 50; // current Vod has 50 media sequences to serve.
|
|
44
|
+
const mockCurrentVideoPosition = 200.0 * 1000; // Video is 200s deep into its content.
|
|
45
|
+
const mockMseqAudio = 25; // current mseq for audio on vod, 25 out of 50.
|
|
46
|
+
const mock_getAudioPlayheadPosition = async (pos_n_current) => {
|
|
47
|
+
const mockPositions = [192.16, 196.0, 199.84, 203.68, 207.52];
|
|
48
|
+
return mockPositions[pos_n_current - mockMseqAudio];
|
|
49
|
+
};
|
|
50
|
+
const output = await session._determineExtraMediaIncrement(
|
|
51
|
+
"audio",
|
|
52
|
+
mockCurrentVideoPosition,
|
|
53
|
+
mockFinalAudioIdx,
|
|
54
|
+
mockMseqAudio,
|
|
55
|
+
mock_getAudioPlayheadPosition,
|
|
56
|
+
24
|
|
57
|
+
);
|
|
58
|
+
expect(output.increment).toBe(2);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it("for demuxed, returns the appropriate audio increment value when they are in sync but there is a floating point error", async () => {
|
|
62
|
+
const session = new Session("dummy", null, sessionLiveStore);
|
|
63
|
+
const mockFinalAudioIdx = 50;
|
|
64
|
+
const mockCurrentVideoPosition = 441.7599999999981697 * 1000;
|
|
65
|
+
const mockMseqAudio = 25;
|
|
66
|
+
const mock_getAudioPlayheadPosition = async (pos_n_current) => {
|
|
67
|
+
const mockPositions = [437.919999999999, 441.75999999999897];
|
|
68
|
+
return mockPositions[pos_n_current - mockMseqAudio];
|
|
69
|
+
};
|
|
70
|
+
const output = await session._determineExtraMediaIncrement(
|
|
71
|
+
"audio",
|
|
72
|
+
mockCurrentVideoPosition,
|
|
73
|
+
mockFinalAudioIdx,
|
|
74
|
+
mockMseqAudio,
|
|
75
|
+
mock_getAudioPlayheadPosition,
|
|
76
|
+
24
|
|
77
|
+
);
|
|
78
|
+
expect(output.increment).toBe(1);
|
|
79
|
+
});
|
|
80
|
+
it("for demuxed, returns the appropriate audio increment value, normal case I", async () => {
|
|
81
|
+
const session = new Session("dummy", null, sessionLiveStore);
|
|
82
|
+
const mockFinalAudioIdx = 50;
|
|
83
|
+
const mockCurrentVideoPosition = 3.840 * 8 * 1000;
|
|
84
|
+
const mockMseqAudio = 5;
|
|
85
|
+
const mock_getAudioPlayheadPosition = async (pos_n_current) => {
|
|
86
|
+
const mockPositions = [0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52];
|
|
87
|
+
return mockPositions[pos_n_current];
|
|
88
|
+
};
|
|
89
|
+
const output = await session._determineExtraMediaIncrement(
|
|
90
|
+
"audio",
|
|
91
|
+
mockCurrentVideoPosition,
|
|
92
|
+
mockFinalAudioIdx,
|
|
93
|
+
mockMseqAudio,
|
|
94
|
+
mock_getAudioPlayheadPosition
|
|
95
|
+
);
|
|
96
|
+
expect(output.increment).toBe(3);
|
|
97
|
+
});
|
|
98
|
+
it("for demuxed, returns the appropriate audio increment value, normal case II", async () => {
|
|
99
|
+
const session = new Session("dummy", null, sessionLiveStore);
|
|
100
|
+
const mockFinalAudioIdx = 50;
|
|
101
|
+
const mockCurrentVideoPosition = 14 * 1000;
|
|
102
|
+
const mockMseqAudio = 0;
|
|
103
|
+
const mock_getAudioPlayheadPosition = async (pos_n_current) => {
|
|
104
|
+
const mockPositions = [0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52];
|
|
105
|
+
return mockPositions[pos_n_current];
|
|
106
|
+
};
|
|
107
|
+
const output = await session._determineExtraMediaIncrement(
|
|
108
|
+
"subtitle",
|
|
109
|
+
mockCurrentVideoPosition,
|
|
110
|
+
mockFinalAudioIdx,
|
|
111
|
+
mockMseqAudio,
|
|
112
|
+
mock_getAudioPlayheadPosition
|
|
113
|
+
);
|
|
114
|
+
expect(output.increment).toBe(4);
|
|
115
|
+
});
|
|
116
|
+
});
|