eyevinn-channel-engine 4.0.4 → 4.0.6
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/server.js +1 -1
- package/dist/engine/session.d.ts +1 -1
- package/dist/engine/session.js +161 -174
- package/dist/package.json +1 -1
- package/engine/server.ts +1 -1
- package/engine/session.js +51 -67
- package/package.json +1 -1
package/dist/engine/server.js
CHANGED
|
@@ -818,7 +818,7 @@ var ChannelEngine = /** @class */ (function () {
|
|
|
818
818
|
"Access-Control-Allow-Origin": "*",
|
|
819
819
|
"Access-Control-Allow-Headers": "X-Session-Id",
|
|
820
820
|
"Access-Control-Expose-Headers": "X-Session-Id",
|
|
821
|
-
"Cache-Control": "
|
|
821
|
+
"Cache-Control": "max-age=300",
|
|
822
822
|
"X-Session-Id": session.sessionId,
|
|
823
823
|
"X-Instance-Id": this.instanceId + "<".concat(version, ">"),
|
|
824
824
|
});
|
package/dist/engine/session.d.ts
CHANGED
|
@@ -87,7 +87,7 @@ declare class Session {
|
|
|
87
87
|
}>;
|
|
88
88
|
getCurrentMediaManifestAsync(bw: any, playbackSessionId: any): Promise<any>;
|
|
89
89
|
getCurrentAudioManifestAsync(audioGroupId: any, audioLanguage: any, playbackSessionId: any): Promise<any>;
|
|
90
|
-
incrementAsync(
|
|
90
|
+
incrementAsync(): Promise<any>;
|
|
91
91
|
getMediaManifestAsync(bw: any, opts: any): Promise<any>;
|
|
92
92
|
getAudioManifestAsync(audioGroupId: any, audioLanguage: any, opts: any): Promise<any>;
|
|
93
93
|
getMasterManifestAsync(filter: any): Promise<string>;
|
package/dist/engine/session.js
CHANGED
|
@@ -193,7 +193,7 @@ var Session = /** @class */ (function () {
|
|
|
193
193
|
});
|
|
194
194
|
Session.prototype.startPlayheadAsync = function () {
|
|
195
195
|
return __awaiter(this, void 0, void 0, function () {
|
|
196
|
-
var playheadState, state, numberOfLargeTicks, audioIncrement, tsIncrementBegin, manifest, tsIncrementEnd, sessionState, isLeader, firstDuration, tickInterval, reqTickInterval, timeSpentInIncrement, tickInterval, delta, position,
|
|
196
|
+
var playheadState, state, numberOfLargeTicks, audioIncrement, tsIncrementBegin, manifest, tsIncrementEnd, sessionState, isLeader, firstDuration, tickInterval, reqTickInterval, timeSpentInIncrement, tickInterval, delta, position, timePosition, diff, timeToAdd, timeToAdd, DIFF_COMPENSATION, changeMaxTick, tsTickEnd, lastDuration, nextTickInterval, err_1;
|
|
197
197
|
return __generator(this, function (_a) {
|
|
198
198
|
switch (_a.label) {
|
|
199
199
|
case 0:
|
|
@@ -212,14 +212,12 @@ var Session = /** @class */ (function () {
|
|
|
212
212
|
audioIncrement = 1;
|
|
213
213
|
_a.label = 3;
|
|
214
214
|
case 3:
|
|
215
|
-
if (!(state !== PlayheadState.CRASHED)) return [3 /*break*/,
|
|
215
|
+
if (!(state !== PlayheadState.CRASHED)) return [3 /*break*/, 25];
|
|
216
216
|
_a.label = 4;
|
|
217
217
|
case 4:
|
|
218
|
-
_a.trys.push([4,
|
|
218
|
+
_a.trys.push([4, 22, , 24]);
|
|
219
219
|
tsIncrementBegin = Date.now();
|
|
220
|
-
return [4 /*yield*/, this.incrementAsync(
|
|
221
|
-
audio: audioIncrement
|
|
222
|
-
})];
|
|
220
|
+
return [4 /*yield*/, this.incrementAsync()];
|
|
223
221
|
case 5:
|
|
224
222
|
manifest = _a.sent();
|
|
225
223
|
if (!!manifest) return [3 /*break*/, 7];
|
|
@@ -256,7 +254,7 @@ var Session = /** @class */ (function () {
|
|
|
256
254
|
debug("[".concat(this._sessionId, "]: I am the leader and updated tick interval to ").concat(tickInterval, " sec"));
|
|
257
255
|
cloudWatchLog(!this.cloudWatchLogging, 'engine-session', { event: 'tickIntervalUpdated', channel: this._sessionId, tickIntervalSec: tickInterval });
|
|
258
256
|
this._playheadState.set("tickInterval", tickInterval);
|
|
259
|
-
return [3 /*break*/,
|
|
257
|
+
return [3 /*break*/, 21];
|
|
260
258
|
case 13:
|
|
261
259
|
if (!(state == PlayheadState.STOPPED)) return [3 /*break*/, 14];
|
|
262
260
|
debug("[".concat(this._sessionId, "]: Stopping playhead"));
|
|
@@ -275,49 +273,6 @@ var Session = /** @class */ (function () {
|
|
|
275
273
|
return [4 /*yield*/, this._getCurrentPlayheadPosition()];
|
|
276
274
|
case 16:
|
|
277
275
|
position = (_a.sent()) * 1000;
|
|
278
|
-
if (!this.use_demuxed_audio) return [3 /*break*/, 23];
|
|
279
|
-
return [4 /*yield*/, this._sessionState.getCurrentVod()];
|
|
280
|
-
case 17:
|
|
281
|
-
currentVod = _a.sent();
|
|
282
|
-
return [4 /*yield*/, this._sessionState.getValues(["vodMediaSeqAudio"])];
|
|
283
|
-
case 18:
|
|
284
|
-
sessionState_1 = _a.sent();
|
|
285
|
-
posDiff = void 0;
|
|
286
|
-
incrementValue = 1;
|
|
287
|
-
index = 0;
|
|
288
|
-
audioSeqLastIdx = currentVod.getLiveMediaSequencesCount("audio") - 1;
|
|
289
|
-
thresh = 0.5;
|
|
290
|
-
direction = 0;
|
|
291
|
-
_a.label = 19;
|
|
292
|
-
case 19: return [4 /*yield*/, this._getAudioPlayheadPosition(sessionState_1.vodMediaSeqAudio + index)];
|
|
293
|
-
case 20:
|
|
294
|
-
audioPosition = (_a.sent()) * 1000;
|
|
295
|
-
posDiff = position - audioPosition;
|
|
296
|
-
if (posDiff > thresh && direction >= 0) {
|
|
297
|
-
index++;
|
|
298
|
-
incrementValue++;
|
|
299
|
-
direction = 1;
|
|
300
|
-
}
|
|
301
|
-
else if (posDiff < -thresh && direction <= 0) {
|
|
302
|
-
incrementValue = 0;
|
|
303
|
-
index--;
|
|
304
|
-
direction = -1;
|
|
305
|
-
return [3 /*break*/, 22];
|
|
306
|
-
}
|
|
307
|
-
else if (direction > 0 && posDiff < 0) {
|
|
308
|
-
return [3 /*break*/, 22];
|
|
309
|
-
}
|
|
310
|
-
if (sessionState_1.vodMediaSeqAudio + index > audioSeqLastIdx || sessionState_1.vodMediaSeqAudio + index < 0) {
|
|
311
|
-
return [3 /*break*/, 22];
|
|
312
|
-
}
|
|
313
|
-
_a.label = 21;
|
|
314
|
-
case 21:
|
|
315
|
-
if (!(-thresh < posDiff && posDiff < thresh)) return [3 /*break*/, 19];
|
|
316
|
-
_a.label = 22;
|
|
317
|
-
case 22:
|
|
318
|
-
audioIncrement = incrementValue;
|
|
319
|
-
_a.label = 23;
|
|
320
|
-
case 23:
|
|
321
276
|
timePosition = Date.now() - playheadState.playheadRef;
|
|
322
277
|
// Apply time position offset if set, only after external diff compensation has concluded.
|
|
323
278
|
if (this.timePositionOffset && this.diffCompensation <= 0 && this.alwaysNewSegments) {
|
|
@@ -368,36 +323,36 @@ var Session = /** @class */ (function () {
|
|
|
368
323
|
}
|
|
369
324
|
debug("[".concat(this._sessionId, "]: (").concat((new Date()).toISOString(), ") ").concat(timeSpentInIncrement, "sec in increment. Next tick in ").concat(tickInterval, " seconds"));
|
|
370
325
|
return [4 /*yield*/, timer((tickInterval * 1000) - 50)];
|
|
371
|
-
case
|
|
326
|
+
case 17:
|
|
372
327
|
_a.sent();
|
|
373
328
|
tsTickEnd = Date.now();
|
|
374
329
|
return [4 /*yield*/, this._playheadState.set("tickMs", (tsTickEnd - tsIncrementBegin))];
|
|
375
|
-
case
|
|
330
|
+
case 18:
|
|
376
331
|
_a.sent();
|
|
377
332
|
cloudWatchLog(!this.cloudWatchLogging, 'engine-session', { event: 'tickInterval', channel: this._sessionId, tickTimeMs: (tsTickEnd - tsIncrementBegin) });
|
|
378
|
-
if (!this.alwaysNewSegments) return [3 /*break*/,
|
|
333
|
+
if (!this.alwaysNewSegments) return [3 /*break*/, 21];
|
|
379
334
|
return [4 /*yield*/, this._getLastDuration(manifest)];
|
|
380
|
-
case
|
|
335
|
+
case 19:
|
|
381
336
|
lastDuration = _a.sent();
|
|
382
337
|
nextTickInterval = lastDuration < 2 ? 2 : lastDuration;
|
|
383
338
|
return [4 /*yield*/, this._playheadState.set("tickInterval", nextTickInterval)];
|
|
384
|
-
case
|
|
339
|
+
case 20:
|
|
385
340
|
_a.sent();
|
|
386
341
|
cloudWatchLog(!this.cloudWatchLogging, "engine-session", { event: "tickIntervalUpdated", channel: this._sessionId, tickIntervalSec: nextTickInterval });
|
|
387
|
-
_a.label =
|
|
388
|
-
case
|
|
389
|
-
case
|
|
342
|
+
_a.label = 21;
|
|
343
|
+
case 21: return [3 /*break*/, 24];
|
|
344
|
+
case 22:
|
|
390
345
|
err_1 = _a.sent();
|
|
391
346
|
debug("[".concat(this._sessionId, "]: Playhead consumer crashed (1)"));
|
|
392
347
|
console.error("[".concat(this._sessionId, "]: ").concat(err_1.message));
|
|
393
348
|
cloudWatchLog(!this.cloudWatchLogging, 'engine-session', { event: 'error', on: 'playhead', channel: this._sessionId, err: err_1 });
|
|
394
349
|
debug(err_1);
|
|
395
350
|
return [4 /*yield*/, this._playheadState.setState(PlayheadState.CRASHED)];
|
|
396
|
-
case
|
|
351
|
+
case 23:
|
|
397
352
|
state = _a.sent();
|
|
398
|
-
return [3 /*break*/,
|
|
399
|
-
case
|
|
400
|
-
case
|
|
353
|
+
return [3 /*break*/, 24];
|
|
354
|
+
case 24: return [3 /*break*/, 3];
|
|
355
|
+
case 25: return [2 /*return*/];
|
|
401
356
|
}
|
|
402
357
|
});
|
|
403
358
|
});
|
|
@@ -786,7 +741,7 @@ var Session = /** @class */ (function () {
|
|
|
786
741
|
};
|
|
787
742
|
Session.prototype.getCurrentMediaManifestAsync = function (bw, playbackSessionId) {
|
|
788
743
|
return __awaiter(this, void 0, void 0, function () {
|
|
789
|
-
var tries, sessionState, playheadState, state, isLeader, diffMs, currentVod, manifestMseq, manifestDseq, mediaSequenceValue, m3u8_1, err_4;
|
|
744
|
+
var tries, sessionState, playheadState, state, DELAY_TIME_MS, ACTION, isLeader, diffMs, currentVod, manifestMseq, manifestDseq, mediaSequenceValue, m3u8_1, err_4;
|
|
790
745
|
return __generator(this, function (_a) {
|
|
791
746
|
switch (_a.label) {
|
|
792
747
|
case 0:
|
|
@@ -815,29 +770,22 @@ var Session = /** @class */ (function () {
|
|
|
815
770
|
if (this.prevMediaSeqOffset.video === null) {
|
|
816
771
|
this.prevMediaSeqOffset.video = playheadState.mediaSeq;
|
|
817
772
|
}
|
|
818
|
-
if (!(playheadState.vodMediaSeqVideo > sessionState.vodMediaSeqVideo ||
|
|
819
|
-
(playheadState.vodMediaSeqVideo < sessionState.vodMediaSeqVideo &&
|
|
820
|
-
playheadState.mediaSeq === this.prevMediaSeqOffset.video))) return [3 /*break*/, 11];
|
|
773
|
+
if (!(playheadState.vodMediaSeqVideo > sessionState.vodMediaSeqVideo || (playheadState.vodMediaSeqVideo < sessionState.vodMediaSeqVideo && playheadState.mediaSeq === this.prevMediaSeqOffset.video))) return [3 /*break*/, 9];
|
|
821
774
|
return [4 /*yield*/, this._sessionState.get("state")];
|
|
822
775
|
case 6:
|
|
823
776
|
state = _a.sent();
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
777
|
+
DELAY_TIME_MS = 1000;
|
|
778
|
+
ACTION = [SessionState.VOD_RELOAD_INIT, SessionState.VOD_RELOAD_INITIATING].includes(state) ? "Reloaded" : "Loaded Next";
|
|
779
|
+
debug("[".concat(this._sessionId, "]: Recently ").concat(ACTION, " Vod. PlayheadState not up-to-date (").concat(playheadState.vodMediaSeqVideo, "_").concat(sessionState.vodMediaSeqVideo, "). Waiting ").concat(DELAY_TIME_MS, "ms before reading from store again"));
|
|
780
|
+
return [4 /*yield*/, timer(DELAY_TIME_MS)];
|
|
827
781
|
case 7:
|
|
828
782
|
_a.sent();
|
|
829
783
|
return [4 /*yield*/, this._playheadState.getValues(["mediaSeq", "vodMediaSeqVideo"])];
|
|
830
784
|
case 8:
|
|
831
785
|
playheadState = _a.sent();
|
|
832
|
-
|
|
786
|
+
_a.label = 9;
|
|
833
787
|
case 9:
|
|
834
|
-
|
|
835
|
-
return [4 /*yield*/, timer(1000)];
|
|
836
|
-
case 10:
|
|
837
|
-
_a.sent();
|
|
838
|
-
_a.label = 11;
|
|
839
|
-
case 11:
|
|
840
|
-
if (!(playheadState.vodMediaSeqVideo < 2 || playheadState.mediaSeq !== this.prevMediaSeqOffset.video)) return [3 /*break*/, 16];
|
|
788
|
+
if (!(playheadState.vodMediaSeqVideo < 2 || playheadState.mediaSeq !== this.prevMediaSeqOffset.video)) return [3 /*break*/, 14];
|
|
841
789
|
debug("[".concat(this._sessionId, "]: current[").concat(playheadState.vodMediaSeqVideo, "]_prev[").concat(this.prevVodMediaSeq.video, "]"));
|
|
842
790
|
debug("[".concat(this._sessionId, "]: current-offset[").concat(playheadState.mediaSeq, "]_prev-offset[").concat(this.prevMediaSeqOffset.video, "]"));
|
|
843
791
|
// If true, then we have not updated the prev-values and not cleared the cache yet.
|
|
@@ -845,16 +793,16 @@ var Session = /** @class */ (function () {
|
|
|
845
793
|
this.isAllowedToClearVodCache = true;
|
|
846
794
|
}
|
|
847
795
|
return [4 /*yield*/, this._sessionStateStore.isLeader(this._instanceId)];
|
|
848
|
-
case
|
|
796
|
+
case 10:
|
|
849
797
|
isLeader = _a.sent();
|
|
850
|
-
if (!(!isLeader && this.isAllowedToClearVodCache)) return [3 /*break*/,
|
|
798
|
+
if (!(!isLeader && this.isAllowedToClearVodCache)) return [3 /*break*/, 13];
|
|
851
799
|
debug("[".concat(this._sessionId, "]: Not a leader and first|second media sequence in a VOD is requested. Invalidate cache to ensure having the correct VOD."));
|
|
852
800
|
return [4 /*yield*/, this._sessionState.clearCurrentVodCache()];
|
|
853
|
-
case
|
|
801
|
+
case 11:
|
|
854
802
|
_a.sent();
|
|
855
803
|
this.isAllowedToClearVodCache = false;
|
|
856
804
|
return [4 /*yield*/, this._playheadState.get("diffCompensation")];
|
|
857
|
-
case
|
|
805
|
+
case 12:
|
|
858
806
|
diffMs = _a.sent();
|
|
859
807
|
if (diffMs) {
|
|
860
808
|
this.diffCompensation = diffMs;
|
|
@@ -867,18 +815,18 @@ var Session = /** @class */ (function () {
|
|
|
867
815
|
this.timePositionOffset = 0;
|
|
868
816
|
}
|
|
869
817
|
}
|
|
818
|
+
_a.label = 13;
|
|
819
|
+
case 13: return [3 /*break*/, 15];
|
|
820
|
+
case 14:
|
|
821
|
+
this.isAllowedToClearVodCache = true;
|
|
870
822
|
_a.label = 15;
|
|
871
|
-
case 15: return [
|
|
823
|
+
case 15: return [4 /*yield*/, this._sessionState.getCurrentVod()];
|
|
872
824
|
case 16:
|
|
873
|
-
this.isAllowedToClearVodCache = true;
|
|
874
|
-
_a.label = 17;
|
|
875
|
-
case 17: return [4 /*yield*/, this._sessionState.getCurrentVod()];
|
|
876
|
-
case 18:
|
|
877
825
|
currentVod = _a.sent();
|
|
878
|
-
if (!currentVod) return [3 /*break*/,
|
|
879
|
-
_a.label =
|
|
880
|
-
case
|
|
881
|
-
_a.trys.push([
|
|
826
|
+
if (!currentVod) return [3 /*break*/, 21];
|
|
827
|
+
_a.label = 17;
|
|
828
|
+
case 17:
|
|
829
|
+
_a.trys.push([17, 18, , 20]);
|
|
882
830
|
manifestMseq = playheadState.mediaSeq + playheadState.vodMediaSeqVideo;
|
|
883
831
|
manifestDseq = sessionState.discSeq + currentVod.discontinuities[playheadState.vodMediaSeqVideo];
|
|
884
832
|
if (currentVod.sequenceAlwaysContainNewSegments) {
|
|
@@ -892,23 +840,23 @@ var Session = /** @class */ (function () {
|
|
|
892
840
|
this.prevVodMediaSeq.video = playheadState.vodMediaSeqVideo;
|
|
893
841
|
this.prevMediaSeqOffset.video = playheadState.mediaSeq;
|
|
894
842
|
return [2 /*return*/, m3u8_1];
|
|
895
|
-
case
|
|
843
|
+
case 18:
|
|
896
844
|
err_4 = _a.sent();
|
|
897
845
|
logerror(this._sessionId, err_4);
|
|
898
846
|
return [4 /*yield*/, this._sessionState.clearCurrentVodCache()];
|
|
899
|
-
case
|
|
847
|
+
case 19:
|
|
900
848
|
_a.sent(); // force reading up from shared store
|
|
901
849
|
throw new Error("Failed to generate manifest: " + JSON.stringify(playheadState));
|
|
902
|
-
case
|
|
903
|
-
case
|
|
904
|
-
case
|
|
850
|
+
case 20: return [3 /*break*/, 22];
|
|
851
|
+
case 21: throw new Error("Engine not ready");
|
|
852
|
+
case 22: return [2 /*return*/];
|
|
905
853
|
}
|
|
906
854
|
});
|
|
907
855
|
});
|
|
908
856
|
};
|
|
909
857
|
Session.prototype.getCurrentAudioManifestAsync = function (audioGroupId, audioLanguage, playbackSessionId) {
|
|
910
858
|
return __awaiter(this, void 0, void 0, function () {
|
|
911
|
-
var currentVod, sessionState, playheadState, state, AGE_THRESH, cacheAge, manifestMseq, manifestDseq, mediaSequenceValue, m3u8_2, err_5;
|
|
859
|
+
var currentVod, sessionState, playheadState, state, DELAY_TIME_MS, ACTION, AGE_THRESH, cacheAge, manifestMseq, manifestDseq, mediaSequenceValue, m3u8_2, err_5;
|
|
912
860
|
return __generator(this, function (_a) {
|
|
913
861
|
switch (_a.label) {
|
|
914
862
|
case 0:
|
|
@@ -922,30 +870,21 @@ var Session = /** @class */ (function () {
|
|
|
922
870
|
return [4 /*yield*/, this._playheadState.getValues(["mediaSeqAudio", "vodMediaSeqAudio"])];
|
|
923
871
|
case 2:
|
|
924
872
|
playheadState = _a.sent();
|
|
925
|
-
if (!(playheadState.vodMediaSeqAudio > sessionState.vodMediaSeqAudio ||
|
|
926
|
-
(playheadState.vodMediaSeqAudio < sessionState.vodMediaSeqAudio && playheadState.mediaSeqAudio === this.prevMediaSeqOffset.audio))) return [3 /*break*/, 9];
|
|
873
|
+
if (!(playheadState.vodMediaSeqAudio > sessionState.vodMediaSeqAudio || (playheadState.vodMediaSeqAudio < sessionState.vodMediaSeqAudio && playheadState.mediaSeqAudio === this.prevMediaSeqOffset.audio))) return [3 /*break*/, 6];
|
|
927
874
|
return [4 /*yield*/, this._sessionState.get("state")];
|
|
928
875
|
case 3:
|
|
929
876
|
state = _a.sent();
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
877
|
+
DELAY_TIME_MS = 1000;
|
|
878
|
+
ACTION = [SessionState.VOD_RELOAD_INIT, SessionState.VOD_RELOAD_INITIATING].includes(state) ? "Reloaded" : "Loaded Next";
|
|
879
|
+
debug("[".concat(this._sessionId, "]: Recently ").concat(ACTION, " Vod. PlayheadState not up-to-date (").concat(playheadState.vodMediaSeqAudio, "_").concat(sessionState.vodMediaSeqAudio, "). Waiting ").concat(DELAY_TIME_MS, "ms before reading from store again"));
|
|
880
|
+
return [4 /*yield*/, timer(DELAY_TIME_MS)];
|
|
933
881
|
case 4:
|
|
934
882
|
_a.sent();
|
|
935
883
|
return [4 /*yield*/, this._playheadState.getValues(["mediaSeqAudio", "vodMediaSeqAudio"])];
|
|
936
884
|
case 5:
|
|
937
885
|
playheadState = _a.sent();
|
|
938
|
-
|
|
886
|
+
_a.label = 6;
|
|
939
887
|
case 6:
|
|
940
|
-
debug("[".concat(this._sessionId, "]: Recently Loaded Next Vod. PlayheadState not up-to-date. Delay audio-m3u8 Response by 1000ms"));
|
|
941
|
-
return [4 /*yield*/, timer(1000)];
|
|
942
|
-
case 7:
|
|
943
|
-
_a.sent();
|
|
944
|
-
return [4 /*yield*/, this._playheadState.getValues(["mediaSeqAudio", "vodMediaSeqAudio"])];
|
|
945
|
-
case 8:
|
|
946
|
-
playheadState = _a.sent();
|
|
947
|
-
_a.label = 9;
|
|
948
|
-
case 9:
|
|
949
888
|
// local store the prev values
|
|
950
889
|
if (this.prevVodMediaSeq.audio === null) {
|
|
951
890
|
this.prevVodMediaSeq.audio = playheadState.vodMediaSeqAudio;
|
|
@@ -954,29 +893,29 @@ var Session = /** @class */ (function () {
|
|
|
954
893
|
this.prevMediaSeqOffset.audio = playheadState.mediaSeqAudio;
|
|
955
894
|
}
|
|
956
895
|
return [4 /*yield*/, this._sessionState.getCurrentVod()];
|
|
957
|
-
case
|
|
896
|
+
case 7:
|
|
958
897
|
currentVod = _a.sent();
|
|
959
|
-
if (!currentVod) return [3 /*break*/,
|
|
960
|
-
if (!(playheadState.vodMediaSeqAudio < 2 || playheadState.mediaSeqAudio !== this.prevMediaSeqOffset.audio)) return [3 /*break*/,
|
|
961
|
-
AGE_THRESH =
|
|
898
|
+
if (!currentVod) return [3 /*break*/, 15];
|
|
899
|
+
if (!(playheadState.vodMediaSeqAudio < 2 || playheadState.mediaSeqAudio !== this.prevMediaSeqOffset.audio)) return [3 /*break*/, 11];
|
|
900
|
+
AGE_THRESH = this.averageSegmentDuration * 2;
|
|
962
901
|
cacheAge = null;
|
|
963
902
|
if (this._sessionState.cache && this._sessionState.cache.currentVod.ts) {
|
|
964
903
|
cacheAge = Date.now() - this._sessionState.cache.currentVod.ts;
|
|
965
904
|
}
|
|
966
|
-
if (!(cacheAge !== null && cacheAge > AGE_THRESH)) return [3 /*break*/,
|
|
905
|
+
if (!(cacheAge !== null && cacheAge > AGE_THRESH)) return [3 /*break*/, 11];
|
|
967
906
|
return [4 /*yield*/, timer(500)];
|
|
968
|
-
case
|
|
907
|
+
case 8:
|
|
969
908
|
_a.sent();
|
|
970
909
|
debug("[".concat(this._sessionId, "]: While requesting audio manifest for ").concat(audioGroupId, "-").concat(audioLanguage, ", (mseq=").concat(playheadState.vodMediaSeqAudio, ")(vod cache age=").concat(cacheAge, ")"));
|
|
971
910
|
return [4 /*yield*/, this._sessionState.clearCurrentVodCache()];
|
|
972
|
-
case
|
|
911
|
+
case 9:
|
|
973
912
|
_a.sent(); // force reading up from shared store
|
|
974
913
|
return [4 /*yield*/, this._sessionState.getCurrentVod()];
|
|
975
|
-
case
|
|
914
|
+
case 10:
|
|
976
915
|
currentVod = _a.sent();
|
|
977
|
-
_a.label =
|
|
978
|
-
case
|
|
979
|
-
_a.trys.push([
|
|
916
|
+
_a.label = 11;
|
|
917
|
+
case 11:
|
|
918
|
+
_a.trys.push([11, 12, , 14]);
|
|
980
919
|
manifestMseq = playheadState.mediaSeqAudio + playheadState.vodMediaSeqAudio;
|
|
981
920
|
manifestDseq = sessionState.discSeqAudio + currentVod.discontinuitiesAudio[playheadState.vodMediaSeqAudio];
|
|
982
921
|
if (currentVod.sequenceAlwaysContainNewSegments) {
|
|
@@ -994,23 +933,23 @@ var Session = /** @class */ (function () {
|
|
|
994
933
|
this.prevVodMediaSeq.audio = playheadState.vodMediaSeqAudio;
|
|
995
934
|
this.prevMediaSeqOffset.audio = playheadState.mediaSeqAudio;
|
|
996
935
|
return [2 /*return*/, m3u8_2];
|
|
997
|
-
case
|
|
936
|
+
case 12:
|
|
998
937
|
err_5 = _a.sent();
|
|
999
938
|
logerror(this._sessionId, err_5);
|
|
1000
939
|
return [4 /*yield*/, this._sessionState.clearCurrentVodCache()];
|
|
1001
|
-
case
|
|
940
|
+
case 13:
|
|
1002
941
|
_a.sent(); // force reading up from shared store
|
|
1003
942
|
throw new Error("Failed to generate audio manifest: " + JSON.stringify(playheadState));
|
|
1004
|
-
case
|
|
1005
|
-
case
|
|
1006
|
-
case
|
|
943
|
+
case 14: return [3 /*break*/, 16];
|
|
944
|
+
case 15: throw new Error("Engine not ready");
|
|
945
|
+
case 16: return [2 /*return*/];
|
|
1007
946
|
}
|
|
1008
947
|
});
|
|
1009
948
|
});
|
|
1010
949
|
};
|
|
1011
|
-
Session.prototype.incrementAsync = function (
|
|
950
|
+
Session.prototype.incrementAsync = function () {
|
|
1012
951
|
return __awaiter(this, void 0, void 0, function () {
|
|
1013
|
-
var isLeader, sessionState, playheadState, currentVod, _a, leaderAction, _b, m3u8_3, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, mediaSequenceValue, diffMs, m3u8;
|
|
952
|
+
var isLeader, sessionState, playheadState, currentVod, _a, leaderAction, _b, m3u8_3, _c, audioIncrement, position, currentVod_1, sessionState_1, posDiff, incrementValue, index, audioSeqLastIdx, thresh, audioPosition, _d, _e, _f, _g, _h, _j, _k, _l, _m, mediaSequenceValue, diffMs, m3u8;
|
|
1014
953
|
return __generator(this, function (_o) {
|
|
1015
954
|
switch (_o.label) {
|
|
1016
955
|
case 0: return [4 /*yield*/, this._tickAsync()];
|
|
@@ -1070,79 +1009,124 @@ var Session = /** @class */ (function () {
|
|
|
1070
1009
|
}
|
|
1071
1010
|
this.isAllowedToClearVodCache = true;
|
|
1072
1011
|
_o.label = 13;
|
|
1073
|
-
case 13: return [3 /*break*/,
|
|
1012
|
+
case 13: return [3 /*break*/, 25];
|
|
1074
1013
|
case 14:
|
|
1075
1014
|
_c = sessionState;
|
|
1076
1015
|
return [4 /*yield*/, this._sessionState.increment("vodMediaSeqVideo")];
|
|
1077
1016
|
case 15:
|
|
1078
1017
|
_c.vodMediaSeqVideo = _o.sent();
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
return [4 /*yield*/, this.
|
|
1018
|
+
audioIncrement = void 0;
|
|
1019
|
+
if (!this.use_demuxed_audio) return [3 /*break*/, 23];
|
|
1020
|
+
return [4 /*yield*/, this._getCurrentPlayheadPosition()];
|
|
1082
1021
|
case 16:
|
|
1083
|
-
|
|
1084
|
-
|
|
1022
|
+
position = (_o.sent()) * 1000;
|
|
1023
|
+
return [4 /*yield*/, this._sessionState.getCurrentVod()];
|
|
1085
1024
|
case 17:
|
|
1086
|
-
|
|
1025
|
+
currentVod_1 = _o.sent();
|
|
1026
|
+
return [4 /*yield*/, this._sessionState.getValues(["vodMediaSeqAudio"])];
|
|
1027
|
+
case 18:
|
|
1028
|
+
sessionState_1 = _o.sent();
|
|
1029
|
+
posDiff = void 0;
|
|
1030
|
+
incrementValue = 1;
|
|
1031
|
+
index = 0;
|
|
1032
|
+
audioSeqLastIdx = currentVod_1.getLiveMediaSequencesCount("audio") - 1;
|
|
1033
|
+
thresh = 0.5;
|
|
1034
|
+
_o.label = 19;
|
|
1035
|
+
case 19: return [4 /*yield*/, this._getAudioPlayheadPosition(sessionState_1.vodMediaSeqAudio + index)];
|
|
1036
|
+
case 20:
|
|
1037
|
+
audioPosition = (_o.sent()) * 1000;
|
|
1038
|
+
posDiff = position - audioPosition;
|
|
1039
|
+
if (posDiff < 0) {
|
|
1040
|
+
return [3 /*break*/, 22];
|
|
1041
|
+
}
|
|
1042
|
+
if (posDiff > thresh) {
|
|
1043
|
+
index++;
|
|
1044
|
+
incrementValue++;
|
|
1045
|
+
}
|
|
1046
|
+
else {
|
|
1047
|
+
index = incrementValue;
|
|
1048
|
+
return [3 /*break*/, 22];
|
|
1049
|
+
}
|
|
1050
|
+
if (sessionState_1.vodMediaSeqAudio + index > audioSeqLastIdx) {
|
|
1051
|
+
return [3 /*break*/, 22];
|
|
1052
|
+
}
|
|
1053
|
+
_o.label = 21;
|
|
1054
|
+
case 21:
|
|
1055
|
+
if (!(-thresh < posDiff && posDiff < thresh)) return [3 /*break*/, 19];
|
|
1056
|
+
_o.label = 22;
|
|
1057
|
+
case 22:
|
|
1058
|
+
audioIncrement = index;
|
|
1059
|
+
_o.label = 23;
|
|
1060
|
+
case 23:
|
|
1061
|
+
_d = sessionState;
|
|
1062
|
+
return [4 /*yield*/, this._sessionState.increment("vodMediaSeqAudio", audioIncrement)];
|
|
1063
|
+
case 24:
|
|
1064
|
+
_d.vodMediaSeqAudio = _o.sent();
|
|
1065
|
+
_o.label = 25;
|
|
1066
|
+
case 25:
|
|
1067
|
+
if (!(sessionState.vodMediaSeqVideo >= currentVod.getLiveMediaSequencesCount() - 1)) return [3 /*break*/, 28];
|
|
1087
1068
|
_e = sessionState;
|
|
1088
1069
|
return [4 /*yield*/, this._sessionState.set("vodMediaSeqVideo", currentVod.getLiveMediaSequencesCount() - 1)];
|
|
1089
|
-
case
|
|
1070
|
+
case 26:
|
|
1090
1071
|
_e.vodMediaSeqVideo = _o.sent();
|
|
1091
1072
|
_f = sessionState;
|
|
1092
|
-
return [4 /*yield*/, this._sessionState.set("vodMediaSeqAudio", currentVod.getLiveMediaSequencesCount("audio") - 1)];
|
|
1093
|
-
case 19:
|
|
1094
|
-
_f.vodMediaSeqAudio = _o.sent();
|
|
1095
|
-
_g = sessionState;
|
|
1096
1073
|
return [4 /*yield*/, this._sessionState.set("state", SessionState.VOD_NEXT_INIT)];
|
|
1097
|
-
case
|
|
1098
|
-
|
|
1099
|
-
_o.label =
|
|
1100
|
-
case
|
|
1101
|
-
if (!
|
|
1074
|
+
case 27:
|
|
1075
|
+
_f.state = _o.sent();
|
|
1076
|
+
_o.label = 28;
|
|
1077
|
+
case 28:
|
|
1078
|
+
if (!(sessionState.vodMediaSeqAudio >= currentVod.getLiveMediaSequencesCount("audio") - 1)) return [3 /*break*/, 30];
|
|
1079
|
+
_g = sessionState;
|
|
1080
|
+
return [4 /*yield*/, this._sessionState.set("vodMediaSeqAudio", currentVod.getLiveMediaSequencesCount("audio") - 1)];
|
|
1081
|
+
case 29:
|
|
1082
|
+
_g.vodMediaSeqAudio = _o.sent();
|
|
1083
|
+
_o.label = 30;
|
|
1084
|
+
case 30:
|
|
1085
|
+
if (!this.isSwitchingBackToV2L) return [3 /*break*/, 32];
|
|
1102
1086
|
_h = sessionState;
|
|
1103
1087
|
return [4 /*yield*/, this._sessionState.set("state", SessionState.VOD_RELOAD_INIT)];
|
|
1104
|
-
case
|
|
1088
|
+
case 31:
|
|
1105
1089
|
_h.state = _o.sent();
|
|
1106
1090
|
this.isSwitchingBackToV2L = false;
|
|
1107
|
-
_o.label =
|
|
1108
|
-
case
|
|
1091
|
+
_o.label = 32;
|
|
1092
|
+
case 32:
|
|
1109
1093
|
_j = playheadState;
|
|
1110
1094
|
return [4 /*yield*/, this._playheadState.set("mediaSeq", sessionState.mediaSeq)];
|
|
1111
|
-
case
|
|
1095
|
+
case 33:
|
|
1112
1096
|
_j.mediaSeq = _o.sent();
|
|
1113
1097
|
_k = playheadState;
|
|
1114
1098
|
return [4 /*yield*/, this._playheadState.set("mediaSeqAudio", sessionState.mediaSeqAudio)];
|
|
1115
|
-
case
|
|
1099
|
+
case 34:
|
|
1116
1100
|
_k.mediaSeqAudio = _o.sent();
|
|
1117
1101
|
_l = playheadState;
|
|
1118
1102
|
return [4 /*yield*/, this._playheadState.set("vodMediaSeqVideo", sessionState.vodMediaSeqVideo)];
|
|
1119
|
-
case
|
|
1103
|
+
case 35:
|
|
1120
1104
|
_l.vodMediaSeqVideo = _o.sent();
|
|
1121
1105
|
_m = playheadState;
|
|
1122
1106
|
return [4 /*yield*/, this._playheadState.set("vodMediaSeqAudio", sessionState.vodMediaSeqAudio)];
|
|
1123
|
-
case
|
|
1107
|
+
case 36:
|
|
1124
1108
|
_m.vodMediaSeqAudio = _o.sent();
|
|
1125
1109
|
if (currentVod.sequenceAlwaysContainNewSegments) {
|
|
1126
1110
|
mediaSequenceValue = currentVod.mediaSequenceValues[playheadState.vodMediaSeqVideo];
|
|
1127
1111
|
debug("[".concat(this._sessionId, "]: Session can now serve mseq={").concat(playheadState.mediaSeq + mediaSequenceValue, "}"));
|
|
1128
1112
|
}
|
|
1129
1113
|
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"), ")"));
|
|
1130
|
-
if (!(playheadState.vodMediaSeqVideo < 2 || playheadState.mediaSeq !== this.prevMediaSeqOffset.video)) return [3 /*break*/,
|
|
1114
|
+
if (!(playheadState.vodMediaSeqVideo < 2 || playheadState.mediaSeq !== this.prevMediaSeqOffset.video)) return [3 /*break*/, 41];
|
|
1131
1115
|
debug("[".concat(this._sessionId, "]: current[").concat(playheadState.vodMediaSeqVideo, "]_prev[").concat(this.prevVodMediaSeq.video, "]"));
|
|
1132
1116
|
debug("[".concat(this._sessionId, "]: current-offset[").concat(playheadState.mediaSeq, "]_prev-offset[").concat(this.prevMediaSeqOffset.video, "]"));
|
|
1133
1117
|
if (playheadState.vodMediaSeqVideo < this.prevVodMediaSeq.video || playheadState.mediaSeq !== this.prevMediaSeqOffset.video) {
|
|
1134
1118
|
this.isAllowedToClearVodCache = true;
|
|
1135
1119
|
}
|
|
1136
|
-
if (!(!isLeader && this.isAllowedToClearVodCache)) return [3 /*break*/,
|
|
1120
|
+
if (!(!isLeader && this.isAllowedToClearVodCache)) return [3 /*break*/, 40];
|
|
1137
1121
|
debug("[".concat(this._sessionId, "]: Not a leader and have just set 'playheadState.vodMediaSeqVideo' to 0|1. Invalidate cache to ensure having the correct VOD."));
|
|
1138
1122
|
return [4 /*yield*/, this._sessionState.clearCurrentVodCache()];
|
|
1139
|
-
case
|
|
1123
|
+
case 37:
|
|
1140
1124
|
_o.sent();
|
|
1141
1125
|
return [4 /*yield*/, this._sessionState.getCurrentVod()];
|
|
1142
|
-
case
|
|
1126
|
+
case 38:
|
|
1143
1127
|
currentVod = _o.sent();
|
|
1144
1128
|
return [4 /*yield*/, this._playheadState.get("diffCompensation")];
|
|
1145
|
-
case
|
|
1129
|
+
case 39:
|
|
1146
1130
|
diffMs = _o.sent();
|
|
1147
1131
|
if (diffMs) {
|
|
1148
1132
|
this.diffCompensation = diffMs;
|
|
@@ -1156,12 +1140,12 @@ var Session = /** @class */ (function () {
|
|
|
1156
1140
|
}
|
|
1157
1141
|
}
|
|
1158
1142
|
this.isAllowedToClearVodCache = false;
|
|
1159
|
-
_o.label =
|
|
1160
|
-
case
|
|
1161
|
-
case
|
|
1143
|
+
_o.label = 40;
|
|
1144
|
+
case 40: return [3 /*break*/, 42];
|
|
1145
|
+
case 41:
|
|
1162
1146
|
this.isAllowedToClearVodCache = true;
|
|
1163
|
-
_o.label =
|
|
1164
|
-
case
|
|
1147
|
+
_o.label = 42;
|
|
1148
|
+
case 42:
|
|
1165
1149
|
// Update Value for Previous Sequence
|
|
1166
1150
|
this.prevVodMediaSeq.video = playheadState.vodMediaSeqVideo;
|
|
1167
1151
|
this.prevMediaSeqOffset.video = playheadState.mediaSeq;
|
|
@@ -1171,7 +1155,7 @@ var Session = /** @class */ (function () {
|
|
|
1171
1155
|
}
|
|
1172
1156
|
m3u8 = currentVod.getLiveMediaSequences(playheadState.mediaSeq, 180000, playheadState.vodMediaSeqVideo, sessionState.discSeq);
|
|
1173
1157
|
return [4 /*yield*/, this._playheadState.setLastM3u8(m3u8)];
|
|
1174
|
-
case
|
|
1158
|
+
case 43:
|
|
1175
1159
|
_o.sent();
|
|
1176
1160
|
return [2 /*return*/, m3u8];
|
|
1177
1161
|
}
|
|
@@ -1534,7 +1518,7 @@ var Session = /** @class */ (function () {
|
|
|
1534
1518
|
};
|
|
1535
1519
|
Session.prototype._tickAsync = function () {
|
|
1536
1520
|
return __awaiter(this, void 0, void 0, function () {
|
|
1537
|
-
var newVod, sessionState, isLeader, currentVod, vodResponse, _a, nextVodPromise, nextVodStart, _b, loadPromise, hlsOpts, loadStart, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, err_6, _o, length_1, endMseqValue, endMseqValueAudio, lastDiscontinuity, lastDiscontinuityAudio, _p, vodPromise, gracePeriod, nextVodStart, _q, loadPromise, hlsOpts, loadStart, _r, _s, _t, _u, _v, _w, _x, _y, _z, diffMs, err_7, startTS, _0, mSeq,
|
|
1521
|
+
var newVod, sessionState, isLeader, currentVod, vodResponse, _a, nextVodPromise, nextVodStart, _b, loadPromise, hlsOpts, loadStart, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, err_6, _o, length_1, endMseqValue, endMseqValueAudio, lastDiscontinuity, lastDiscontinuityAudio, _p, vodPromise, gracePeriod, nextVodStart, _q, loadPromise, hlsOpts, loadStart, _r, _s, _t, _u, _v, _w, _x, _y, _z, diffMs, err_7, startTS, _0, mSeq, currentVod_2, dSeq, mSeqOffset, reloadBehind, segments, playheadState, nextMseq, _1, err_8;
|
|
1538
1522
|
var _this = this;
|
|
1539
1523
|
return __generator(this, function (_2) {
|
|
1540
1524
|
switch (_2.label) {
|
|
@@ -1959,8 +1943,8 @@ var Session = /** @class */ (function () {
|
|
|
1959
1943
|
mSeq = this.switchDataForSession.mediaSeq;
|
|
1960
1944
|
return [4 /*yield*/, this._sessionState.getCurrentVod()];
|
|
1961
1945
|
case 64:
|
|
1962
|
-
|
|
1963
|
-
if (
|
|
1946
|
+
currentVod_2 = _2.sent();
|
|
1947
|
+
if (currentVod_2.sequenceAlwaysContainNewSegments) {
|
|
1964
1948
|
// (!) will need to compensate if using this setting on HLSVod Object.
|
|
1965
1949
|
Object.keys(this.switchDataForSession.transitionSegments).forEach(function (bw) {
|
|
1966
1950
|
var shiftedSeg = _this.switchDataForSession.transitionSegments[bw].shift();
|
|
@@ -1994,19 +1978,19 @@ var Session = /** @class */ (function () {
|
|
|
1994
1978
|
case 68:
|
|
1995
1979
|
playheadState = _2.sent();
|
|
1996
1980
|
nextMseq = playheadState.vodMediaSeqVideo + 1;
|
|
1997
|
-
if (nextMseq >
|
|
1998
|
-
nextMseq =
|
|
1981
|
+
if (nextMseq > currentVod_2.getLiveMediaSequencesCount() - 1) {
|
|
1982
|
+
nextMseq = currentVod_2.getLiveMediaSequencesCount() - 1;
|
|
1999
1983
|
}
|
|
2000
1984
|
// ---------------------------------------------------.
|
|
2001
1985
|
// TODO: Support reloading with audioSegments as well |
|
|
2002
1986
|
// ---------------------------------------------------'
|
|
2003
|
-
return [4 /*yield*/,
|
|
1987
|
+
return [4 /*yield*/, currentVod_2.reload(nextMseq, segments, null, reloadBehind)];
|
|
2004
1988
|
case 69:
|
|
2005
1989
|
// ---------------------------------------------------.
|
|
2006
1990
|
// TODO: Support reloading with audioSegments as well |
|
|
2007
1991
|
// ---------------------------------------------------'
|
|
2008
1992
|
_2.sent();
|
|
2009
|
-
return [4 /*yield*/, this._sessionState.setCurrentVod(
|
|
1993
|
+
return [4 /*yield*/, this._sessionState.setCurrentVod(currentVod_2, { ttl: currentVod_2.getDuration() * 1000 })];
|
|
2010
1994
|
case 70:
|
|
2011
1995
|
_2.sent();
|
|
2012
1996
|
return [4 /*yield*/, this._sessionState.set("vodReloaded", 1)];
|
|
@@ -2029,9 +2013,9 @@ var Session = /** @class */ (function () {
|
|
|
2029
2013
|
_2.sent();
|
|
2030
2014
|
// 4) Log to debug and cloudwatch
|
|
2031
2015
|
debug("[".concat(this._sessionId, "]: LEADER: Set new Reloaded VOD and vodMediaSeq counts in store."));
|
|
2032
|
-
debug("[".concat(this._sessionId, "]: next VOD Reloaded (").concat(
|
|
2033
|
-
debug("[".concat(this._sessionId, "]: ").concat(
|
|
2034
|
-
debug("[".concat(this._sessionId, "]: msequences=").concat(
|
|
2016
|
+
debug("[".concat(this._sessionId, "]: next VOD Reloaded (").concat(currentVod_2.getDeltaTimes(), ")"));
|
|
2017
|
+
debug("[".concat(this._sessionId, "]: ").concat(currentVod_2.getPlayheadPositions()));
|
|
2018
|
+
debug("[".concat(this._sessionId, "]: msequences=").concat(currentVod_2.getLiveMediaSequencesCount()));
|
|
2035
2019
|
cloudWatchLog(!this.cloudWatchLogging, "engine-session", { event: "switchback", channel: this._sessionId, reqTimeMs: Date.now() - startTS });
|
|
2036
2020
|
return [2 /*return*/];
|
|
2037
2021
|
case 77:
|
|
@@ -2331,6 +2315,9 @@ var Session = /** @class */ (function () {
|
|
|
2331
2315
|
case 1:
|
|
2332
2316
|
currentVod = _a.sent();
|
|
2333
2317
|
playheadPositions = currentVod.getPlayheadPositions("audio");
|
|
2318
|
+
if (seqIdx >= playheadPositions.length - 1) {
|
|
2319
|
+
seqIdx = playheadPositions.length - 1;
|
|
2320
|
+
}
|
|
2334
2321
|
debug("[".concat(this._sessionId, "]: Current audio playhead position (").concat(seqIdx, "): ").concat(playheadPositions[seqIdx]));
|
|
2335
2322
|
return [2 /*return*/, playheadPositions[seqIdx]];
|
|
2336
2323
|
}
|
package/dist/package.json
CHANGED
package/engine/server.ts
CHANGED
|
@@ -659,7 +659,7 @@ export class ChannelEngine {
|
|
|
659
659
|
"Access-Control-Allow-Origin": "*",
|
|
660
660
|
"Access-Control-Allow-Headers": "X-Session-Id",
|
|
661
661
|
"Access-Control-Expose-Headers": "X-Session-Id",
|
|
662
|
-
"Cache-Control": "
|
|
662
|
+
"Cache-Control": "max-age=300",
|
|
663
663
|
"X-Session-Id": session.sessionId,
|
|
664
664
|
"X-Instance-Id": this.instanceId + `<${version}>`,
|
|
665
665
|
});
|
package/engine/session.js
CHANGED
|
@@ -160,9 +160,7 @@ class Session {
|
|
|
160
160
|
while (state !== PlayheadState.CRASHED) {
|
|
161
161
|
try {
|
|
162
162
|
const tsIncrementBegin = Date.now();
|
|
163
|
-
const manifest = await this.incrementAsync(
|
|
164
|
-
audio: audioIncrement
|
|
165
|
-
});
|
|
163
|
+
const manifest = await this.incrementAsync();
|
|
166
164
|
if (!manifest) {
|
|
167
165
|
debug(`[${this._sessionId}]: No manifest available yet, will try again after 1000ms`);
|
|
168
166
|
await timer(1000);
|
|
@@ -202,38 +200,6 @@ class Session {
|
|
|
202
200
|
debug(`[${this._sessionId}]: Delta time is != 0 need will adjust ${delta}sec to tick interval. tick=${tickInterval}`);
|
|
203
201
|
}
|
|
204
202
|
const position = (await this._getCurrentPlayheadPosition()) * 1000;
|
|
205
|
-
|
|
206
|
-
if (this.use_demuxed_audio) {
|
|
207
|
-
let currentVod = await this._sessionState.getCurrentVod();
|
|
208
|
-
const sessionState = await this._sessionState.getValues(["vodMediaSeqAudio"]);
|
|
209
|
-
let posDiff;
|
|
210
|
-
let incrementValue = 1;
|
|
211
|
-
let index = 0;
|
|
212
|
-
const audioSeqLastIdx = currentVod.getLiveMediaSequencesCount("audio") - 1;
|
|
213
|
-
const thresh = 0.5;
|
|
214
|
-
let direction = 0;
|
|
215
|
-
do {
|
|
216
|
-
const audioPosition = (await this._getAudioPlayheadPosition(sessionState.vodMediaSeqAudio + index)) * 1000;
|
|
217
|
-
posDiff = position - audioPosition;
|
|
218
|
-
if (posDiff > thresh && direction >= 0) {
|
|
219
|
-
index++;
|
|
220
|
-
incrementValue++;
|
|
221
|
-
direction = 1;
|
|
222
|
-
} else if (posDiff < -thresh && direction <= 0) {
|
|
223
|
-
incrementValue = 0;
|
|
224
|
-
index--;
|
|
225
|
-
direction = -1;
|
|
226
|
-
break;
|
|
227
|
-
} else if (direction > 0 && posDiff < 0) {
|
|
228
|
-
break;
|
|
229
|
-
}
|
|
230
|
-
if (sessionState.vodMediaSeqAudio + index > audioSeqLastIdx || sessionState.vodMediaSeqAudio + index < 0) {
|
|
231
|
-
break;
|
|
232
|
-
}
|
|
233
|
-
} while (!(-thresh < posDiff && posDiff < thresh));
|
|
234
|
-
audioIncrement = incrementValue;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
203
|
let timePosition = Date.now() - playheadState.playheadRef;
|
|
238
204
|
// Apply time position offset if set, only after external diff compensation has concluded.
|
|
239
205
|
if (this.timePositionOffset && this.diffCompensation <= 0 && this.alwaysNewSegments) {
|
|
@@ -576,18 +542,13 @@ class Session {
|
|
|
576
542
|
this.prevMediaSeqOffset.video = playheadState.mediaSeq;
|
|
577
543
|
}
|
|
578
544
|
|
|
579
|
-
if (playheadState.vodMediaSeqVideo > sessionState.vodMediaSeqVideo ||
|
|
580
|
-
(playheadState.vodMediaSeqVideo < sessionState.vodMediaSeqVideo &&
|
|
581
|
-
playheadState.mediaSeq === this.prevMediaSeqOffset.video)) {
|
|
545
|
+
if (playheadState.vodMediaSeqVideo > sessionState.vodMediaSeqVideo || (playheadState.vodMediaSeqVideo < sessionState.vodMediaSeqVideo && playheadState.mediaSeq === this.prevMediaSeqOffset.video)) {
|
|
582
546
|
const state = await this._sessionState.get("state");
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
debug(`[${this._sessionId}]: Recently Loaded Next Vod. PlayheadState not up-to-date. Delay media-m3u8 Response by 1000ms`);
|
|
589
|
-
await timer(1000);
|
|
590
|
-
}
|
|
547
|
+
const DELAY_TIME_MS = 1000;
|
|
548
|
+
const ACTION = [SessionState.VOD_RELOAD_INIT, SessionState.VOD_RELOAD_INITIATING].includes(state) ? "Reloaded" : "Loaded Next";
|
|
549
|
+
debug(`[${this._sessionId}]: Recently ${ACTION} Vod. PlayheadState not up-to-date (${playheadState.vodMediaSeqVideo}_${sessionState.vodMediaSeqVideo}). Waiting ${DELAY_TIME_MS}ms before reading from store again`);
|
|
550
|
+
await timer(DELAY_TIME_MS);
|
|
551
|
+
playheadState = await this._playheadState.getValues(["mediaSeq", "vodMediaSeqVideo"]);
|
|
591
552
|
}
|
|
592
553
|
|
|
593
554
|
// Force reading up from store, but only once if the condition is right
|
|
@@ -655,24 +616,14 @@ class Session {
|
|
|
655
616
|
const sessionState = await this._sessionState.getValues(["discSeqAudio", "vodMediaSeqAudio"]);
|
|
656
617
|
let playheadState = await this._playheadState.getValues(["mediaSeqAudio", "vodMediaSeqAudio"]);
|
|
657
618
|
|
|
658
|
-
if (
|
|
659
|
-
playheadState.vodMediaSeqAudio > sessionState.vodMediaSeqAudio ||
|
|
660
|
-
(playheadState.vodMediaSeqAudio < sessionState.vodMediaSeqAudio && playheadState.mediaSeqAudio === this.prevMediaSeqOffset.audio)
|
|
661
|
-
) {
|
|
619
|
+
if (playheadState.vodMediaSeqAudio > sessionState.vodMediaSeqAudio || (playheadState.vodMediaSeqAudio < sessionState.vodMediaSeqAudio && playheadState.mediaSeqAudio === this.prevMediaSeqOffset.audio)) {
|
|
662
620
|
const state = await this._sessionState.get("state");
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
playheadState = await this._playheadState.getValues(["mediaSeqAudio", "vodMediaSeqAudio"]);
|
|
669
|
-
} else {
|
|
670
|
-
debug(`[${this._sessionId}]: Recently Loaded Next Vod. PlayheadState not up-to-date. Delay audio-m3u8 Response by 1000ms`);
|
|
671
|
-
await timer(1000);
|
|
672
|
-
playheadState = await this._playheadState.getValues(["mediaSeqAudio", "vodMediaSeqAudio"]);
|
|
673
|
-
}
|
|
621
|
+
const DELAY_TIME_MS = 1000;
|
|
622
|
+
const ACTION = [SessionState.VOD_RELOAD_INIT, SessionState.VOD_RELOAD_INITIATING].includes(state) ? "Reloaded" : "Loaded Next";
|
|
623
|
+
debug(`[${this._sessionId}]: Recently ${ACTION} Vod. PlayheadState not up-to-date (${playheadState.vodMediaSeqAudio}_${sessionState.vodMediaSeqAudio}). Waiting ${DELAY_TIME_MS}ms before reading from store again`);
|
|
624
|
+
await timer(DELAY_TIME_MS);
|
|
625
|
+
playheadState = await this._playheadState.getValues(["mediaSeqAudio", "vodMediaSeqAudio"]);
|
|
674
626
|
}
|
|
675
|
-
|
|
676
627
|
// local store the prev values
|
|
677
628
|
if (this.prevVodMediaSeq.audio === null) {
|
|
678
629
|
this.prevVodMediaSeq.audio = playheadState.vodMediaSeqAudio;
|
|
@@ -684,7 +635,7 @@ class Session {
|
|
|
684
635
|
if (currentVod) {
|
|
685
636
|
// condition suggesting that a new vod should exist
|
|
686
637
|
if (playheadState.vodMediaSeqAudio < 2 || playheadState.mediaSeqAudio !== this.prevMediaSeqOffset.audio) {
|
|
687
|
-
const AGE_THRESH =
|
|
638
|
+
const AGE_THRESH = this.averageSegmentDuration * 2;
|
|
688
639
|
let cacheAge = null;
|
|
689
640
|
if (this._sessionState.cache && this._sessionState.cache.currentVod.ts) {
|
|
690
641
|
cacheAge = Date.now() - this._sessionState.cache.currentVod.ts;
|
|
@@ -732,7 +683,7 @@ class Session {
|
|
|
732
683
|
}
|
|
733
684
|
}
|
|
734
685
|
|
|
735
|
-
async incrementAsync(
|
|
686
|
+
async incrementAsync() {
|
|
736
687
|
await this._tickAsync();
|
|
737
688
|
const isLeader = await this._sessionStateStore.isLeader(this._instanceId);
|
|
738
689
|
|
|
@@ -772,17 +723,47 @@ class Session {
|
|
|
772
723
|
}
|
|
773
724
|
} else {
|
|
774
725
|
sessionState.vodMediaSeqVideo = await this._sessionState.increment("vodMediaSeqVideo");
|
|
775
|
-
|
|
776
|
-
|
|
726
|
+
let audioIncrement;
|
|
727
|
+
if (this.use_demuxed_audio) {
|
|
728
|
+
const position = (await this._getCurrentPlayheadPosition()) * 1000;
|
|
729
|
+
let currentVod = await this._sessionState.getCurrentVod();
|
|
730
|
+
const sessionState = await this._sessionState.getValues(["vodMediaSeqAudio"]);
|
|
731
|
+
let posDiff;
|
|
732
|
+
let incrementValue = 1;
|
|
733
|
+
let index = 0;
|
|
734
|
+
const audioSeqLastIdx = currentVod.getLiveMediaSequencesCount("audio") - 1;
|
|
735
|
+
const thresh = 0.5;
|
|
736
|
+
do {
|
|
737
|
+
const audioPosition = (await this._getAudioPlayheadPosition(sessionState.vodMediaSeqAudio + index)) * 1000;
|
|
738
|
+
posDiff = position - audioPosition;
|
|
739
|
+
if (posDiff < 0) {
|
|
740
|
+
break;
|
|
741
|
+
}
|
|
742
|
+
if (posDiff > thresh) {
|
|
743
|
+
index++;
|
|
744
|
+
incrementValue++;
|
|
745
|
+
} else {
|
|
746
|
+
index = incrementValue;
|
|
747
|
+
break;
|
|
748
|
+
}
|
|
749
|
+
if (sessionState.vodMediaSeqAudio + index > audioSeqLastIdx) {
|
|
750
|
+
break;
|
|
751
|
+
}
|
|
752
|
+
} while (!(-thresh < posDiff && posDiff < thresh));
|
|
753
|
+
audioIncrement = index;
|
|
777
754
|
}
|
|
755
|
+
sessionState.vodMediaSeqAudio = await this._sessionState.increment("vodMediaSeqAudio", audioIncrement);
|
|
778
756
|
}
|
|
779
757
|
|
|
780
758
|
if (sessionState.vodMediaSeqVideo >= currentVod.getLiveMediaSequencesCount() - 1) {
|
|
781
759
|
sessionState.vodMediaSeqVideo = await this._sessionState.set("vodMediaSeqVideo", currentVod.getLiveMediaSequencesCount() - 1);
|
|
782
|
-
sessionState.vodMediaSeqAudio = await this._sessionState.set("vodMediaSeqAudio", currentVod.getLiveMediaSequencesCount("audio") - 1);
|
|
783
760
|
sessionState.state = await this._sessionState.set("state", SessionState.VOD_NEXT_INIT);
|
|
784
761
|
}
|
|
785
762
|
|
|
763
|
+
if (sessionState.vodMediaSeqAudio >= currentVod.getLiveMediaSequencesCount("audio") - 1) {
|
|
764
|
+
sessionState.vodMediaSeqAudio = await this._sessionState.set("vodMediaSeqAudio", currentVod.getLiveMediaSequencesCount("audio") - 1);
|
|
765
|
+
}
|
|
766
|
+
|
|
786
767
|
if (this.isSwitchingBackToV2L) {
|
|
787
768
|
sessionState.state = await this._sessionState.set("state", SessionState.VOD_RELOAD_INIT);
|
|
788
769
|
this.isSwitchingBackToV2L = false;
|
|
@@ -1688,6 +1669,9 @@ class Session {
|
|
|
1688
1669
|
async _getAudioPlayheadPosition(seqIdx) {
|
|
1689
1670
|
const currentVod = await this._sessionState.getCurrentVod();
|
|
1690
1671
|
const playheadPositions = currentVod.getPlayheadPositions("audio");
|
|
1672
|
+
if (seqIdx >= playheadPositions.length - 1) {
|
|
1673
|
+
seqIdx = playheadPositions.length - 1
|
|
1674
|
+
}
|
|
1691
1675
|
debug(`[${this._sessionId}]: Current audio playhead position (${seqIdx}): ${playheadPositions[seqIdx]}`);
|
|
1692
1676
|
return playheadPositions[seqIdx];
|
|
1693
1677
|
}
|