eyevinn-channel-engine 4.0.6 → 4.0.7

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.
@@ -75,6 +75,8 @@ export interface ClosedCaptions {
75
75
  export interface AudioTracks {
76
76
  language: string;
77
77
  name: string;
78
+ channels?: number;
79
+ codecs?: string;
78
80
  default?: boolean;
79
81
  }
80
82
  export interface IChannelManager {
@@ -1346,7 +1346,7 @@ var Session = /** @class */ (function () {
1346
1346
  };
1347
1347
  Session.prototype.getMasterManifestAsync = function (filter) {
1348
1348
  return __awaiter(this, void 0, void 0, function () {
1349
- var m3u8, currentVod, audioGroupIds, defaultAudioGroupId, hasClosedCaptions, i, audioGroupId, j, audioTrack, sessionProfile;
1349
+ var m3u8, currentVod, audioGroupIds, defaultAudioGroupId, hasClosedCaptions, i, audioGroupId, j, audioTrack, channels, sessionProfile;
1350
1350
  var _this = this;
1351
1351
  return __generator(this, function (_a) {
1352
1352
  switch (_a.label) {
@@ -1378,12 +1378,13 @@ var Session = /** @class */ (function () {
1378
1378
  audioGroupId = audioGroupIds[i];
1379
1379
  for (j = 0; j < this._audioTracks.length; j++) {
1380
1380
  audioTrack = this._audioTracks[j];
1381
+ channels = this._audioTracks[j].channels ? this._audioTracks[j].channels : 2;
1381
1382
  // Make default track if set property is true.
1382
1383
  if (audioTrack.default) {
1383
- m3u8 += "#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID=\"".concat(audioGroupId, "\",LANGUAGE=\"").concat(audioTrack.language, "\", NAME=\"").concat(audioTrack.name, "\",AUTOSELECT=YES,DEFAULT=YES,CHANNELS=\"2\",URI=\"master-").concat(audioGroupId, "_").concat(audioTrack.language, ".m3u8;session=").concat(this._sessionId, "\"\n");
1384
+ m3u8 += "#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID=\"".concat(audioGroupId, "\",LANGUAGE=\"").concat(audioTrack.language, "\", NAME=\"").concat(audioTrack.name, "\",AUTOSELECT=YES,DEFAULT=YES,CHANNELS=\"").concat(channels, "\",URI=\"master-").concat(audioGroupId, "_").concat(audioTrack.language, ".m3u8;session=").concat(this._sessionId, "\"\n");
1384
1385
  }
1385
1386
  else {
1386
- m3u8 += "#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID=\"".concat(audioGroupId, "\",LANGUAGE=\"").concat(audioTrack.language, "\", NAME=\"").concat(audioTrack.name, "\",AUTOSELECT=YES,DEFAULT=NO,CHANNELS=\"2\",URI=\"master-").concat(audioGroupId, "_").concat(audioTrack.language, ".m3u8;session=").concat(this._sessionId, "\"\n");
1387
+ m3u8 += "#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID=\"".concat(audioGroupId, "\",LANGUAGE=\"").concat(audioTrack.language, "\", NAME=\"").concat(audioTrack.name, "\",AUTOSELECT=YES,DEFAULT=NO,CHANNELS=\"").concat(channels, "\",URI=\"master-").concat(audioGroupId, "_").concat(audioTrack.language, ".m3u8;session=").concat(this._sessionId, "\"\n");
1387
1388
  }
1388
1389
  }
1389
1390
  }
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eyevinn-channel-engine",
3
- "version": "4.0.6",
3
+ "version": "4.0.7",
4
4
  "description": "OTT TV Channel Engine",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ /*
3
+ * Reference implementation of Channel Engine library
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ var index_1 = require("./index");
7
+ var RefAssetManager = /** @class */ (function () {
8
+ function RefAssetManager(opts) {
9
+ this.assets = {
10
+ 1: [
11
+ {
12
+ id: 1,
13
+ title: "Sollevante",
14
+ uri: "https://testcontent.eyevinn.technology/dolby/index.m3u8",
15
+ }
16
+ ],
17
+ };
18
+ this.pos = {
19
+ 1: 0,
20
+ };
21
+ }
22
+ /**
23
+ *
24
+ * @param {Object} vodRequest
25
+ * {
26
+ * sessionId,
27
+ * category,
28
+ * playlistId
29
+ * }
30
+ */
31
+ RefAssetManager.prototype.getNextVod = function (vodRequest) {
32
+ var _this = this;
33
+ console.log(this.assets);
34
+ return new Promise(function (resolve, reject) {
35
+ var channelId = vodRequest.playlistId;
36
+ if (_this.assets[channelId]) {
37
+ var vod = _this.assets[channelId][_this.pos[channelId]++];
38
+ if (_this.pos[channelId] > _this.assets[channelId].length - 1) {
39
+ _this.pos[channelId] = 0;
40
+ }
41
+ var vodResponse = {
42
+ id: vod.id,
43
+ title: vod.title,
44
+ uri: vod.uri,
45
+ };
46
+ resolve(vodResponse);
47
+ }
48
+ else {
49
+ reject("Invalid channelId provided");
50
+ }
51
+ });
52
+ };
53
+ return RefAssetManager;
54
+ }());
55
+ var RefChannelManager = /** @class */ (function () {
56
+ function RefChannelManager() {
57
+ }
58
+ RefChannelManager.prototype.getChannels = function () {
59
+ //return [ { id: '1', profile: this._getProfile() }, { id: 'faulty', profile: this._getProfile() } ];
60
+ return [{
61
+ id: "1",
62
+ profile: this._getProfile(),
63
+ audioTracks: this._getAudioTracks(),
64
+ }];
65
+ };
66
+ RefChannelManager.prototype._getProfile = function () {
67
+ return [
68
+ { resolution: [640, 360], bw: 3663471, codecs: "avc1.64001F,mp4a.40.2" },
69
+ { resolution: [1280, 720], bw: 5841380, codecs: "avc1.64001F,mp4a.40.2" },
70
+ { resolution: [1920, 1080], bw: 8973571, codecs: "avc1.64001F,mp4a.40.2" },
71
+ { resolution: [640, 360], bw: 4301519, codecs: "avc1.64001F,ec-3" },
72
+ { resolution: [1280, 720], bw: 6479428, codecs: "avc1.64001F,ec-3" },
73
+ { resolution: [1920, 1080], bw: 9611619, codecs: "avc1.640032,ec-3" },
74
+ ];
75
+ };
76
+ RefChannelManager.prototype._getAudioTracks = function () {
77
+ return [
78
+ { language: "ja", "name": "日本語 stereo", channels: 2, codecs: "mp4a.40.2", default: true },
79
+ { language: "ja", "name": "日本語 surround", channels: 16, codecs: "ec-3", default: false }
80
+ ];
81
+ };
82
+ return RefChannelManager;
83
+ }());
84
+ var refAssetManager = new RefAssetManager();
85
+ var refChannelManager = new RefChannelManager();
86
+ var engineOptions = {
87
+ heartbeat: "/",
88
+ useDemuxedAudio: true,
89
+ averageSegmentDuration: 2000,
90
+ channelManager: refChannelManager,
91
+ slateRepetitions: 10,
92
+ redisUrl: process.env.REDIS_URL,
93
+ };
94
+ var engine = new index_1.ChannelEngine(refAssetManager, engineOptions);
95
+ engine.start();
96
+ engine.listen(process.env.PORT || 8000);
package/engine/server.ts CHANGED
@@ -119,6 +119,8 @@ export interface ClosedCaptions {
119
119
  export interface AudioTracks {
120
120
  language: string;
121
121
  name: string;
122
+ channels?: number;
123
+ codecs?: string;
122
124
  default?: boolean;
123
125
  }
124
126
 
package/engine/session.js CHANGED
@@ -959,11 +959,12 @@ class Session {
959
959
  let audioGroupId = audioGroupIds[i];
960
960
  for (let j = 0; j < this._audioTracks.length; j++) {
961
961
  let audioTrack = this._audioTracks[j];
962
+ let channels = this._audioTracks[j].channels ? this._audioTracks[j].channels : 2;
962
963
  // Make default track if set property is true.
963
964
  if (audioTrack.default) {
964
- m3u8 += `#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="${audioGroupId}",LANGUAGE="${audioTrack.language}", NAME="${audioTrack.name}",AUTOSELECT=YES,DEFAULT=YES,CHANNELS="2",URI="master-${audioGroupId}_${audioTrack.language}.m3u8;session=${this._sessionId}"\n`;
965
+ m3u8 += `#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="${audioGroupId}",LANGUAGE="${audioTrack.language}", NAME="${audioTrack.name}",AUTOSELECT=YES,DEFAULT=YES,CHANNELS="${channels}",URI="master-${audioGroupId}_${audioTrack.language}.m3u8;session=${this._sessionId}"\n`;
965
966
  } else {
966
- m3u8 += `#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="${audioGroupId}",LANGUAGE="${audioTrack.language}", NAME="${audioTrack.name}",AUTOSELECT=YES,DEFAULT=NO,CHANNELS="2",URI="master-${audioGroupId}_${audioTrack.language}.m3u8;session=${this._sessionId}"\n`;
967
+ m3u8 += `#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="${audioGroupId}",LANGUAGE="${audioTrack.language}", NAME="${audioTrack.name}",AUTOSELECT=YES,DEFAULT=NO,CHANNELS="${channels}",URI="master-${audioGroupId}_${audioTrack.language}.m3u8;session=${this._sessionId}"\n`;
967
968
  }
968
969
  }
969
970
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eyevinn-channel-engine",
3
- "version": "4.0.6",
3
+ "version": "4.0.7",
4
4
  "description": "OTT TV Channel Engine",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -0,0 +1,104 @@
1
+ /*
2
+ * Reference implementation of Channel Engine library
3
+ */
4
+
5
+ import { ChannelEngine, ChannelEngineOpts,
6
+ IAssetManager, IChannelManager,
7
+ VodRequest, VodResponse, Channel, ChannelProfile,
8
+ AudioTracks
9
+ } from "./index";
10
+
11
+ class RefAssetManager implements IAssetManager {
12
+ private assets;
13
+ private pos;
14
+ constructor(opts?) {
15
+ this.assets = {
16
+ 1: [
17
+ {
18
+ id: 1,
19
+ title: "Sollevante",
20
+ uri: "https://testcontent.eyevinn.technology/dolby/index.m3u8",
21
+ }
22
+ ],
23
+ };
24
+ this.pos = {
25
+ 1: 0,
26
+ };
27
+ }
28
+
29
+ /**
30
+ *
31
+ * @param {Object} vodRequest
32
+ * {
33
+ * sessionId,
34
+ * category,
35
+ * playlistId
36
+ * }
37
+ */
38
+ getNextVod(vodRequest: VodRequest): Promise<VodResponse> {
39
+ console.log(this.assets);
40
+ return new Promise((resolve, reject) => {
41
+ const channelId = vodRequest.playlistId;
42
+ if (this.assets[channelId]) {
43
+ let vod = this.assets[channelId][this.pos[channelId]++];
44
+ if (this.pos[channelId] > this.assets[channelId].length - 1) {
45
+ this.pos[channelId] = 0;
46
+ }
47
+ const vodResponse = {
48
+ id: vod.id,
49
+ title: vod.title,
50
+ uri: vod.uri,
51
+ };
52
+ resolve(vodResponse);
53
+ } else {
54
+ reject("Invalid channelId provided");
55
+ }
56
+ });
57
+ }
58
+ }
59
+
60
+ class RefChannelManager implements IChannelManager {
61
+ getChannels(): Channel[] {
62
+ //return [ { id: '1', profile: this._getProfile() }, { id: 'faulty', profile: this._getProfile() } ];
63
+ return [{
64
+ id: "1",
65
+ profile: this._getProfile(),
66
+ audioTracks: this._getAudioTracks(),
67
+ }];
68
+ }
69
+
70
+ _getProfile(): ChannelProfile[] {
71
+ return [
72
+ { resolution: [640, 360], bw: 3663471, codecs: "avc1.64001F,mp4a.40.2" },
73
+ { resolution: [1280, 720], bw: 5841380, codecs: "avc1.64001F,mp4a.40.2" },
74
+ { resolution: [1920, 1080], bw: 8973571, codecs: "avc1.64001F,mp4a.40.2" },
75
+
76
+ { resolution: [640, 360], bw: 4301519, codecs: "avc1.64001F,ec-3" },
77
+ { resolution: [1280, 720], bw: 6479428, codecs: "avc1.64001F,ec-3" },
78
+ { resolution: [1920, 1080], bw: 9611619, codecs: "avc1.640032,ec-3" },
79
+ ];
80
+ }
81
+
82
+ _getAudioTracks(): AudioTracks[] {
83
+ return [
84
+ { language: "ja", "name": "日本語 stereo", channels: 2, codecs: "mp4a.40.2", default: true },
85
+ { language: "ja", "name": "日本語 surround", channels: 16, codecs: "ec-3", default: false }
86
+ ];
87
+ }
88
+ }
89
+
90
+ const refAssetManager = new RefAssetManager();
91
+ const refChannelManager = new RefChannelManager();
92
+
93
+ const engineOptions: ChannelEngineOpts = {
94
+ heartbeat: "/",
95
+ useDemuxedAudio: true,
96
+ averageSegmentDuration: 2000,
97
+ channelManager: refChannelManager,
98
+ slateRepetitions: 10,
99
+ redisUrl: process.env.REDIS_URL,
100
+ };
101
+
102
+ const engine = new ChannelEngine(refAssetManager, engineOptions);
103
+ engine.start();
104
+ engine.listen(process.env.PORT || 8000);
package/tsconfig.json CHANGED
@@ -6,5 +6,5 @@
6
6
  "esModuleInterop": true,
7
7
  "declaration": true
8
8
  },
9
- "include": ["./server.ts", "./server-demux.ts", "./server-livemix.ts", "./engine/**/*"]
9
+ "include": ["./server.ts", "./server-demux.ts", "./server-livemix.ts", "./server-multicodec.ts", "./engine/**/*"]
10
10
  }