eyevinn-channel-engine 3.1.0 → 3.1.3
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/engine/session.js +8 -20
- package/engine/session_live.js +18 -37
- package/package.json +1 -1
package/engine/session.js
CHANGED
|
@@ -395,20 +395,10 @@ class Session {
|
|
|
395
395
|
if (!this._sessionState) {
|
|
396
396
|
throw new Error('Session not ready');
|
|
397
397
|
}
|
|
398
|
-
const sessionState = await this._sessionState.getValues(["discSeq"
|
|
398
|
+
const sessionState = await this._sessionState.getValues(["discSeq"]);
|
|
399
399
|
const playheadState = await this._playheadState.getValues(["mediaSeq", "vodMediaSeqVideo"]);
|
|
400
400
|
|
|
401
|
-
|
|
402
|
-
Since sessionState is always newer. If it is a smaller value, then this signals that
|
|
403
|
-
a new vod has been loaded but playheadState has yet to get the new mseq value in 'incrementAsync()'.
|
|
404
|
-
Without this, we risk returning an m3u8 with an old mseq on a new vod to the client.
|
|
405
|
-
*/
|
|
406
|
-
if (playheadState.vodMediaSeqVideo > sessionState.vodMediaSeqVideo) {
|
|
407
|
-
playheadState.vodMediaSeqVideo = sessionState.vodMediaSeqVideo;
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
if (playheadState.vodMediaSeqVideo === 0 || this.waitingForNextVod) {
|
|
411
|
-
this.waitingForNextVod = false;
|
|
401
|
+
if (playheadState.vodMediaSeqVideo === 0) {
|
|
412
402
|
const isLeader = await this._sessionStateStore.isLeader(this._instanceId);
|
|
413
403
|
if (!isLeader) {
|
|
414
404
|
debug(`[${this._sessionId}]: Not a leader and first media sequence in a VOD is requested. Invalidate cache to ensure having the correct VOD.`);
|
|
@@ -465,14 +455,6 @@ class Session {
|
|
|
465
455
|
let sessionState = await this._sessionState.getValues(
|
|
466
456
|
["state", "mediaSeq", "discSeq", "vodMediaSeqVideo", "vodMediaSeqAudio"]);
|
|
467
457
|
let playheadState = await this._playheadState.getValues(["mediaSeq", "vodMediaSeqVideo", "vodMediaSeqAudio"]);
|
|
468
|
-
if (playheadState.vodMediaSeqVideo < 2) {
|
|
469
|
-
// This is due to the possibility that we miss the tick where vodMediaSeqVideo is 0
|
|
470
|
-
// The worst case scenario is that we clear cache two times in a row on a switch
|
|
471
|
-
if (!isLeader) {
|
|
472
|
-
debug(`[${this._sessionId}]: Not a leader and first media sequence in a VOD is requested. Invalidate cache to ensure having the correct VOD.`);
|
|
473
|
-
await this._sessionState.clearCurrentVodCache(); // force reading up from shared store
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
458
|
let currentVod = await this._sessionState.getCurrentVod();
|
|
477
459
|
if (!currentVod ||
|
|
478
460
|
sessionState.vodMediaSeqVideo === null ||
|
|
@@ -517,6 +499,12 @@ class Session {
|
|
|
517
499
|
debug(`[${this._sessionId}]: INCREMENT (mseq=${playheadState.mediaSeq + playheadState.vodMediaSeqVideo}) vodMediaSeq=(${playheadState.vodMediaSeqVideo}_${playheadState.vodMediaSeqAudio} of ${currentVod.getLiveMediaSequencesCount()})`);
|
|
518
500
|
let m3u8 = currentVod.getLiveMediaSequences(playheadState.mediaSeq, 180000, playheadState.vodMediaSeqVideo, sessionState.discSeq);
|
|
519
501
|
await this._playheadState.setLastM3u8(m3u8);
|
|
502
|
+
|
|
503
|
+
if (!isLeader && playheadState.vodMediaSeqVideo < 2) {
|
|
504
|
+
debug(`[${this._sessionId}]: Not a leader and have just set playheadState vodMediaSeqVideo to 0|1. Invalidate cache to ensure having the correct VOD.`);
|
|
505
|
+
await this._sessionState.clearCurrentVodCache();
|
|
506
|
+
}
|
|
507
|
+
|
|
520
508
|
return m3u8;
|
|
521
509
|
}
|
|
522
510
|
|
package/engine/session_live.js
CHANGED
|
@@ -18,6 +18,7 @@ const daterangeAttribute = (key, attr) => {
|
|
|
18
18
|
const TARGET_PLAYLIST_DURATION_SEC = 60;
|
|
19
19
|
const RESET_DELAY = 5000;
|
|
20
20
|
const FAIL_TIMEOUT = 4000;
|
|
21
|
+
const DEFAULT_PLAYHEAD_INTERVAL_MS = 6 * 1000;
|
|
21
22
|
const PlayheadState = Object.freeze({
|
|
22
23
|
RUNNING: 1,
|
|
23
24
|
STOPPED: 2,
|
|
@@ -40,7 +41,6 @@ class SessionLive {
|
|
|
40
41
|
this.mediaManifestURIs = {};
|
|
41
42
|
this.liveSegQueue = {};
|
|
42
43
|
this.lastRequestedMediaSeqRaw = null;
|
|
43
|
-
this.targetNumSeg = 0;
|
|
44
44
|
this.liveSourceM3Us = {};
|
|
45
45
|
this.playheadState = PlayheadState.IDLE;
|
|
46
46
|
this.liveSegsForFollowers = {};
|
|
@@ -117,7 +117,6 @@ class SessionLive {
|
|
|
117
117
|
this.mediaManifestURIs = {};
|
|
118
118
|
this.liveSegQueue = {};
|
|
119
119
|
this.lastRequestedMediaSeqRaw = null;
|
|
120
|
-
this.targetNumSeg = 0;
|
|
121
120
|
this.liveSourceM3Us = {};
|
|
122
121
|
this.liveSegsForFollowers = {};
|
|
123
122
|
this.timerCompensation = null;
|
|
@@ -149,13 +148,6 @@ class SessionLive {
|
|
|
149
148
|
return;
|
|
150
149
|
}
|
|
151
150
|
|
|
152
|
-
// Let the playhead move at an interval set according to live segment duration
|
|
153
|
-
let liveSegmentDurationMs = 6000;
|
|
154
|
-
let liveBws = Object.keys(this.liveSegQueue);
|
|
155
|
-
if (liveBws.length !== 0 && this.liveSegQueue[liveBws[0]].length !== 0 && this.liveSegQueue[liveBws[0]][0].duration) {
|
|
156
|
-
liveSegmentDurationMs = this.liveSegQueue[liveBws[0]][0].duration * 1000;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
151
|
// Fetch Live-Source Segments, and get ready for on-the-fly manifest generation
|
|
160
152
|
// And also compensate for processing time
|
|
161
153
|
|
|
@@ -165,6 +157,13 @@ class SessionLive {
|
|
|
165
157
|
const tsIncrementEnd = Date.now();
|
|
166
158
|
this.waitForPlayhead = false;
|
|
167
159
|
|
|
160
|
+
// Let the playhead move at an interval set according to live segment duration
|
|
161
|
+
let liveSegmentDurationMs = DEFAULT_PLAYHEAD_INTERVAL_MS;
|
|
162
|
+
let liveBws = Object.keys(this.liveSegQueue);
|
|
163
|
+
if (liveBws.length !== 0 && this.liveSegQueue[liveBws[0]].length !== 0 && this.liveSegQueue[liveBws[0]][0].duration) {
|
|
164
|
+
liveSegmentDurationMs = this.liveSegQueue[liveBws[0]][0].duration * 1000;
|
|
165
|
+
}
|
|
166
|
+
|
|
168
167
|
// Set the timer
|
|
169
168
|
let timerValueMs = 0;
|
|
170
169
|
if (this.timerCompensation) {
|
|
@@ -242,14 +241,13 @@ class SessionLive {
|
|
|
242
241
|
}
|
|
243
242
|
// Make it possible to add & share new segments
|
|
244
243
|
this.allowedToSet = true;
|
|
245
|
-
let segCount = 0;
|
|
246
244
|
const allBws = Object.keys(segments);
|
|
247
245
|
for (let i = 0; i < allBws.length; i++) {
|
|
248
246
|
const bw = allBws[i];
|
|
249
247
|
if (!this.vodSegments[bw]) {
|
|
250
248
|
this.vodSegments[bw] = [];
|
|
251
249
|
}
|
|
252
|
-
|
|
250
|
+
|
|
253
251
|
if (segments[bw][0].discontinuity) {
|
|
254
252
|
segments[bw].shift();
|
|
255
253
|
}
|
|
@@ -264,12 +262,6 @@ class SessionLive {
|
|
|
264
262
|
}
|
|
265
263
|
}
|
|
266
264
|
|
|
267
|
-
for (let segIdx = 0; segIdx < segments[allBws[0]].length; segIdx++) {
|
|
268
|
-
if (segments[allBws[0]][segIdx].uri) {
|
|
269
|
-
segCount++;
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
this.targetNumSeg = segCount;
|
|
273
265
|
debug(`[${this.sessionId}]: Setting CurrentMediaSequenceSegments. First seg is: [${this.vodSegments[allBws[0]][0].uri}]`);
|
|
274
266
|
|
|
275
267
|
const isLeader = await this.sessionLiveStateStore.isLeader(this.instanceId);
|
|
@@ -645,12 +637,16 @@ class SessionLive {
|
|
|
645
637
|
if (Object.keys(this.liveSegQueue).length > 0) {
|
|
646
638
|
const firstBw = Object.keys(this.liveSegQueue)[0];
|
|
647
639
|
const lastIdx = this.liveSegQueue[firstBw].length - 1;
|
|
648
|
-
|
|
640
|
+
if (this.liveSegQueue[firstBw][lastIdx].duration) {
|
|
641
|
+
retryDelayMs = this.liveSegQueue[firstBw][lastIdx].duration * 1000 * 0.25;
|
|
642
|
+
}
|
|
649
643
|
}
|
|
650
644
|
// Wait a little before trying again
|
|
651
645
|
debug(`[${this.sessionId}]: ALERT! Live Source Data NOT in sync! Will try again after ${retryDelayMs}ms`);
|
|
652
646
|
await timer(retryDelayMs);
|
|
653
|
-
|
|
647
|
+
if (isLeader) {
|
|
648
|
+
this.timerCompensation = false;
|
|
649
|
+
}
|
|
654
650
|
continue;
|
|
655
651
|
}
|
|
656
652
|
|
|
@@ -688,14 +684,6 @@ class SessionLive {
|
|
|
688
684
|
const transitSegs = await this.sessionLiveState.get("transitSegs");
|
|
689
685
|
if (!this._isEmpty(transitSegs)) {
|
|
690
686
|
this.vodSegments = transitSegs;
|
|
691
|
-
let discTagCount = 0;
|
|
692
|
-
const allBws = Object.keys(this.vodSegments);
|
|
693
|
-
for (let segIdx = 0; segIdx < this.vodSegments[allBws[0]].length; segIdx++) {
|
|
694
|
-
if (this.vodSegments[allBws[0]][segIdx].discontinuity) {
|
|
695
|
-
discTagCount++;
|
|
696
|
-
}
|
|
697
|
-
}
|
|
698
|
-
this.targetNumSeg = this.vodSegments[allBws[0]].length - (discTagCount - 1);
|
|
699
687
|
}
|
|
700
688
|
}
|
|
701
689
|
|
|
@@ -711,14 +699,6 @@ class SessionLive {
|
|
|
711
699
|
//debug(`[${this.sessionId}]: NEW FOLLOWER: I tried to get 'transitSegs'. This is what I found ${JSON.stringify(transitSegs)}`);
|
|
712
700
|
if (!this._isEmpty(transitSegs)) {
|
|
713
701
|
this.vodSegments = transitSegs;
|
|
714
|
-
let discTagCount = 0;
|
|
715
|
-
const allBws = Object.keys(this.vodSegments);
|
|
716
|
-
for (let segIdx = 0; segIdx < this.vodSegments[allBws[0]].length; segIdx++) {
|
|
717
|
-
if (this.vodSegments[allBws[0]][segIdx].discontinuity) {
|
|
718
|
-
discTagCount++;
|
|
719
|
-
}
|
|
720
|
-
}
|
|
721
|
-
this.targetNumSeg = this.vodSegments[allBws[0]].length - (discTagCount - 1);
|
|
722
702
|
}
|
|
723
703
|
}
|
|
724
704
|
debug(`[${this.sessionId}]: ...pushAmount=${this.pushAmount}`);
|
|
@@ -779,7 +759,8 @@ class SessionLive {
|
|
|
779
759
|
await allSettled(pushPromises);
|
|
780
760
|
|
|
781
761
|
// UPDATE COUNTS, & Shift Segments in vodSegments and liveSegQueue if needed.
|
|
782
|
-
const
|
|
762
|
+
const leaderORFollower = isLeader ? "LEADER" : "NEW FOLLOWER";
|
|
763
|
+
const newTotalDuration = this._incrementAndShift(leaderORFollower);
|
|
783
764
|
if (newTotalDuration) {
|
|
784
765
|
debug(`[${this.sessionId}]: New Adjusted Playlist Duration=${newTotalDuration}s`);
|
|
785
766
|
}
|
|
@@ -1128,7 +1109,7 @@ class SessionLive {
|
|
|
1128
1109
|
}
|
|
1129
1110
|
// Push new Live Segments!
|
|
1130
1111
|
this.liveSegQueue[liveTargetBandwidth].push(seg);
|
|
1131
|
-
this.liveSegsForFollowers[liveTargetBandwidth].push(seg);
|
|
1112
|
+
this.liveSegsForFollowers[liveTargetBandwidth].push(seg);
|
|
1132
1113
|
}
|
|
1133
1114
|
}
|
|
1134
1115
|
}
|