eyevinn-channel-engine 4.1.0 → 4.1.1

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.
@@ -2,7 +2,7 @@ name: Publish
2
2
 
3
3
  on:
4
4
  release:
5
- types: [created]
5
+ types: [released]
6
6
 
7
7
  jobs:
8
8
  build:
@@ -0,0 +1,22 @@
1
+ name: Publish release candidate
2
+
3
+ on:
4
+ release:
5
+ types: [prereleased]
6
+
7
+ jobs:
8
+ build:
9
+ runs-on: ubuntu-latest
10
+
11
+ steps:
12
+ - uses: actions/checkout@v1
13
+ - uses: actions/setup-node@v1
14
+ with:
15
+ node-version: 16
16
+ registry-url: https://registry.npmjs.org/
17
+ - run: |
18
+ npm install
19
+ npm run build
20
+ npm publish --tag rc
21
+ env:
22
+ NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
@@ -952,7 +952,7 @@ var Session = /** @class */ (function () {
952
952
  };
953
953
  Session.prototype.incrementAsync = function () {
954
954
  return __awaiter(this, void 0, void 0, function () {
955
- var isLeader, sessionState, playheadState, currentVod, _a, leaderAction, _b, m3u8_3, _c, audioIncrement, positionV, positionA, position, currentVod_1, sessionState_1, posDiff, incrementValue, index, audioSeqLastIdx, thresh, audioPosition, _d, _e, _f, _g, _h, _j, _k, _l, _m, mediaSequenceValue, diffMs, m3u8;
955
+ var isLeader, sessionState, playheadState, currentVod, _a, leaderAction, _b, m3u8_3, _c, audioIncrement, positionV, positionA, position, currentVod_1, sessionState_1, posDiff, incrementValue, index, audioSeqLastIdx, thresh, audioPosition, _d, _e, _f, _g, _h, _j, _k, _l, _m, mediaSequenceValue, audioInfo, mediaSequenceValueAudio, diffMs, m3u8;
956
956
  return __generator(this, function (_o) {
957
957
  switch (_o.label) {
958
958
  case 0: return [4 /*yield*/, this._tickAsync()];
@@ -1121,7 +1121,12 @@ var Session = /** @class */ (function () {
1121
1121
  _m.vodMediaSeqAudio = _o.sent();
1122
1122
  if (currentVod.sequenceAlwaysContainNewSegments) {
1123
1123
  mediaSequenceValue = currentVod.mediaSequenceValues[playheadState.vodMediaSeqVideo];
1124
- debug("[".concat(this._sessionId, "]: Session can now serve mseq={").concat(playheadState.mediaSeq + mediaSequenceValue, "}"));
1124
+ audioInfo = "";
1125
+ if (this.use_demuxed_audio) {
1126
+ mediaSequenceValueAudio = currentVod.mediaSequenceValuesAudio[playheadState.vodMediaSeqAudio];
1127
+ audioInfo = " mseq[A]={".concat(playheadState.mediaSeqAudio + mediaSequenceValueAudio, "}");
1128
+ }
1129
+ debug("[".concat(this._sessionId, "]: Session can now serve mseq[V]={").concat(playheadState.mediaSeq + mediaSequenceValue, "}") + audioInfo);
1125
1130
  }
1126
1131
  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"), ")"));
1127
1132
  if (!(playheadState.vodMediaSeqVideo < 2 || playheadState.mediaSeq !== this.prevMediaSeqOffset.video)) return [3 /*break*/, 41];
@@ -52,6 +52,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
52
52
  var HLSVod = require('@eyevinn/hls-vodtolive');
53
53
  var SharedStateStore = require('./shared_state_store.js');
54
54
  var debug = require("debug")("session-state-store");
55
+ var timeLeft = require('./util.js').timeLeft;
55
56
  var SessionState = Object.freeze({
56
57
  VOD_INIT: 1,
57
58
  VOD_PLAYING: 2,
@@ -99,7 +100,7 @@ var SharedSessionState = /** @class */ (function () {
99
100
  throw new Error("shared session state store has not been initialized");
100
101
  }
101
102
  if (this.cache.currentVod.value && Date.now() < this.cache.currentVod.ts + this.cache.currentVod.ttl) {
102
- debug("[".concat(this.sessionId, "]: reading 'currentVod' from cache"));
103
+ debug("[".concat(this.sessionId, "]: reading 'currentVod' from cache. Expires in ").concat(timeLeft(this.cache.currentVod.ts + this.cache.currentVod.ttl, Date.now())));
103
104
  return [2 /*return*/, this.cache.currentVod.value];
104
105
  }
105
106
  return [4 /*yield*/, this.get("currentVod")];
@@ -18,3 +18,4 @@ export function findNearestValue(val: any, array: any): any;
18
18
  export function isValidUrl(url: any): boolean;
19
19
  export function fetchWithRetry(uri: any, opts: any, maxRetries: any, retryDelayMs: any, timeoutMs: any, debug: any): Promise<any>;
20
20
  export function codecsFromString(codecs: any): any[];
21
+ export function timeLeft(endTimestamp: any, currentTimestamp: any): string;
@@ -275,6 +275,26 @@ var codecsFromString = function (codecs) {
275
275
  });
276
276
  return [videoCodecs, audioCodecs];
277
277
  };
278
+ var timeLeft = function (endTimestamp, currentTimestamp) {
279
+ var secondsLeft = Math.floor((endTimestamp - currentTimestamp) / 1000);
280
+ if (secondsLeft < 0) {
281
+ return "Time has already passed.";
282
+ }
283
+ var hours = Math.floor(secondsLeft / 3600);
284
+ var minutes = Math.floor((secondsLeft % 3600) / 60);
285
+ var seconds = secondsLeft % 60;
286
+ var msg = "";
287
+ if (hours) {
288
+ msg = "".concat(hours, "h").concat(minutes, "m").concat(seconds, "s");
289
+ }
290
+ else if (minutes) {
291
+ msg = "".concat(minutes, "m").concat(seconds, "s");
292
+ }
293
+ else {
294
+ msg = "".concat(seconds, "s");
295
+ }
296
+ return msg;
297
+ };
278
298
  module.exports = {
279
299
  filterQueryParser: filterQueryParser,
280
300
  applyFilter: applyFilter,
@@ -287,5 +307,6 @@ module.exports = {
287
307
  findNearestValue: findNearestValue,
288
308
  isValidUrl: isValidUrl,
289
309
  fetchWithRetry: fetchWithRetry,
290
- codecsFromString: codecsFromString
310
+ codecsFromString: codecsFromString,
311
+ timeLeft: timeLeft,
291
312
  };
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eyevinn-channel-engine",
3
- "version": "4.1.0",
3
+ "version": "4.1.1",
4
4
  "description": "OTT TV Channel Engine",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -8,6 +8,7 @@
8
8
  "build": "tsc --project ./ && cp ./package.json dist/",
9
9
  "debug-server": "DEBUG=engine-*,vod-to-live node dist/server.js",
10
10
  "test": "jasmine",
11
+ "version:rc": "npm version prerelease --preid=rc",
11
12
  "postversion": "git push && git push --tags",
12
13
  "start": "node dist/server.js",
13
14
  "start-demux": "node dist/server-demux.js",
@@ -29,7 +30,7 @@
29
30
  "dependencies": {
30
31
  "@eyevinn/hls-repeat": "^0.2.0",
31
32
  "@eyevinn/hls-truncate": "^0.2.0",
32
- "@eyevinn/hls-vodtolive": "^2.3.10",
33
+ "@eyevinn/hls-vodtolive": "^2.3.12",
33
34
  "@eyevinn/m3u8": "^0.5.3",
34
35
  "abort-controller": "^3.0.0",
35
36
  "debug": "^3.2.7",
package/engine/session.js CHANGED
@@ -787,7 +787,12 @@ class Session {
787
787
 
788
788
  if (currentVod.sequenceAlwaysContainNewSegments) {
789
789
  const mediaSequenceValue = currentVod.mediaSequenceValues[playheadState.vodMediaSeqVideo];
790
- debug(`[${this._sessionId}]: Session can now serve mseq={${playheadState.mediaSeq + mediaSequenceValue}}`);
790
+ let audioInfo = "";
791
+ if (this.use_demuxed_audio) {
792
+ const mediaSequenceValueAudio = currentVod.mediaSequenceValuesAudio[playheadState.vodMediaSeqAudio];
793
+ audioInfo = ` mseq[A]={${playheadState.mediaSeqAudio + mediaSequenceValueAudio}}`
794
+ }
795
+ debug(`[${this._sessionId}]: Session can now serve mseq[V]={${playheadState.mediaSeq + mediaSequenceValue}}` + audioInfo);
791
796
  }
792
797
 
793
798
  debug(`[${this._sessionId}]: INCREMENT (mseq=${playheadState.mediaSeq + playheadState.vodMediaSeqVideo}) vodMediaSeq=(${playheadState.vodMediaSeqVideo}_${playheadState.vodMediaSeqAudio} of ${currentVod.getLiveMediaSequencesCount()}_${currentVod.getLiveMediaSequencesCount("audio")})`);
@@ -1,6 +1,7 @@
1
1
  const HLSVod = require('@eyevinn/hls-vodtolive');
2
2
  const SharedStateStore = require('./shared_state_store.js');
3
3
  const debug = require("debug")("session-state-store");
4
+ const { timeLeft } = require('./util.js');
4
5
 
5
6
  const SessionState = Object.freeze({
6
7
  VOD_INIT: 1,
@@ -43,7 +44,12 @@ class SharedSessionState {
43
44
  }
44
45
 
45
46
  if (this.cache.currentVod.value && Date.now() < this.cache.currentVod.ts + this.cache.currentVod.ttl) {
46
- debug(`[${this.sessionId}]: reading 'currentVod' from cache`);
47
+ debug(
48
+ `[${this.sessionId}]: reading 'currentVod' from cache. Expires in ${timeLeft(
49
+ this.cache.currentVod.ts + this.cache.currentVod.ttl,
50
+ Date.now()
51
+ )}`
52
+ );
47
53
  return this.cache.currentVod.value;
48
54
  }
49
55
 
package/engine/util.js CHANGED
@@ -6,7 +6,7 @@ const filterQueryParser = (filterQuery) => {
6
6
  const conditions = filterQuery.match(/\(([^\(\)]*?)\)/g);
7
7
 
8
8
  let filter = {};
9
-
9
+
10
10
  if (!conditions) {
11
11
  return filter;
12
12
  }
@@ -157,7 +157,7 @@ const findNearestValue = (val, array) => {
157
157
  return sorted.reduce((a, b) => {
158
158
  return Math.abs(b - val) < Math.abs(a - val) ? b : a;
159
159
  });
160
- }
160
+ };
161
161
 
162
162
  const isValidUrl = (url) => {
163
163
  try {
@@ -166,8 +166,7 @@ const isValidUrl = (url) => {
166
166
  } catch (err) {
167
167
  return false;
168
168
  }
169
- }
170
-
169
+ };
171
170
 
172
171
  const fetchWithRetry = async (uri, opts, maxRetries, retryDelayMs, timeoutMs, debug) => {
173
172
  if (!debug) {
@@ -224,6 +223,25 @@ const codecsFromString = (codecs) => {
224
223
  return [videoCodecs, audioCodecs];
225
224
  };
226
225
 
226
+ const timeLeft = (endTimestamp, currentTimestamp) => {
227
+ const secondsLeft = Math.floor((endTimestamp - currentTimestamp) / 1000);
228
+ if (secondsLeft < 0) {
229
+ return "Time has already passed.";
230
+ }
231
+ const hours = Math.floor(secondsLeft / 3600);
232
+ const minutes = Math.floor((secondsLeft % 3600) / 60);
233
+ const seconds = secondsLeft % 60;
234
+ let msg = "";
235
+ if (hours) {
236
+ msg = `${hours}h${minutes}m${seconds}s`;
237
+ } else if (minutes) {
238
+ msg = `${minutes}m${seconds}s`;
239
+ } else {
240
+ msg = `${seconds}s`;
241
+ }
242
+ return msg;
243
+ };
244
+
227
245
  module.exports = {
228
246
  filterQueryParser,
229
247
  applyFilter,
@@ -236,5 +254,6 @@ module.exports = {
236
254
  findNearestValue,
237
255
  isValidUrl,
238
256
  fetchWithRetry,
239
- codecsFromString
257
+ codecsFromString,
258
+ timeLeft,
240
259
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eyevinn-channel-engine",
3
- "version": "4.1.0",
3
+ "version": "4.1.1",
4
4
  "description": "OTT TV Channel Engine",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -8,6 +8,7 @@
8
8
  "build": "tsc --project ./ && cp ./package.json dist/",
9
9
  "debug-server": "DEBUG=engine-*,vod-to-live node dist/server.js",
10
10
  "test": "jasmine",
11
+ "version:rc": "npm version prerelease --preid=rc",
11
12
  "postversion": "git push && git push --tags",
12
13
  "start": "node dist/server.js",
13
14
  "start-demux": "node dist/server-demux.js",
@@ -29,7 +30,7 @@
29
30
  "dependencies": {
30
31
  "@eyevinn/hls-repeat": "^0.2.0",
31
32
  "@eyevinn/hls-truncate": "^0.2.0",
32
- "@eyevinn/hls-vodtolive": "^2.3.10",
33
+ "@eyevinn/hls-vodtolive": "^2.3.12",
33
34
  "@eyevinn/m3u8": "^0.5.3",
34
35
  "abort-controller": "^3.0.0",
35
36
  "debug": "^3.2.7",