eyevinn-channel-engine 4.2.10 → 4.3.0

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.
@@ -17,6 +17,7 @@ export interface ChannelEngineOpts {
17
17
  subtitleSliceEndpoint?: string;
18
18
  useVTTSubtitles?: boolean;
19
19
  alwaysNewSegments?: boolean;
20
+ partialStoreHLSVod?: boolean;
20
21
  alwaysMapBandwidthByNearest?: boolean;
21
22
  diffCompensationRate?: number;
22
23
  staticDirectory?: string;
@@ -127,6 +128,7 @@ export declare class ChannelEngine {
127
128
  private subtitleSliceEndpoint;
128
129
  private useVTTSubtitles;
129
130
  private alwaysNewSegments;
131
+ private partialStoreHLSVod;
130
132
  private alwaysMapBandwidthByNearest;
131
133
  private defaultSlateUri?;
132
134
  private slateDuration?;
@@ -89,6 +89,10 @@ var ChannelEngine = /** @class */ (function () {
89
89
  if (options && options.alwaysNewSegments) {
90
90
  this.alwaysNewSegments = true;
91
91
  }
92
+ this.partialStoreHLSVod = false;
93
+ if (options && options.partialStoreHLSVod) {
94
+ this.partialStoreHLSVod = true;
95
+ }
92
96
  this.alwaysMapBandwidthByNearest = false;
93
97
  if (options && options.alwaysMapBandwidthByNearest) {
94
98
  this.alwaysMapBandwidthByNearest = true;
@@ -441,6 +445,7 @@ var ChannelEngine = /** @class */ (function () {
441
445
  subtitleSliceEndpoint: this.subtitleSliceEndpoint,
442
446
  useVTTSubtitles: this.useVTTSubtitles,
443
447
  alwaysNewSegments: options.alwaysNewSegments,
448
+ partialStoreHLSVod: options.partialStoreHLSVod,
444
449
  alwaysMapBandwidthByNearest: options.alwaysMapBandwidthByNearest,
445
450
  noSessionDataTags: options.noSessionDataTags,
446
451
  playheadDiffThreshold: channel.options && channel.options.playheadDiffThreshold ? channel.options.playheadDiffThreshold : this.streamerOpts.defaultPlayheadDiffThreshold,
@@ -50,6 +50,8 @@ declare class Session {
50
50
  isAllowedToClearVodCache: boolean;
51
51
  alwaysNewSegments: any;
52
52
  alwaysMapBandwidthByNearest: any;
53
+ partialStoreHLSVod: any;
54
+ currentPlayheadRef: any;
53
55
  _category: any;
54
56
  startWithId: any;
55
57
  _sessionProfile: any;
@@ -102,10 +102,15 @@ var Session = /** @class */ (function () {
102
102
  this.isAllowedToClearVodCache = null;
103
103
  this.alwaysNewSegments = null;
104
104
  this.alwaysMapBandwidthByNearest = null;
105
+ this.partialStoreHLSVod = null;
106
+ this.currentPlayheadRef = null;
105
107
  if (config) {
106
108
  if (config.alwaysNewSegments) {
107
109
  this.alwaysNewSegments = config.alwaysNewSegments;
108
110
  }
111
+ if (config.partialStoreHLSVod) {
112
+ this.partialStoreHLSVod = config.partialStoreHLSVod;
113
+ }
109
114
  if (config.alwaysMapBandwidthByNearest) {
110
115
  this.alwaysMapBandwidthByNearest = config.alwaysMapBandwidthByNearest;
111
116
  }
@@ -880,7 +885,7 @@ var Session = /** @class */ (function () {
880
885
  };
881
886
  Session.prototype.getCurrentAudioManifestAsync = function (audioGroupId, audioLanguage, playbackSessionId) {
882
887
  return __awaiter(this, void 0, void 0, function () {
883
- var currentVod, sessionState, playheadState, state, DELAY_TIME_MS, ACTION, AGE_THRESH, cacheAge, manifestMseq, manifestDseq, mediaSequenceValue, m3u8_2, err_5;
888
+ var currentVod, sessionState, playheadState, state, DELAY_TIME_MS, ACTION, manifestMseq, manifestDseq, mediaSequenceValue, m3u8_2, err_5;
884
889
  return __generator(this, function (_a) {
885
890
  switch (_a.label) {
886
891
  case 0:
@@ -891,7 +896,7 @@ var Session = /** @class */ (function () {
891
896
  return [4 /*yield*/, this._sessionState.getValues(["discSeqAudio", "vodMediaSeqAudio"])];
892
897
  case 1:
893
898
  sessionState = _a.sent();
894
- return [4 /*yield*/, this._playheadState.getValues(["mediaSeqAudio", "vodMediaSeqAudio"])];
899
+ return [4 /*yield*/, this._playheadState.getValues(["mediaSeqAudio", "vodMediaSeqAudio", "playheadRef"])];
895
900
  case 2:
896
901
  playheadState = _a.sent();
897
902
  if (!(playheadState.vodMediaSeqAudio > sessionState.vodMediaSeqAudio || (playheadState.vodMediaSeqAudio < sessionState.vodMediaSeqAudio && playheadState.mediaSeqAudio === this.prevMediaSeqOffset.audio))) return [3 /*break*/, 6];
@@ -921,16 +926,12 @@ var Session = /** @class */ (function () {
921
926
  currentVod = _a.sent();
922
927
  if (!currentVod) return [3 /*break*/, 15];
923
928
  if (!(playheadState.vodMediaSeqAudio < 2 || playheadState.mediaSeqAudio !== this.prevMediaSeqOffset.audio)) return [3 /*break*/, 11];
924
- AGE_THRESH = this.averageSegmentDuration * 2;
925
- cacheAge = null;
926
- if (this._sessionState.cache && this._sessionState.cache.currentVod.ts) {
927
- cacheAge = Date.now() - this._sessionState.cache.currentVod.ts;
928
- }
929
- if (!(cacheAge !== null && cacheAge > AGE_THRESH)) return [3 /*break*/, 11];
929
+ if (!(playheadState.playheadRef > this.currentPlayheadRef)) return [3 /*break*/, 11];
930
930
  return [4 /*yield*/, timer(500)];
931
931
  case 8:
932
932
  _a.sent();
933
- debug("[".concat(this._sessionId, "]: While requesting audio manifest for ").concat(audioGroupId, "-").concat(audioLanguage, ", (mseq=").concat(playheadState.vodMediaSeqAudio, ")(vod cache age=").concat(cacheAge, ")"));
933
+ this.currentPlayheadRef = playheadState.playheadRef;
934
+ debug("[".concat(this._sessionId, "]: While requesting audio manifest for ").concat(audioGroupId, "-").concat(audioLanguage, ", (mseq=").concat(playheadState.vodMediaSeqAudio, ")"));
934
935
  return [4 /*yield*/, this._sessionState.clearCurrentVodCache()];
935
936
  case 9:
936
937
  _a.sent(); // force reading up from shared store
@@ -973,7 +974,7 @@ var Session = /** @class */ (function () {
973
974
  };
974
975
  Session.prototype.getCurrentSubtitleManifestAsync = function (subtitleGroupId, subtitleLanguage) {
975
976
  return __awaiter(this, void 0, void 0, function () {
976
- var currentVod, sessionState, playheadState, state, DELAY_TIME_MS, ACTION, AGE_THRESH, cacheAge, manifestMseq, manifestDseq, mediaSequenceValue, m3u8_3, err_6;
977
+ var currentVod, sessionState, playheadState, state, DELAY_TIME_MS, ACTION, manifestMseq, manifestDseq, mediaSequenceValue, m3u8_3, err_6;
977
978
  return __generator(this, function (_a) {
978
979
  switch (_a.label) {
979
980
  case 0:
@@ -984,7 +985,7 @@ var Session = /** @class */ (function () {
984
985
  return [4 /*yield*/, this._sessionState.getValues(["discSeqSubtitle", "vodMediaSeqSubtitle"])];
985
986
  case 1:
986
987
  sessionState = _a.sent();
987
- return [4 /*yield*/, this._playheadState.getValues(["mediaSeqSubtitle", "vodMediaSeqSubtitle"])];
988
+ return [4 /*yield*/, this._playheadState.getValues(["mediaSeqSubtitle", "vodMediaSeqSubtitle", "playheadRef"])];
988
989
  case 2:
989
990
  playheadState = _a.sent();
990
991
  if (!(playheadState.vodMediaSeqSubtitle > sessionState.vodMediaSeqSubtitle || (playheadState.vodMediaSeqSubtitle < sessionState.vodMediaSeqSubtitle && playheadState.mediaSeqSubtitle === this.prevMediaSeqOffset.subtitle))) return [3 /*break*/, 6];
@@ -1014,16 +1015,12 @@ var Session = /** @class */ (function () {
1014
1015
  currentVod = _a.sent();
1015
1016
  if (!currentVod) return [3 /*break*/, 15];
1016
1017
  if (!(playheadState.vodMediaSeqSubtitle < 2 || playheadState.mediaSeqSubtitle !== this.prevMediaSeqOffset.subtitle)) return [3 /*break*/, 11];
1017
- AGE_THRESH = this.averageSegmentDuration * 2;
1018
- cacheAge = null;
1019
- if (this._sessionState.cache && this._sessionState.cache.currentVod.ts) {
1020
- cacheAge = Date.now() - this._sessionState.cache.currentVod.ts;
1021
- }
1022
- if (!(cacheAge !== null && cacheAge > AGE_THRESH)) return [3 /*break*/, 11];
1018
+ if (!(playheadState.playheadRef > this.currentPlayheadRef)) return [3 /*break*/, 11];
1023
1019
  return [4 /*yield*/, timer(500)];
1024
1020
  case 8:
1025
1021
  _a.sent();
1026
- debug("[".concat(this._sessionId, "]: While requesting subtitle manifest for ").concat(subtitleGroupId, "-").concat(subtitleLanguage, ", (mseq=").concat(playheadState.vodMediaSeqSubtitle, ")(vod cache age=").concat(cacheAge, ")"));
1022
+ this.currentPlayheadRef = playheadState.playheadRef;
1023
+ debug("[".concat(this._sessionId, "]: While requesting subtitle manifest for ").concat(subtitleGroupId, "-").concat(subtitleLanguage, ", (mseq=").concat(playheadState.vodMediaSeqSubtitle, ")"));
1027
1024
  return [4 /*yield*/, this._sessionState.clearCurrentVodCache()];
1028
1025
  case 9:
1029
1026
  _a.sent(); // force reading up from shared store
@@ -1704,19 +1701,19 @@ var Session = /** @class */ (function () {
1704
1701
  };
1705
1702
  Session.prototype._insertSlate = function (currentVod) {
1706
1703
  return __awaiter(this, void 0, void 0, function () {
1707
- var slateVod, sessionState, endValue, endValueAudio, lastDiscontinuity, lastDiscontinuityAudio, isLeader;
1708
- return __generator(this, function (_a) {
1709
- switch (_a.label) {
1704
+ var slateVod, sessionState, endValue, endValueAudio, lastDiscontinuity, lastDiscontinuityAudio, isLeader, _a;
1705
+ return __generator(this, function (_b) {
1706
+ switch (_b.label) {
1710
1707
  case 0:
1711
1708
  if (!this.slateUri) return [3 /*break*/, 14];
1712
1709
  console.error("[".concat(this._sessionId, "]: Will insert slate"));
1713
1710
  return [4 /*yield*/, this._loadSlate(currentVod)];
1714
1711
  case 1:
1715
- slateVod = _a.sent();
1712
+ slateVod = _b.sent();
1716
1713
  debug("[".concat(this._sessionId, "]: slate loaded"));
1717
1714
  return [4 /*yield*/, this._sessionState.getValues(["slateCount", "mediaSeq", "discSeq", "mediaSeqAudio", "discSeqAudio"])];
1718
1715
  case 2:
1719
- sessionState = _a.sent();
1716
+ sessionState = _b.sent();
1720
1717
  endValue = 0;
1721
1718
  endValueAudio = 0;
1722
1719
  lastDiscontinuity = 0;
@@ -1735,37 +1732,38 @@ var Session = /** @class */ (function () {
1735
1732
  }
1736
1733
  return [4 /*yield*/, this._sessionStateStore.isLeader(this._instanceId)];
1737
1734
  case 3:
1738
- isLeader = _a.sent();
1735
+ isLeader = _b.sent();
1739
1736
  return [4 /*yield*/, this._sessionState.set("vodMediaSeqVideo", 0)];
1740
1737
  case 4:
1741
- _a.sent();
1738
+ _b.sent();
1742
1739
  return [4 /*yield*/, this._sessionState.set("vodMediaSeqAudio", 0)];
1743
1740
  case 5:
1744
- _a.sent();
1741
+ _b.sent();
1745
1742
  return [4 /*yield*/, this._sessionState.set("state", SessionState.VOD_NEXT_INITIATING)];
1746
1743
  case 6:
1747
- _a.sent();
1744
+ _b.sent();
1748
1745
  return [4 /*yield*/, this._sessionState.setCurrentVod(slateVod)];
1749
1746
  case 7:
1750
- _a.sent();
1747
+ _b.sent();
1751
1748
  return [4 /*yield*/, this._sessionState.set("mediaSeq", sessionState.mediaSeq + endValue)];
1752
1749
  case 8:
1753
- _a.sent();
1750
+ _b.sent();
1754
1751
  return [4 /*yield*/, this._sessionState.set("mediaSeqAudio", sessionState.mediaSeqAudio + endValueAudio)];
1755
1752
  case 9:
1756
- _a.sent();
1753
+ _b.sent();
1757
1754
  return [4 /*yield*/, this._sessionState.set("discSeq", sessionState.discSeq + lastDiscontinuity)];
1758
1755
  case 10:
1759
- _a.sent();
1756
+ _b.sent();
1760
1757
  return [4 /*yield*/, this._sessionState.set("discSeqAudio", sessionState.discSeqAudio + lastDiscontinuityAudio)];
1761
1758
  case 11:
1762
- _a.sent();
1759
+ _b.sent();
1763
1760
  return [4 /*yield*/, this._sessionState.set("slateCount", sessionState.slateCount + 1)];
1764
1761
  case 12:
1765
- _a.sent();
1762
+ _b.sent();
1763
+ _a = this;
1766
1764
  return [4 /*yield*/, this._playheadState.set("playheadRef", Date.now(), isLeader)];
1767
1765
  case 13:
1768
- _a.sent();
1766
+ _a.currentPlayheadRef = _b.sent();
1769
1767
  cloudWatchLog(!this.cloudWatchLogging, 'engine-session', { event: 'slateInserted', channel: this._sessionId });
1770
1768
  return [2 /*return*/, slateVod];
1771
1769
  case 14: return [2 /*return*/, null];
@@ -1775,19 +1773,19 @@ var Session = /** @class */ (function () {
1775
1773
  };
1776
1774
  Session.prototype._tickAsync = function () {
1777
1775
  return __awaiter(this, void 0, void 0, function () {
1778
- var newVod, sessionState, isLeader, currentVod, vodResponse, _a, nextVodPromise, nextVodStart, _b, loadPromise, hlsOpts, _c, mediaManifestLoader, audioManifestLoader, loadStart, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, err_7, _s, length_1, endMseqValue, endMseqValueAudio, endMseqValueSubtitle, lastDiscontinuity, lastDiscontinuityAudio, lastDiscontinuitySubtitle, _t, vodPromise, gracePeriod, nextVodStart, _u, loadPromise, hlsOpts, _v, mediaManifestLoader, audioManifestLoader, loadStart, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, diffMs, err_8, startTS, _8, mSeq, currentVod_2, dSeq, mSeqOffset, reloadBehind, segments, playheadState, nextMseq, _9, err_9;
1776
+ var newVod, sessionState, isLeader, currentVod, vodResponse, _a, nextVodPromise, nextVodStart, _b, loadPromise, hlsOpts, _c, mediaManifestLoader, audioManifestLoader, loadStart, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, err_7, _t, length_1, endMseqValue, endMseqValueAudio, endMseqValueSubtitle, lastDiscontinuity, lastDiscontinuityAudio, lastDiscontinuitySubtitle, _u, vodPromise, gracePeriod, nextVodStart, _v, loadPromise, hlsOpts, _w, mediaManifestLoader, audioManifestLoader, loadStart, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, diffMs, err_8, startTS, _10, mSeq, currentVod_2, dSeq, mSeqOffset, reloadBehind, segments, playheadState, nextMseq, _11, _12, err_9;
1779
1777
  var _this = this;
1780
- return __generator(this, function (_10) {
1781
- switch (_10.label) {
1778
+ return __generator(this, function (_13) {
1779
+ switch (_13.label) {
1782
1780
  case 0: return [4 /*yield*/, this._sessionState.getValues(["state", "assetId", "vodMediaSeqVideo", "vodMediaSeqAudio", "vodMediaSeqSubtitle", "mediaSeq", "mediaSeqAudio", "mediaSeqSubtitle", "discSeq", "discSeqAudio", "discSeqSubtitle", "nextVod"])];
1783
1781
  case 1:
1784
- sessionState = _10.sent();
1782
+ sessionState = _13.sent();
1785
1783
  return [4 /*yield*/, this._sessionStateStore.isLeader(this._instanceId)];
1786
1784
  case 2:
1787
- isLeader = _10.sent();
1785
+ isLeader = _13.sent();
1788
1786
  return [4 /*yield*/, this._sessionState.getCurrentVod()];
1789
1787
  case 3:
1790
- currentVod = _10.sent();
1788
+ currentVod = _13.sent();
1791
1789
  if (!sessionState.state) {
1792
1790
  sessionState.state = SessionState.VOD_INIT;
1793
1791
  }
@@ -1803,15 +1801,15 @@ var Session = /** @class */ (function () {
1803
1801
  }
1804
1802
  return [3 /*break*/, 104];
1805
1803
  case 4:
1806
- _10.trys.push([4, 32, , 35]);
1804
+ _13.trys.push([4, 32, , 35]);
1807
1805
  // Needed if store was reset
1808
1806
  return [4 /*yield*/, this._sessionStateStore.clearLeaderCache()];
1809
1807
  case 5:
1810
1808
  // Needed if store was reset
1811
- _10.sent();
1809
+ _13.sent();
1812
1810
  return [4 /*yield*/, this._sessionStateStore.isLeader(this._instanceId)];
1813
1811
  case 6:
1814
- isLeader = _10.sent();
1812
+ isLeader = _13.sent();
1815
1813
  nextVodPromise = void 0;
1816
1814
  if (sessionState.state === SessionState.VOD_INIT) {
1817
1815
  debug("[".concat(this._sessionId, "]: state=VOD_INIT"));
@@ -1825,11 +1823,11 @@ var Session = /** @class */ (function () {
1825
1823
  nextVodStart = Date.now();
1826
1824
  return [4 /*yield*/, nextVodPromise];
1827
1825
  case 7:
1828
- vodResponse = _10.sent();
1826
+ vodResponse = _13.sent();
1829
1827
  _b = sessionState;
1830
1828
  return [4 /*yield*/, this._sessionState.set("nextVod", vodResponse)];
1831
1829
  case 8:
1832
- _b.nextVod = _10.sent();
1830
+ _b.nextVod = _13.sent();
1833
1831
  cloudWatchLog(!this.cloudWatchLogging, 'engine-session', { event: 'nextVod', channel: this._sessionId, reqTimeMs: Date.now() - nextVodStart });
1834
1832
  loadPromise = void 0;
1835
1833
  if (!!vodResponse.type) return [3 /*break*/, 12];
@@ -1840,7 +1838,8 @@ var Session = /** @class */ (function () {
1840
1838
  subtitleSliceEndpoint: this.subtitleSliceEndpoint,
1841
1839
  shouldContainSubtitles: this.use_vtt_subtitles,
1842
1840
  expectedSubtitleTracks: this._subtitleTracks,
1843
- alwaysMapBandwidthByNearest: this.alwaysMapBandwidthByNearest
1841
+ alwaysMapBandwidthByNearest: this.alwaysMapBandwidthByNearest,
1842
+ skipSerializeMediaSequences: this.partialStoreHLSVod
1844
1843
  };
1845
1844
  newVod = new HLSVod(vodResponse.uri, [], vodResponse.unixTs, vodResponse.offset * 1000, m3u8Header(this._instanceId), hlsOpts);
1846
1845
  if (vodResponse.timedMetadata) {
@@ -1852,12 +1851,12 @@ var Session = /** @class */ (function () {
1852
1851
  if (!vodResponse.desiredDuration) return [3 /*break*/, 10];
1853
1852
  return [4 /*yield*/, this._truncateVod(vodResponse)];
1854
1853
  case 9:
1855
- _c = _10.sent(), mediaManifestLoader = _c.mediaManifestLoader, audioManifestLoader = _c.audioManifestLoader;
1854
+ _c = _13.sent(), mediaManifestLoader = _c.mediaManifestLoader, audioManifestLoader = _c.audioManifestLoader;
1856
1855
  loadPromise = currentVod.load(null, mediaManifestLoader, audioManifestLoader);
1857
1856
  return [3 /*break*/, 11];
1858
1857
  case 10:
1859
1858
  loadPromise = currentVod.load();
1860
- _10.label = 11;
1859
+ _13.label = 11;
1861
1860
  case 11: return [3 /*break*/, 13];
1862
1861
  case 12:
1863
1862
  if (vodResponse.type === 'gap') {
@@ -1869,12 +1868,12 @@ var Session = /** @class */ (function () {
1869
1868
  }).catch(reject);
1870
1869
  });
1871
1870
  }
1872
- _10.label = 13;
1871
+ _13.label = 13;
1873
1872
  case 13:
1874
1873
  loadStart = Date.now();
1875
1874
  return [4 /*yield*/, loadPromise];
1876
1875
  case 14:
1877
- _10.sent();
1876
+ _13.sent();
1878
1877
  cloudWatchLog(!this.cloudWatchLogging, 'engine-session', { event: 'loadVod', channel: this._sessionId, loadTimeMs: Date.now() - loadStart });
1879
1878
  debug("[".concat(this._sessionId, "]: first VOD loaded"));
1880
1879
  debug("[".concat(this._sessionId, "]: ").concat(currentVod.getDeltaTimes()));
@@ -1885,42 +1884,39 @@ var Session = /** @class */ (function () {
1885
1884
  return [4 /*yield*/, this._sessionState.set("mediaSeq", 0)];
1886
1885
  case 15:
1887
1886
  //debug(newVod);
1888
- _d.mediaSeq = _10.sent();
1887
+ _d.mediaSeq = _13.sent();
1889
1888
  _e = sessionState;
1890
1889
  return [4 /*yield*/, this._sessionState.set("mediaSeqAudio", 0)];
1891
1890
  case 16:
1892
- _e.mediaSeqAudio = _10.sent();
1891
+ _e.mediaSeqAudio = _13.sent();
1893
1892
  _f = sessionState;
1894
1893
  return [4 /*yield*/, this._sessionState.set("mediaSeqSubtitle", 0)];
1895
1894
  case 17:
1896
- _f.mediaSeqSubtitle = _10.sent();
1895
+ _f.mediaSeqSubtitle = _13.sent();
1897
1896
  _g = sessionState;
1898
1897
  return [4 /*yield*/, this._sessionState.set("discSeq", 0)];
1899
1898
  case 18:
1900
- _g.discSeq = _10.sent();
1899
+ _g.discSeq = _13.sent();
1901
1900
  _h = sessionState;
1902
1901
  return [4 /*yield*/, this._sessionState.set("discSeqAudio", 0)];
1903
1902
  case 19:
1904
- _h.discSeqAudio = _10.sent();
1903
+ _h.discSeqAudio = _13.sent();
1905
1904
  _j = sessionState;
1906
1905
  return [4 /*yield*/, this._sessionState.set("discSeqSubtitle", 0)];
1907
1906
  case 20:
1908
- _j.discSeqSubtitle = _10.sent();
1907
+ _j.discSeqSubtitle = _13.sent();
1909
1908
  _k = sessionState;
1910
1909
  return [4 /*yield*/, this._sessionState.set("vodMediaSeqVideo", 0)];
1911
1910
  case 21:
1912
- _k.vodMediaSeqVideo = _10.sent();
1911
+ _k.vodMediaSeqVideo = _13.sent();
1913
1912
  _l = sessionState;
1914
1913
  return [4 /*yield*/, this._sessionState.set("vodMediaSeqAudio", 0)];
1915
1914
  case 22:
1916
- _l.vodMediaSeqAudio = _10.sent();
1915
+ _l.vodMediaSeqAudio = _13.sent();
1917
1916
  _m = sessionState;
1918
1917
  return [4 /*yield*/, this._sessionState.set("vodMediaSeqSubtitle", 0)];
1919
1918
  case 23:
1920
- _m.vodMediaSeqSubtitle = _10.sent();
1921
- return [4 /*yield*/, this._playheadState.set("playheadRef", Date.now(), isLeader)];
1922
- case 24:
1923
- _10.sent();
1919
+ _m.vodMediaSeqSubtitle = _13.sent();
1924
1920
  this.produceEvent({
1925
1921
  type: 'NOW_PLAYING',
1926
1922
  data: {
@@ -1930,30 +1926,34 @@ var Session = /** @class */ (function () {
1930
1926
  });
1931
1927
  _o = sessionState;
1932
1928
  return [4 /*yield*/, this._sessionState.set("state", SessionState.VOD_PLAYING)];
1933
- case 25:
1934
- _o.state = _10.sent();
1929
+ case 24:
1930
+ _o.state = _13.sent();
1935
1931
  _p = sessionState;
1936
1932
  return [4 /*yield*/, this._sessionState.setCurrentVod(currentVod, { ttl: currentVod.getDuration() * 1000 })];
1933
+ case 25:
1934
+ _p.currentVod = _13.sent();
1935
+ _q = this;
1936
+ return [4 /*yield*/, this._playheadState.set("playheadRef", Date.now(), isLeader)];
1937
1937
  case 26:
1938
- _p.currentVod = _10.sent();
1938
+ _q.currentPlayheadRef = _13.sent();
1939
1939
  return [4 /*yield*/, this._sessionState.remove("nextVod")];
1940
1940
  case 27:
1941
- _10.sent();
1941
+ _13.sent();
1942
1942
  return [2 /*return*/];
1943
1943
  case 28:
1944
1944
  debug("[".concat(this._sessionId, "]: not a leader so will go directly to state VOD_PLAYING"));
1945
- _q = sessionState;
1945
+ _r = sessionState;
1946
1946
  return [4 /*yield*/, this._sessionState.set("state", SessionState.VOD_PLAYING)];
1947
1947
  case 29:
1948
- _q.state = _10.sent();
1949
- _r = sessionState;
1948
+ _r.state = _13.sent();
1949
+ _s = sessionState;
1950
1950
  return [4 /*yield*/, this._sessionState.getCurrentVod()];
1951
1951
  case 30:
1952
- _r.currentVod = _10.sent();
1952
+ _s.currentVod = _13.sent();
1953
1953
  return [2 /*return*/];
1954
1954
  case 31: return [3 /*break*/, 35];
1955
1955
  case 32:
1956
- err_7 = _10.sent();
1956
+ err_7 = _13.sent();
1957
1957
  console.error("[".concat(this._sessionId, "]: Failed to init first VOD"));
1958
1958
  if (this._assetManager.handleError) {
1959
1959
  this._assetManager.handleError(new Error("Failed to init first VOD"), vodResponse);
@@ -1962,10 +1962,10 @@ var Session = /** @class */ (function () {
1962
1962
  debug(err_7);
1963
1963
  return [4 /*yield*/, this._sessionState.remove("nextVod")];
1964
1964
  case 33:
1965
- _10.sent();
1965
+ _13.sent();
1966
1966
  return [4 /*yield*/, this._insertSlate(currentVod)];
1967
1967
  case 34:
1968
- currentVod = _10.sent();
1968
+ currentVod = _13.sent();
1969
1969
  if (!currentVod) {
1970
1970
  debug("No slate to load");
1971
1971
  throw err_7;
@@ -2000,14 +2000,14 @@ var Session = /** @class */ (function () {
2000
2000
  debug("[".concat(this._sessionId, "]: state=VOD_PLAYING, current[").concat(sessionState.vodMediaSeqVideo, "], prev[").concat(this.prevVodMediaSeq.video, "], total[").concat(currentVod.getLiveMediaSequencesCount(), "]"));
2001
2001
  return [4 /*yield*/, this._sessionState.clearCurrentVodCache()];
2002
2002
  case 36:
2003
- _10.sent();
2003
+ _13.sent();
2004
2004
  return [4 /*yield*/, this._sessionState.getCurrentVod()];
2005
2005
  case 37:
2006
- currentVod = _10.sent();
2006
+ currentVod = _13.sent();
2007
2007
  this.prevVodMediaSeq.video = sessionState.vodMediaSeqVideo;
2008
2008
  this.prevVodMediaSeq.audio = sessionState.vodMediaSeqAudio;
2009
2009
  this.prevVodMediaSeq.subtitle = sessionState.vodMediaSeqSubtitle;
2010
- _10.label = 38;
2010
+ _13.label = 38;
2011
2011
  case 38: return [3 /*break*/, 40];
2012
2012
  case 39:
2013
2013
  // Handle edge case where Leader loaded next vod but Follower remained in state=VOD_PLAYING
@@ -2017,7 +2017,7 @@ var Session = /** @class */ (function () {
2017
2017
  // Allow Follower to clear VodCache...
2018
2018
  this.isAllowedToClearVodCache = true;
2019
2019
  }
2020
- _10.label = 40;
2020
+ _13.label = 40;
2021
2021
  case 40:
2022
2022
  debug("[".concat(this._sessionId, "]: state=VOD_PLAYING (").concat(sessionState.vodMediaSeqVideo, "_").concat(sessionState.vodMediaSeqAudio, "_").concat(sessionState.vodMediaSeqSubtitle, ", ").concat(currentVod.getLiveMediaSequencesCount(), "_").concat(currentVod.getLiveMediaSequencesCount("audio"), "_").concat(currentVod.getLiveMediaSequencesCount("subtitle"), ")"));
2023
2023
  return [2 /*return*/];
@@ -2030,15 +2030,15 @@ var Session = /** @class */ (function () {
2030
2030
  this.isAllowedToClearVodCache = true;
2031
2031
  return [2 /*return*/];
2032
2032
  case 42:
2033
- _10.trys.push([42, 74, , 77]);
2033
+ _13.trys.push([42, 74, , 77]);
2034
2034
  debug("[".concat(this._sessionId, "]: state=VOD_NEXT_INIT"));
2035
2035
  if (!isLeader) return [3 /*break*/, 69];
2036
2036
  if (!!currentVod) return [3 /*break*/, 44];
2037
2037
  debug("[".concat(this._sessionId, "]: no VOD to append to, assume first VOD to init"));
2038
- _s = sessionState;
2038
+ _t = sessionState;
2039
2039
  return [4 /*yield*/, this._sessionState.set("state", SessionState.VOD_INIT)];
2040
2040
  case 43:
2041
- _s.state = _10.sent();
2041
+ _t.state = _13.sent();
2042
2042
  return [2 /*return*/];
2043
2043
  case 44:
2044
2044
  length_1 = currentVod.getLiveMediaSequencesCount();
@@ -2058,27 +2058,27 @@ var Session = /** @class */ (function () {
2058
2058
  lastDiscontinuity = currentVod.getLastDiscontinuity();
2059
2059
  lastDiscontinuityAudio = currentVod.getLastDiscontinuityAudio();
2060
2060
  lastDiscontinuitySubtitle = currentVod.getLastDiscontinuitySubtitle();
2061
- _t = sessionState;
2061
+ _u = sessionState;
2062
2062
  return [4 /*yield*/, this._sessionState.set("state", SessionState.VOD_NEXT_INITIATING)];
2063
2063
  case 45:
2064
- _t.state = _10.sent();
2064
+ _u.state = _13.sent();
2065
2065
  vodPromise = this._getNextVod();
2066
2066
  if (!(length_1 === 1)) return [3 /*break*/, 47];
2067
2067
  gracePeriod = (this.averageSegmentDuration / 2);
2068
2068
  debug("[".concat(this._sessionId, "]: adding a grace period before calling nextVod: ").concat(gracePeriod, "ms"));
2069
2069
  return [4 /*yield*/, timer(gracePeriod)];
2070
2070
  case 46:
2071
- _10.sent();
2072
- _10.label = 47;
2071
+ _13.sent();
2072
+ _13.label = 47;
2073
2073
  case 47:
2074
2074
  nextVodStart = Date.now();
2075
2075
  return [4 /*yield*/, vodPromise];
2076
2076
  case 48:
2077
- vodResponse = _10.sent();
2078
- _u = sessionState;
2077
+ vodResponse = _13.sent();
2078
+ _v = sessionState;
2079
2079
  return [4 /*yield*/, this._sessionState.set("nextVod", vodResponse)];
2080
2080
  case 49:
2081
- _u.nextVod = _10.sent();
2081
+ _v.nextVod = _13.sent();
2082
2082
  cloudWatchLog(!this.cloudWatchLogging, 'engine-session', { event: 'nextVod', channel: this._sessionId, reqTimeMs: Date.now() - nextVodStart });
2083
2083
  loadPromise = void 0;
2084
2084
  if (!!vodResponse.type) return [3 /*break*/, 53];
@@ -2089,7 +2089,8 @@ var Session = /** @class */ (function () {
2089
2089
  subtitleSliceEndpoint: this.subtitleSliceEndpoint,
2090
2090
  shouldContainSubtitles: this.use_vtt_subtitles,
2091
2091
  expectedSubtitleTracks: this._subtitleTracks,
2092
- alwaysMapBandwidthByNearest: this.alwaysMapBandwidthByNearest
2092
+ alwaysMapBandwidthByNearest: this.alwaysMapBandwidthByNearest,
2093
+ skipSerializeMediaSequences: this.partialStoreHLSVod
2093
2094
  };
2094
2095
  newVod = new HLSVod(vodResponse.uri, null, vodResponse.unixTs, vodResponse.offset * 1000, m3u8Header(this._instanceId), hlsOpts);
2095
2096
  if (vodResponse.timedMetadata) {
@@ -2108,12 +2109,12 @@ var Session = /** @class */ (function () {
2108
2109
  if (!vodResponse.desiredDuration) return [3 /*break*/, 51];
2109
2110
  return [4 /*yield*/, this._truncateVod(vodResponse)];
2110
2111
  case 50:
2111
- _v = _10.sent(), mediaManifestLoader = _v.mediaManifestLoader, audioManifestLoader = _v.audioManifestLoader;
2112
+ _w = _13.sent(), mediaManifestLoader = _w.mediaManifestLoader, audioManifestLoader = _w.audioManifestLoader;
2112
2113
  loadPromise = newVod.loadAfter(currentVod, null, mediaManifestLoader, audioManifestLoader);
2113
2114
  return [3 /*break*/, 52];
2114
2115
  case 51:
2115
2116
  loadPromise = newVod.loadAfter(currentVod);
2116
- _10.label = 52;
2117
+ _13.label = 52;
2117
2118
  case 52:
2118
2119
  if (vodResponse.diffMs) {
2119
2120
  this.diffCompensation = vodResponse.diffMs;
@@ -2134,12 +2135,12 @@ var Session = /** @class */ (function () {
2134
2135
  resolve(newVod);
2135
2136
  }).catch(reject);
2136
2137
  });
2137
- _10.label = 54;
2138
+ _13.label = 54;
2138
2139
  case 54:
2139
2140
  loadStart = Date.now();
2140
2141
  return [4 /*yield*/, ChaosMonkey.loadVod(loadPromise)];
2141
2142
  case 55:
2142
- _10.sent();
2143
+ _13.sent();
2143
2144
  cloudWatchLog(!this.cloudWatchLogging, 'engine-session', { event: 'loadVod', channel: this._sessionId, loadTimeMs: Date.now() - loadStart });
2144
2145
  this.leaderIsSettingNextVod = true;
2145
2146
  debug("[".concat(this._sessionId, "]: next VOD loaded (").concat(newVod.getDeltaTimes(), ")"));
@@ -2147,57 +2148,58 @@ var Session = /** @class */ (function () {
2147
2148
  debug("[".concat(this._sessionId, "]: playhead positions [A]=").concat(newVod.getPlayheadPositions("audio")));
2148
2149
  currentVod = newVod;
2149
2150
  debug("[".concat(this._sessionId, "]: msequences=").concat(currentVod.getLiveMediaSequencesCount(), "; audio msequences=").concat(currentVod.getLiveMediaSequencesCount("audio"), "; subtitle msequences=").concat(currentVod.getLiveMediaSequencesCount("subtitle")));
2150
- _w = sessionState;
2151
+ _x = sessionState;
2151
2152
  return [4 /*yield*/, this._sessionState.setCurrentVod(currentVod, { ttl: currentVod.getDuration() * 1000 })];
2152
2153
  case 56:
2153
- _w.currentVod = _10.sent();
2154
+ _x.currentVod = _13.sent();
2155
+ _y = this;
2154
2156
  return [4 /*yield*/, this._playheadState.set("playheadRef", Date.now(), isLeader)];
2155
2157
  case 57:
2156
- _10.sent();
2157
- _x = sessionState;
2158
+ _y.currentPlayheadRef = _13.sent();
2159
+ _z = sessionState;
2158
2160
  return [4 /*yield*/, this._sessionState.set("vodMediaSeqVideo", 0)];
2159
2161
  case 58:
2160
- _x.vodMediaSeqVideo = _10.sent();
2161
- _y = sessionState;
2162
+ _z.vodMediaSeqVideo = _13.sent();
2163
+ _0 = sessionState;
2162
2164
  return [4 /*yield*/, this._sessionState.set("vodMediaSeqAudio", 0)];
2163
2165
  case 59:
2164
- _y.vodMediaSeqAudio = _10.sent();
2165
- _z = sessionState;
2166
+ _0.vodMediaSeqAudio = _13.sent();
2167
+ _1 = sessionState;
2166
2168
  return [4 /*yield*/, this._sessionState.set("vodMediaSeqSubtitle", 0)];
2167
2169
  case 60:
2168
- _z.vodMediaSeqSubtitle = _10.sent();
2169
- _0 = sessionState;
2170
+ _1.vodMediaSeqSubtitle = _13.sent();
2171
+ _2 = sessionState;
2170
2172
  return [4 /*yield*/, this._sessionState.set("mediaSeq", sessionState.mediaSeq + endMseqValue)];
2171
2173
  case 61:
2172
- _0.mediaSeq = _10.sent();
2173
- _1 = sessionState;
2174
+ _2.mediaSeq = _13.sent();
2175
+ _3 = sessionState;
2174
2176
  return [4 /*yield*/, this._sessionState.set("mediaSeqAudio", sessionState.mediaSeqAudio + endMseqValueAudio)];
2175
2177
  case 62:
2176
- _1.mediaSeqAudio = _10.sent();
2177
- _2 = sessionState;
2178
+ _3.mediaSeqAudio = _13.sent();
2179
+ _4 = sessionState;
2178
2180
  return [4 /*yield*/, this._sessionState.set("mediaSeqSubtitle", sessionState.mediaSeqSubtitle + endMseqValueSubtitle)];
2179
2181
  case 63:
2180
- _2.mediaSeqSubtitle = _10.sent();
2181
- _3 = sessionState;
2182
+ _4.mediaSeqSubtitle = _13.sent();
2183
+ _5 = sessionState;
2182
2184
  return [4 /*yield*/, this._sessionState.set("discSeq", sessionState.discSeq + lastDiscontinuity)];
2183
2185
  case 64:
2184
- _3.discSeq = _10.sent();
2185
- _4 = sessionState;
2186
+ _5.discSeq = _13.sent();
2187
+ _6 = sessionState;
2186
2188
  return [4 /*yield*/, this._sessionState.set("discSeqAudio", sessionState.discSeqAudio + lastDiscontinuityAudio)];
2187
2189
  case 65:
2188
- _4.discSeqAudio = _10.sent();
2189
- _5 = sessionState;
2190
+ _6.discSeqAudio = _13.sent();
2191
+ _7 = sessionState;
2190
2192
  return [4 /*yield*/, this._sessionState.set("discSeqSubtitle", sessionState.discSeqSubtitle + lastDiscontinuitySubtitle)];
2191
2193
  case 66:
2192
- _5.discSeqSubtitle = _10.sent();
2194
+ _7.discSeqSubtitle = _13.sent();
2193
2195
  debug("[".concat(this._sessionId, "]: new sequence data set in store V[").concat(sessionState.mediaSeq, "][").concat(sessionState.discSeq, "]_A[").concat(sessionState.mediaSeqAudio, "][").concat(sessionState.discSeqAudio, "]_S[").concat(sessionState.mediaSeqSubtitle, "][").concat(sessionState.discSeqSubtitle, "]"));
2194
2196
  return [4 /*yield*/, this._sessionState.remove("nextVod")];
2195
2197
  case 67:
2196
- _10.sent();
2198
+ _13.sent();
2197
2199
  this.leaderIsSettingNextVod = false;
2198
2200
  return [4 /*yield*/, this._playheadState.set("diffCompensation", this.diffCompensation, isLeader)];
2199
2201
  case 68:
2200
- _10.sent();
2202
+ _13.sent();
2201
2203
  debug("[".concat(this._sessionId, "]: sharing durrent vods diffCompensation=").concat(this.diffCompensation));
2202
2204
  this.produceEvent({
2203
2205
  type: 'NOW_PLAYING',
@@ -2210,19 +2212,19 @@ var Session = /** @class */ (function () {
2210
2212
  case 69:
2211
2213
  debug("[".concat(this._sessionId, "]: not a leader so will go directly to state VOD_NEXT_INITIATING"));
2212
2214
  this.waitingForNextVod = true;
2213
- _6 = sessionState;
2215
+ _8 = sessionState;
2214
2216
  return [4 /*yield*/, this._sessionState.set("state", SessionState.VOD_NEXT_INITIATING)];
2215
2217
  case 70:
2216
- _6.state = _10.sent();
2218
+ _8.state = _13.sent();
2217
2219
  // Allow Leader|Follower to clear vodCache...
2218
2220
  this.isAllowedToClearVodCache = true;
2219
- _7 = sessionState;
2221
+ _9 = sessionState;
2220
2222
  return [4 /*yield*/, this._sessionState.getCurrentVod()];
2221
2223
  case 71:
2222
- _7.currentVod = _10.sent();
2224
+ _9.currentVod = _13.sent();
2223
2225
  return [4 /*yield*/, this._playheadState.get("diffCompensation")];
2224
2226
  case 72:
2225
- diffMs = _10.sent();
2227
+ diffMs = _13.sent();
2226
2228
  if (diffMs) {
2227
2229
  this.diffCompensation = diffMs;
2228
2230
  debug("[".concat(this._sessionId, "]: Setting diffCompensation=").concat(this.diffCompensation));
@@ -2234,10 +2236,10 @@ var Session = /** @class */ (function () {
2234
2236
  this.timePositionOffset = 0;
2235
2237
  }
2236
2238
  }
2237
- _10.label = 73;
2239
+ _13.label = 73;
2238
2240
  case 73: return [3 /*break*/, 77];
2239
2241
  case 74:
2240
- err_8 = _10.sent();
2242
+ err_8 = _13.sent();
2241
2243
  console.error("[".concat(this._sessionId, "]: Failed to init next VOD"));
2242
2244
  debug("[".concat(this._sessionId, "]: ").concat(err_8));
2243
2245
  if (this._assetManager.handleError) {
@@ -2246,10 +2248,10 @@ var Session = /** @class */ (function () {
2246
2248
  cloudWatchLog(!this.cloudWatchLogging, 'engine-session', { event: 'error', on: 'nextvod', channel: this._sessionId, err: err_8, vod: vodResponse });
2247
2249
  return [4 /*yield*/, this._sessionState.remove("nextVod")];
2248
2250
  case 75:
2249
- _10.sent();
2251
+ _13.sent();
2250
2252
  return [4 /*yield*/, this._insertSlate(currentVod)];
2251
2253
  case 76:
2252
- currentVod = _10.sent();
2254
+ currentVod = _13.sent();
2253
2255
  if (!currentVod) {
2254
2256
  debug("No slate to load");
2255
2257
  throw err_8;
@@ -2259,20 +2261,20 @@ var Session = /** @class */ (function () {
2259
2261
  return [3 /*break*/, 77];
2260
2262
  case 77: return [3 /*break*/, 105];
2261
2263
  case 78:
2262
- _10.trys.push([78, 98, , 99]);
2264
+ _13.trys.push([78, 98, , 99]);
2263
2265
  debug("[".concat(this._sessionId, "]: state=VOD_RELOAD_INIT"));
2264
2266
  if (!isLeader) return [3 /*break*/, 95];
2265
2267
  startTS = Date.now();
2266
2268
  // 1) To tell Follower that, Leader is working on it!
2267
- _8 = sessionState;
2269
+ _10 = sessionState;
2268
2270
  return [4 /*yield*/, this._sessionState.set("state", SessionState.VOD_RELOAD_INITIATING)];
2269
2271
  case 79:
2270
2272
  // 1) To tell Follower that, Leader is working on it!
2271
- _8.state = _10.sent();
2273
+ _10.state = _13.sent();
2272
2274
  mSeq = this.switchDataForSession.mediaSeq;
2273
2275
  return [4 /*yield*/, this._sessionState.getCurrentVod()];
2274
2276
  case 80:
2275
- currentVod_2 = _10.sent();
2277
+ currentVod_2 = _13.sent();
2276
2278
  if (currentVod_2.sequenceAlwaysContainNewSegments) {
2277
2279
  // (!) will need to compensate if using this setting on HLSVod Object.
2278
2280
  Object.keys(this.switchDataForSession.transitionSegments).forEach(function (bw) {
@@ -2292,20 +2294,20 @@ var Session = /** @class */ (function () {
2292
2294
  }
2293
2295
  return [4 /*yield*/, this._sessionState.set("mediaSeq", mSeq)];
2294
2296
  case 81:
2295
- _10.sent();
2297
+ _13.sent();
2296
2298
  return [4 /*yield*/, this._playheadState.set("mediaSeq", mSeq, isLeader)];
2297
2299
  case 82:
2298
- _10.sent();
2300
+ _13.sent();
2299
2301
  return [4 /*yield*/, this._sessionState.set("discSeq", dSeq)];
2300
2302
  case 83:
2301
- _10.sent();
2303
+ _13.sent();
2302
2304
  // TODO: support demux^
2303
2305
  debug("[".concat(this._sessionId, "]: Setting current media and discontinuity count -> [").concat(mSeq, "]:[").concat(dSeq, "]"));
2304
2306
  // 3) Set new media segments/currentVod, to carry on the continuity from session-live
2305
2307
  debug("[".concat(this._sessionId, "]: LEADER: making changes to current VOD. I will also update currentVod in store."));
2306
2308
  return [4 /*yield*/, this._playheadState.getValues(["vodMediaSeqVideo"])];
2307
2309
  case 84:
2308
- playheadState = _10.sent();
2310
+ playheadState = _13.sent();
2309
2311
  nextMseq = playheadState.vodMediaSeqVideo + 1;
2310
2312
  if (nextMseq > currentVod_2.getLiveMediaSequencesCount() - 1) {
2311
2313
  nextMseq = currentVod_2.getLiveMediaSequencesCount() - 1;
@@ -2318,34 +2320,35 @@ var Session = /** @class */ (function () {
2318
2320
  // ---------------------------------------------------.
2319
2321
  // TODO: Support reloading with audioSegments and SubtitleSegments as well |
2320
2322
  // ---------------------------------------------------'
2321
- _10.sent();
2323
+ _13.sent();
2322
2324
  return [4 /*yield*/, this._sessionState.setCurrentVod(currentVod_2, { ttl: currentVod_2.getDuration() * 1000 })];
2323
2325
  case 86:
2324
- _10.sent();
2326
+ _13.sent();
2325
2327
  return [4 /*yield*/, this._sessionState.set("vodReloaded", 1)];
2326
2328
  case 87:
2327
- _10.sent();
2329
+ _13.sent();
2328
2330
  return [4 /*yield*/, this._sessionState.set("vodMediaSeqVideo", 0)];
2329
2331
  case 88:
2330
- _10.sent();
2332
+ _13.sent();
2331
2333
  return [4 /*yield*/, this._sessionState.set("vodMediaSeqAudio", 0)];
2332
2334
  case 89:
2333
- _10.sent();
2335
+ _13.sent();
2334
2336
  return [4 /*yield*/, this._sessionState.set("vodMediaSeqSubtitle", 0)];
2335
2337
  case 90:
2336
- _10.sent();
2338
+ _13.sent();
2337
2339
  return [4 /*yield*/, this._playheadState.set("vodMediaSeqVideo", 0, isLeader)];
2338
2340
  case 91:
2339
- _10.sent();
2341
+ _13.sent();
2340
2342
  return [4 /*yield*/, this._playheadState.set("vodMediaSeqAudio", 0, isLeader)];
2341
2343
  case 92:
2342
- _10.sent();
2344
+ _13.sent();
2343
2345
  return [4 /*yield*/, this._playheadState.set("vodMediaSeqSubtitle", 0, isLeader)];
2344
2346
  case 93:
2345
- _10.sent();
2347
+ _13.sent();
2348
+ _11 = this;
2346
2349
  return [4 /*yield*/, this._playheadState.set("playheadRef", Date.now(), isLeader)];
2347
2350
  case 94:
2348
- _10.sent();
2351
+ _11.currentPlayheadRef = _13.sent();
2349
2352
  // 4) Log to debug and cloudwatch
2350
2353
  debug("[".concat(this._sessionId, "]: LEADER: Set new Reloaded VOD and vodMediaSeq counts in store."));
2351
2354
  debug("[".concat(this._sessionId, "]: next VOD Reloaded (").concat(currentVod_2.getDeltaTimes(), ")"));
@@ -2355,14 +2358,14 @@ var Session = /** @class */ (function () {
2355
2358
  return [2 /*return*/];
2356
2359
  case 95:
2357
2360
  debug("[".concat(this._sessionId, "]: not a leader so will go directly to state VOD_RELOAD_INITIATING"));
2358
- _9 = sessionState;
2361
+ _12 = sessionState;
2359
2362
  return [4 /*yield*/, this._sessionState.set("state", SessionState.VOD_RELOAD_INITIATING)];
2360
2363
  case 96:
2361
- _9.state = _10.sent();
2362
- _10.label = 97;
2364
+ _12.state = _13.sent();
2365
+ _13.label = 97;
2363
2366
  case 97: return [3 /*break*/, 99];
2364
2367
  case 98:
2365
- err_9 = _10.sent();
2368
+ err_9 = _13.sent();
2366
2369
  debug("Failed to init reload vod");
2367
2370
  throw err_9;
2368
2371
  case 99: return [3 /*break*/, 105];
@@ -2374,11 +2377,11 @@ var Session = /** @class */ (function () {
2374
2377
  debug("[".concat(this._sessionId, "]: First mediasequence in VOD and I am not the leader so invalidate current VOD cache and fetch the new one from the leader"));
2375
2378
  return [4 /*yield*/, this._sessionState.clearCurrentVodCache()];
2376
2379
  case 101:
2377
- _10.sent();
2378
- _10.label = 102;
2380
+ _13.sent();
2381
+ _13.label = 102;
2379
2382
  case 102:
2380
2383
  this.waitingForNextVod = true;
2381
- _10.label = 103;
2384
+ _13.label = 103;
2382
2385
  case 103:
2383
2386
  // Allow Leader|Follower to clear vodCache...
2384
2387
  this.isAllowedToClearVodCache = true;
@@ -2435,7 +2438,8 @@ var Session = /** @class */ (function () {
2435
2438
  subtitleSliceEndpoint: _this.subtitleSliceEndpoint,
2436
2439
  shouldContainSubtitles: _this.use_vtt_subtitles,
2437
2440
  expectedSubtitleTracks: _this._subtitleTracks,
2438
- alwaysMapBandwidthByNearest: _this.alwaysMapBandwidthByNearest
2441
+ alwaysMapBandwidthByNearest: _this.alwaysMapBandwidthByNearest,
2442
+ skipSerializeMediaSequences: _this.partialStoreHLSVod
2439
2443
  };
2440
2444
  var timestamp = Date.now();
2441
2445
  hlsVod_1 = new HLSVod(_this.slateUri, null, timestamp, null, m3u8Header(_this._instanceId), hlsOpts);
@@ -2543,7 +2547,8 @@ var Session = /** @class */ (function () {
2543
2547
  subtitleSliceEndpoint: _this.subtitleSliceEndpoint,
2544
2548
  shouldContainSubtitles: _this.use_vtt_subtitles,
2545
2549
  expectedSubtitleTracks: _this._subtitleTracks,
2546
- alwaysMapBandwidthByNearest: _this.alwaysMapBandwidthByNearest
2550
+ alwaysMapBandwidthByNearest: _this.alwaysMapBandwidthByNearest,
2551
+ skipSerializeMediaSequences: _this.partialStoreHLSVod
2547
2552
  };
2548
2553
  var timestamp = Date.now();
2549
2554
  hlsVod_2 = new HLSVod(nexVodUri, null, timestamp, null, m3u8Header(_this._instanceId), hlsOpts);
@@ -92,7 +92,7 @@ var SharedSessionState = /** @class */ (function () {
92
92
  };
93
93
  SharedSessionState.prototype.getCurrentVod = function () {
94
94
  return __awaiter(this, void 0, void 0, function () {
95
- var currentVod, hlsVod;
95
+ var currentVod, hlsVod, strToMB;
96
96
  return __generator(this, function (_a) {
97
97
  switch (_a.label) {
98
98
  case 0:
@@ -107,16 +107,27 @@ var SharedSessionState = /** @class */ (function () {
107
107
  case 1:
108
108
  currentVod = _a.sent();
109
109
  hlsVod = null;
110
- if (currentVod) {
111
- if (this.store.isShared()) {
112
- debug("[".concat(this.sessionId, "]: reading ").concat(currentVod.length, " characters from shared store (").concat(Date.now(), " < ").concat(this.cache.currentVod.ts + this.cache.currentVod.ttl, ")"));
113
- hlsVod = new HLSVod();
114
- hlsVod.fromJSON(currentVod);
115
- }
116
- else {
117
- hlsVod = currentVod;
118
- }
119
- }
110
+ if (!currentVod) return [3 /*break*/, 5];
111
+ if (!this.store.isShared()) return [3 /*break*/, 4];
112
+ strToMB = function (str) {
113
+ var bytesPerCharacter = 2; // Assuming each character takes around 2 bytes in memory
114
+ var stringSizeBytes = str.length * bytesPerCharacter;
115
+ var sizeInMegabytes = stringSizeBytes / (1024 * 1024);
116
+ return sizeInMegabytes.toFixed(1);
117
+ };
118
+ debug("[".concat(this.sessionId, "]: reading ").concat(currentVod.length, " characters or (").concat(strToMB(currentVod), " MB) from shared store (").concat(Date.now(), " < ").concat(this.cache.currentVod.ts + this.cache.currentVod.ttl, ")"));
119
+ hlsVod = new HLSVod();
120
+ hlsVod.fromJSON(currentVod);
121
+ if (!hlsVod.skipSerializeMediaSequences) return [3 /*break*/, 3];
122
+ return [4 /*yield*/, hlsVod.generateMediaSequences()];
123
+ case 2:
124
+ _a.sent();
125
+ _a.label = 3;
126
+ case 3: return [3 /*break*/, 5];
127
+ case 4:
128
+ hlsVod = currentVod;
129
+ _a.label = 5;
130
+ case 5:
120
131
  this.cache.currentVod.ts = Date.now();
121
132
  this.cache.currentVod.value = hlsVod;
122
133
  return [2 /*return*/, hlsVod];
@@ -133,7 +144,7 @@ var SharedSessionState = /** @class */ (function () {
133
144
  if (!this.sessionId) {
134
145
  throw new Error("shared session state store has not been initialized");
135
146
  }
136
- if (!this.store.isShared()) return [3 /*break*/, 7];
147
+ if (!this.store.isShared()) return [3 /*break*/, 8];
137
148
  return [4 /*yield*/, this.store.clearLeaderCache()];
138
149
  case 1:
139
150
  _a.sent();
@@ -144,7 +155,7 @@ var SharedSessionState = /** @class */ (function () {
144
155
  return [4 /*yield*/, this.set("currentVod", hlsVod.toJSON())];
145
156
  case 3:
146
157
  _a.sent();
147
- return [3 /*break*/, 6];
158
+ return [3 /*break*/, 7];
148
159
  case 4:
149
160
  debug("[".concat(this.sessionId, "]: Not a leader. Will not overwrite. Getting currentVod in shared store"));
150
161
  return [4 /*yield*/, this.get("currentVod")];
@@ -152,13 +163,17 @@ var SharedSessionState = /** @class */ (function () {
152
163
  currentVod = _a.sent();
153
164
  hlsVod = new HLSVod();
154
165
  hlsVod.fromJSON(currentVod);
155
- _a.label = 6;
156
- case 6: return [3 /*break*/, 9];
157
- case 7: return [4 /*yield*/, this.set("currentVod", hlsVod)];
158
- case 8:
166
+ if (!hlsVod.skipSerializeMediaSequences) return [3 /*break*/, 7];
167
+ return [4 /*yield*/, hlsVod.generateMediaSequences()];
168
+ case 6:
159
169
  _a.sent();
160
- _a.label = 9;
170
+ _a.label = 7;
171
+ case 7: return [3 /*break*/, 10];
172
+ case 8: return [4 /*yield*/, this.set("currentVod", hlsVod)];
161
173
  case 9:
174
+ _a.sent();
175
+ _a.label = 10;
176
+ case 10:
162
177
  if (this.cache.currentVod) {
163
178
  this.cache.currentVod.ts = Date.now();
164
179
  this.cache.currentVod.ttl = CURRENTVOD_CACHE_TTL;
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eyevinn-channel-engine",
3
- "version": "4.2.10",
3
+ "version": "4.3.0",
4
4
  "description": "OTT TV Channel Engine",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -30,7 +30,7 @@
30
30
  "dependencies": {
31
31
  "@eyevinn/hls-repeat": "^0.2.0",
32
32
  "@eyevinn/hls-truncate": "^0.3.0",
33
- "@eyevinn/hls-vodtolive": "^3.1.1",
33
+ "@eyevinn/hls-vodtolive": "^4.0.0",
34
34
  "@eyevinn/m3u8": "^0.5.3",
35
35
  "abort-controller": "^3.0.0",
36
36
  "debug": "^3.2.7",
package/engine/server.ts CHANGED
@@ -46,6 +46,7 @@ export interface ChannelEngineOpts {
46
46
  subtitleSliceEndpoint?: string;
47
47
  useVTTSubtitles?: boolean;
48
48
  alwaysNewSegments?: boolean;
49
+ partialStoreHLSVod?: boolean;
49
50
  alwaysMapBandwidthByNearest?: boolean;
50
51
  diffCompensationRate?: number;
51
52
  staticDirectory?: string;
@@ -183,6 +184,7 @@ export class ChannelEngine {
183
184
  private subtitleSliceEndpoint: string;
184
185
  private useVTTSubtitles: boolean;
185
186
  private alwaysNewSegments: boolean;
187
+ private partialStoreHLSVod: boolean;
186
188
  private alwaysMapBandwidthByNearest: boolean;
187
189
  private defaultSlateUri?: string;
188
190
  private slateDuration?: number;
@@ -223,6 +225,10 @@ export class ChannelEngine {
223
225
  if (options && options.alwaysNewSegments) {
224
226
  this.alwaysNewSegments = true;
225
227
  }
228
+ this.partialStoreHLSVod = false;
229
+ if (options && options.partialStoreHLSVod) {
230
+ this.partialStoreHLSVod = true;
231
+ }
226
232
  this.alwaysMapBandwidthByNearest = false;
227
233
  if (options && options.alwaysMapBandwidthByNearest) {
228
234
  this.alwaysMapBandwidthByNearest = true;
@@ -460,6 +466,7 @@ export class ChannelEngine {
460
466
  subtitleSliceEndpoint: this.subtitleSliceEndpoint,
461
467
  useVTTSubtitles: this.useVTTSubtitles,
462
468
  alwaysNewSegments: options.alwaysNewSegments,
469
+ partialStoreHLSVod: options.partialStoreHLSVod,
463
470
  alwaysMapBandwidthByNearest: options.alwaysMapBandwidthByNearest,
464
471
  noSessionDataTags: options.noSessionDataTags,
465
472
  playheadDiffThreshold: channel.options && channel.options.playheadDiffThreshold ? channel.options.playheadDiffThreshold : this.streamerOpts.defaultPlayheadDiffThreshold,
package/engine/session.js CHANGED
@@ -73,11 +73,17 @@ class Session {
73
73
  this.isAllowedToClearVodCache = null;
74
74
  this.alwaysNewSegments = null;
75
75
  this.alwaysMapBandwidthByNearest = null;
76
+ this.partialStoreHLSVod = null;
77
+ this.currentPlayheadRef = null;
76
78
  if (config) {
77
79
  if (config.alwaysNewSegments) {
78
80
  this.alwaysNewSegments = config.alwaysNewSegments;
79
81
  }
80
82
 
83
+ if (config.partialStoreHLSVod) {
84
+ this.partialStoreHLSVod = config.partialStoreHLSVod;
85
+ }
86
+
81
87
  if (config.alwaysMapBandwidthByNearest) {
82
88
  this.alwaysMapBandwidthByNearest = config.alwaysMapBandwidthByNearest;
83
89
  }
@@ -637,7 +643,7 @@ class Session {
637
643
  }
638
644
  let currentVod = null;
639
645
  const sessionState = await this._sessionState.getValues(["discSeqAudio", "vodMediaSeqAudio"]);
640
- let playheadState = await this._playheadState.getValues(["mediaSeqAudio", "vodMediaSeqAudio"]);
646
+ let playheadState = await this._playheadState.getValues(["mediaSeqAudio", "vodMediaSeqAudio", "playheadRef"]);
641
647
 
642
648
  if (playheadState.vodMediaSeqAudio > sessionState.vodMediaSeqAudio || (playheadState.vodMediaSeqAudio < sessionState.vodMediaSeqAudio && playheadState.mediaSeqAudio === this.prevMediaSeqOffset.audio)) {
643
649
  const state = await this._sessionState.get("state");
@@ -658,14 +664,10 @@ class Session {
658
664
  if (currentVod) {
659
665
  // condition suggesting that a new vod should exist
660
666
  if (playheadState.vodMediaSeqAudio < 2 || playheadState.mediaSeqAudio !== this.prevMediaSeqOffset.audio) {
661
- const AGE_THRESH = this.averageSegmentDuration * 2;
662
- let cacheAge = null;
663
- if (this._sessionState.cache && this._sessionState.cache.currentVod.ts) {
664
- cacheAge = Date.now() - this._sessionState.cache.currentVod.ts;
665
- }
666
- if (cacheAge !== null && cacheAge > AGE_THRESH) {
667
+ if (playheadState.playheadRef > this.currentPlayheadRef) {
667
668
  await timer(500);
668
- debug(`[${this._sessionId}]: While requesting audio manifest for ${audioGroupId}-${audioLanguage}, (mseq=${playheadState.vodMediaSeqAudio})(vod cache age=${cacheAge})`);
669
+ this.currentPlayheadRef = playheadState.playheadRef;
670
+ debug(`[${this._sessionId}]: While requesting audio manifest for ${audioGroupId}-${audioLanguage}, (mseq=${playheadState.vodMediaSeqAudio})`);
669
671
  await this._sessionState.clearCurrentVodCache(); // force reading up from shared store
670
672
  currentVod = await this._sessionState.getCurrentVod();
671
673
  }
@@ -712,7 +714,7 @@ class Session {
712
714
  }
713
715
  let currentVod = null;
714
716
  const sessionState = await this._sessionState.getValues(["discSeqSubtitle", "vodMediaSeqSubtitle"]);
715
- let playheadState = await this._playheadState.getValues(["mediaSeqSubtitle", "vodMediaSeqSubtitle"]);
717
+ let playheadState = await this._playheadState.getValues(["mediaSeqSubtitle", "vodMediaSeqSubtitle", "playheadRef"]);
716
718
 
717
719
  if (playheadState.vodMediaSeqSubtitle > sessionState.vodMediaSeqSubtitle || (playheadState.vodMediaSeqSubtitle < sessionState.vodMediaSeqSubtitle && playheadState.mediaSeqSubtitle === this.prevMediaSeqOffset.subtitle)) {
718
720
  const state = await this._sessionState.get("state");
@@ -733,14 +735,10 @@ class Session {
733
735
  if (currentVod) {
734
736
  // condition suggesting that a new vod should exist
735
737
  if (playheadState.vodMediaSeqSubtitle < 2 || playheadState.mediaSeqSubtitle !== this.prevMediaSeqOffset.subtitle) {
736
- const AGE_THRESH = this.averageSegmentDuration * 2;
737
- let cacheAge = null;
738
- if (this._sessionState.cache && this._sessionState.cache.currentVod.ts) {
739
- cacheAge = Date.now() - this._sessionState.cache.currentVod.ts;
740
- }
741
- if (cacheAge !== null && cacheAge > AGE_THRESH) {
738
+ if (playheadState.playheadRef > this.currentPlayheadRef) {
742
739
  await timer(500);
743
- debug(`[${this._sessionId}]: While requesting subtitle manifest for ${subtitleGroupId}-${subtitleLanguage}, (mseq=${playheadState.vodMediaSeqSubtitle})(vod cache age=${cacheAge})`);
740
+ this.currentPlayheadRef = playheadState.playheadRef;
741
+ debug(`[${this._sessionId}]: While requesting subtitle manifest for ${subtitleGroupId}-${subtitleLanguage}, (mseq=${playheadState.vodMediaSeqSubtitle})`);
744
742
  await this._sessionState.clearCurrentVodCache(); // force reading up from shared store
745
743
  currentVod = await this._sessionState.getCurrentVod();
746
744
  }
@@ -1275,7 +1273,7 @@ class Session {
1275
1273
  await this._sessionState.set("discSeq", sessionState.discSeq + lastDiscontinuity);
1276
1274
  await this._sessionState.set("discSeqAudio", sessionState.discSeqAudio + lastDiscontinuityAudio);
1277
1275
  await this._sessionState.set("slateCount", sessionState.slateCount + 1);
1278
- await this._playheadState.set("playheadRef", Date.now(), isLeader);
1276
+ this.currentPlayheadRef = await this._playheadState.set("playheadRef", Date.now(), isLeader);
1279
1277
 
1280
1278
  cloudWatchLog(!this.cloudWatchLogging, 'engine-session', { event: 'slateInserted', channel: this._sessionId });
1281
1279
 
@@ -1331,7 +1329,8 @@ class Session {
1331
1329
  subtitleSliceEndpoint: this.subtitleSliceEndpoint,
1332
1330
  shouldContainSubtitles: this.use_vtt_subtitles,
1333
1331
  expectedSubtitleTracks: this._subtitleTracks,
1334
- alwaysMapBandwidthByNearest: this.alwaysMapBandwidthByNearest
1332
+ alwaysMapBandwidthByNearest: this.alwaysMapBandwidthByNearest,
1333
+ skipSerializeMediaSequences: this.partialStoreHLSVod
1335
1334
  };
1336
1335
  newVod = new HLSVod(vodResponse.uri, [], vodResponse.unixTs, vodResponse.offset * 1000, m3u8Header(this._instanceId), hlsOpts);
1337
1336
  if (vodResponse.timedMetadata) {
@@ -1375,7 +1374,6 @@ class Session {
1375
1374
  sessionState.vodMediaSeqVideo = await this._sessionState.set("vodMediaSeqVideo", 0);
1376
1375
  sessionState.vodMediaSeqAudio = await this._sessionState.set("vodMediaSeqAudio", 0);
1377
1376
  sessionState.vodMediaSeqSubtitle = await this._sessionState.set("vodMediaSeqSubtitle", 0);
1378
- await this._playheadState.set("playheadRef", Date.now(), isLeader);
1379
1377
  this.produceEvent({
1380
1378
  type: 'NOW_PLAYING',
1381
1379
  data: {
@@ -1385,6 +1383,7 @@ class Session {
1385
1383
  });
1386
1384
  sessionState.state = await this._sessionState.set("state", SessionState.VOD_PLAYING);
1387
1385
  sessionState.currentVod = await this._sessionState.setCurrentVod(currentVod, { ttl: currentVod.getDuration() * 1000 });
1386
+ this.currentPlayheadRef = await this._playheadState.set("playheadRef", Date.now(), isLeader);
1388
1387
  await this._sessionState.remove("nextVod");
1389
1388
  return;
1390
1389
  } else {
@@ -1508,7 +1507,8 @@ class Session {
1508
1507
  subtitleSliceEndpoint: this.subtitleSliceEndpoint,
1509
1508
  shouldContainSubtitles: this.use_vtt_subtitles,
1510
1509
  expectedSubtitleTracks: this._subtitleTracks,
1511
- alwaysMapBandwidthByNearest: this.alwaysMapBandwidthByNearest
1510
+ alwaysMapBandwidthByNearest: this.alwaysMapBandwidthByNearest,
1511
+ skipSerializeMediaSequences: this.partialStoreHLSVod
1512
1512
  };
1513
1513
  newVod = new HLSVod(vodResponse.uri, null, vodResponse.unixTs, vodResponse.offset * 1000, m3u8Header(this._instanceId), hlsOpts);
1514
1514
  if (vodResponse.timedMetadata) {
@@ -1560,7 +1560,7 @@ class Session {
1560
1560
  currentVod = newVod;
1561
1561
  debug(`[${this._sessionId}]: msequences=${currentVod.getLiveMediaSequencesCount()}; audio msequences=${currentVod.getLiveMediaSequencesCount("audio")}; subtitle msequences=${currentVod.getLiveMediaSequencesCount("subtitle")}`);
1562
1562
  sessionState.currentVod = await this._sessionState.setCurrentVod(currentVod, { ttl: currentVod.getDuration() * 1000 });
1563
- await this._playheadState.set("playheadRef", Date.now(), isLeader);
1563
+ this.currentPlayheadRef = await this._playheadState.set("playheadRef", Date.now(), isLeader);
1564
1564
  sessionState.vodMediaSeqVideo = await this._sessionState.set("vodMediaSeqVideo", 0);
1565
1565
  sessionState.vodMediaSeqAudio = await this._sessionState.set("vodMediaSeqAudio", 0);
1566
1566
  sessionState.vodMediaSeqSubtitle = await this._sessionState.set("vodMediaSeqSubtitle", 0);
@@ -1675,7 +1675,7 @@ class Session {
1675
1675
  await this._playheadState.set("vodMediaSeqVideo", 0, isLeader);
1676
1676
  await this._playheadState.set("vodMediaSeqAudio", 0, isLeader);
1677
1677
  await this._playheadState.set("vodMediaSeqSubtitle", 0, isLeader);
1678
- await this._playheadState.set("playheadRef", Date.now(), isLeader);
1678
+ this.currentPlayheadRef = await this._playheadState.set("playheadRef", Date.now(), isLeader);
1679
1679
  // 4) Log to debug and cloudwatch
1680
1680
  debug(`[${this._sessionId}]: LEADER: Set new Reloaded VOD and vodMediaSeq counts in store.`);
1681
1681
  debug(`[${this._sessionId}]: next VOD Reloaded (${currentVod.getDeltaTimes()})`);
@@ -1756,7 +1756,8 @@ class Session {
1756
1756
  subtitleSliceEndpoint: this.subtitleSliceEndpoint,
1757
1757
  shouldContainSubtitles: this.use_vtt_subtitles,
1758
1758
  expectedSubtitleTracks: this._subtitleTracks,
1759
- alwaysMapBandwidthByNearest: this.alwaysMapBandwidthByNearest
1759
+ alwaysMapBandwidthByNearest: this.alwaysMapBandwidthByNearest,
1760
+ skipSerializeMediaSequences: this.partialStoreHLSVod
1760
1761
  };
1761
1762
  const timestamp = Date.now();
1762
1763
  hlsVod = new HLSVod(this.slateUri, null, timestamp, null, m3u8Header(this._instanceId), hlsOpts);
@@ -1860,7 +1861,8 @@ class Session {
1860
1861
  subtitleSliceEndpoint: this.subtitleSliceEndpoint,
1861
1862
  shouldContainSubtitles: this.use_vtt_subtitles,
1862
1863
  expectedSubtitleTracks: this._subtitleTracks,
1863
- alwaysMapBandwidthByNearest: this.alwaysMapBandwidthByNearest
1864
+ alwaysMapBandwidthByNearest: this.alwaysMapBandwidthByNearest,
1865
+ skipSerializeMediaSequences: this.partialStoreHLSVod
1864
1866
  };
1865
1867
  const timestamp = Date.now();
1866
1868
  hlsVod = new HLSVod(nexVodUri, null, timestamp, null, m3u8Header(this._instanceId), hlsOpts);
@@ -57,9 +57,18 @@ class SharedSessionState {
57
57
  let hlsVod = null;
58
58
  if (currentVod) {
59
59
  if (this.store.isShared()) {
60
- debug(`[${this.sessionId}]: reading ${currentVod.length} characters from shared store (${Date.now()} < ${this.cache.currentVod.ts + this.cache.currentVod.ttl})`);
60
+ const strToMB = (str) => {
61
+ const bytesPerCharacter = 2; // Assuming each character takes around 2 bytes in memory
62
+ const stringSizeBytes = str.length * bytesPerCharacter;
63
+ const sizeInMegabytes = stringSizeBytes / (1024 * 1024);
64
+ return sizeInMegabytes.toFixed(1);
65
+ }
66
+ debug(`[${this.sessionId}]: reading ${currentVod.length} characters or (${strToMB(currentVod)} MB) from shared store (${Date.now()} < ${this.cache.currentVod.ts + this.cache.currentVod.ttl})`);
61
67
  hlsVod = new HLSVod();
62
68
  hlsVod.fromJSON(currentVod);
69
+ if (hlsVod.skipSerializeMediaSequences) {
70
+ await hlsVod.generateMediaSequences();
71
+ }
63
72
  } else {
64
73
  hlsVod = currentVod;
65
74
  }
@@ -83,6 +92,9 @@ class SharedSessionState {
83
92
  const currentVod = await this.get("currentVod");
84
93
  hlsVod = new HLSVod();
85
94
  hlsVod.fromJSON(currentVod);
95
+ if (hlsVod.skipSerializeMediaSequences) {
96
+ await hlsVod.generateMediaSequences();
97
+ }
86
98
  }
87
99
  } else {
88
100
  await this.set("currentVod", hlsVod);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eyevinn-channel-engine",
3
- "version": "4.2.10",
3
+ "version": "4.3.0",
4
4
  "description": "OTT TV Channel Engine",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -30,7 +30,7 @@
30
30
  "dependencies": {
31
31
  "@eyevinn/hls-repeat": "^0.2.0",
32
32
  "@eyevinn/hls-truncate": "^0.3.0",
33
- "@eyevinn/hls-vodtolive": "^3.1.1",
33
+ "@eyevinn/hls-vodtolive": "^4.0.0",
34
34
  "@eyevinn/m3u8": "^0.5.3",
35
35
  "abort-controller": "^3.0.0",
36
36
  "debug": "^3.2.7",