eyevinn-channel-engine 3.3.9 → 3.3.10
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/.github/workflows/nodejs.yml +1 -1
- package/README.md +29 -249
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -1,269 +1,49 @@
|
|
|
1
|
-
|
|
1
|
+
# Eyevinn Channel Engine
|
|
2
|
+
> *Open Source FAST Channel Engine based on VOD2Live technology*
|
|
2
3
|
|
|
3
|
-

|
|
6
|
-
|
|
7
|
-
## Usage
|
|
8
|
-
|
|
9
|
-
To use this library in your NodeJS project download and install the library in your project by running the following in your project folder.
|
|
10
|
-
|
|
11
|
-
```
|
|
12
|
-
$ npm install --save eyevinn-channel-engine
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
To run the basic reference implementation included in this repository you run:
|
|
16
|
-
|
|
17
|
-
```
|
|
18
|
-
$ npm start
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
To run the basic reference implementation for using demuxed VODs you run:
|
|
22
|
-
|
|
23
|
-
```
|
|
24
|
-
$ npm run start-demux
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
And to run the basic reference implementation for using live-mixing you run:
|
|
28
|
-
|
|
29
|
-
```
|
|
30
|
-
$ npm run start-livemix
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
Then point your HLS video player to `http://localhost:8000/channels/1/master.m3u8` to start playing the linear live stream.
|
|
35
|
-
|
|
36
|
-
## Master manifest filtering
|
|
37
|
-
|
|
38
|
-
The engine supports a very simplistic and basic filtering of media playlists included in the master manifest. Currently supports to filter on video bandwidth and video height. To specify a filter provide the query parameter `filter` when loading the master manifest, e.g. `(type=="video"ANDheight>200)AND(type=="video"ANDheight<400)`. This needs to be URL encoded resulting in the following URL: `http://localhost:8000/channels/1/master.m3u8?filter=%28type%3D%3D%22video%22ANDheight%3E200%29AND%28type%3D%3D%22video%22ANDheight%3C400%29`.
|
|
39
|
-
|
|
40
|
-
To filter by video bandwidth use the `systemBitrate` keyword in the query, e.g. `(type=="video"ANDsystemBitrate>2121000)AND(type=="video"ANDsystemBitrate<6161000)`.
|
|
41
|
-
|
|
42
|
-
You can also combine the filter conditions, e.g. `(type=="video"ANDheight>240)AND(type=="video"ANDsystemBitrate<4141000)`
|
|
43
|
-
|
|
44
|
-
## API
|
|
45
|
-
|
|
46
|
-
Initiate and start the engine as below.
|
|
47
|
-
|
|
48
|
-
```
|
|
49
|
-
const ChannelEngine = require('eyevinn-channel-engine');
|
|
50
|
-
|
|
51
|
-
const engine = new ChannelEngine(myAssetManager, { channelManager: myChannelManager });
|
|
52
|
-
engine.start();
|
|
53
|
-
engine.listen(process.env.port || 8000);
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
where `myAssetManager` and `myChannelManager` are classes implementing the interfaces below.
|
|
57
|
-
|
|
58
|
-
```
|
|
59
|
-
class MyAssetManager {
|
|
60
|
-
getNextVod({ sessionId, category, playlistId }) -> { id, title, uri, offset, timedMetadata? }
|
|
61
|
-
handleError(err, vodResponse)
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
class MyChannelManager {
|
|
65
|
-
getChannels() -> [ { id, name, slate?, closedCaptions?, profile?, audioTracks?, options? } ]
|
|
66
|
-
}
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
Find a simplistic reference implementation for guidance in `./server.js`.
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
### Enabling Demuxed Audio
|
|
73
|
-
**LIMITATIONS:** At the moment, only supported for assets with matching audio track GROUP-IDs. Assets with different GROUP-IDs on their tracks will not be loaded correctly when transitioning between them, resulting in buffer errors. (This will be fixed).
|
|
74
|
-
|
|
75
|
-
To support playing assets with multiple audio tracks, a list of supported languages needs to be pre-defined.
|
|
76
|
-
Assign to the `audioTracks` property,
|
|
77
|
-
in the return object for the channel manager class's `getChannels()` function, a list of objects in the following format
|
|
78
|
-
|
|
79
|
-
```
|
|
80
|
-
{
|
|
81
|
-
language: { type: string } ,
|
|
82
|
-
name: { type: string },
|
|
83
|
-
default: { type: bool } // optional
|
|
84
|
-
}
|
|
85
|
-
```
|
|
86
|
-
Example value for `audioTracks`:
|
|
87
|
-
```
|
|
88
|
-
audioTracks = [ { language: "en", name: "English", default: true }, { language: "es", name: "Español" } ];
|
|
89
|
-
```
|
|
90
|
-
**NOTE:** In the case where an asset does not have a track in a language found in the pre-defined list, then the asset's default track will be played in its place.
|
|
4
|
+
[](http://slack.streamingtech.se)
|
|
91
5
|
|
|
92
|
-
|
|
6
|
+
Eyevinn Channel Engine is a core component library for creating FAST channels based on VOD2Live technology. Combine this vod2live technology component with your business and scheduling logic to build your very own and unique FAST channel engine.
|
|
93
7
|
|
|
8
|
+
Please see the [Documentation](https://vod2live.docs.eyevinn.technology) for introductory tutorials and how to get started building your own FAST channel engine.
|
|
94
9
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
Available options when constructing the Channel Engine object are:
|
|
98
|
-
|
|
99
|
-
- `defaultSlateUri`: URI to an HLS VOD that can be inserted when a VOD for some reason cannot be loaded.
|
|
100
|
-
- `slateRepetitions`: Number of times the slate should be repeated.
|
|
101
|
-
- `redisUrl`: A Redis DB URL for storing states that can be shared between nodes.
|
|
102
|
-
- `sharedStoreCacheTTL`: How long should data be cached in memory before writing to shared store. Default is 1000 ms.
|
|
103
|
-
- `heartbeat`: Path for heartbeat requests
|
|
104
|
-
- `channelManager`: A reference to a channel manager object.
|
|
105
|
-
- `streamSwitchManager`: A reference to a stream switch manager object.
|
|
106
|
-
- `cacheTTL`: Sets the cache-control header TTL. Default is 4 sec.
|
|
107
|
-
- `playheadDiffThreshold`: Sets the threshold when starting to adjust tick interval to compensate for playhead drift.
|
|
108
|
-
- `maxTickInterval`: The maximum interval for playhead tick interval. Default is 10000 ms.
|
|
109
|
-
- `cloudWatchMetrics`: Output CloudWatch JSON metrics on console log. Default is false.
|
|
110
|
-
- `useDemuxedAudio`: Enable playing VODs with multiple audio tracks. Default is false.
|
|
111
|
-
- `alwaysNewSegments`: Force all new HLS media sequences to always contain at least 1 new segment. Default is false.
|
|
112
|
-
- `diffCompensationRate`: The rate for how much time is added on each sequence to slow down the playhead until it is back on schedule. Default is 0.5 (delay with half a segment duration).
|
|
113
|
-
|
|
114
|
-
## High Availability
|
|
115
|
-
|
|
116
|
-
As the engine is not a stateless microservice accomplish high availablity and redundancy is not a trivial task, and requires a shared cache cluster (also redundant) to store current state.
|
|
117
|
-
|
|
118
|
-

|
|
119
|
-
|
|
120
|
-
High availability support is from v3 general available in the Channel Engine and it uses Redis as the shared storage. This allows you to run a replicaset behind a round-robin load balancer as examplified in the drawing above. To enable high-availability initiate the engine with the URL to the Redis cache.
|
|
121
|
-
|
|
122
|
-
```
|
|
123
|
-
const engineOptions = {
|
|
124
|
-
heartbeat: '/',
|
|
125
|
-
averageSegmentDuration: 2000,
|
|
126
|
-
channelManager: refChannelManager,
|
|
127
|
-
defaultSlateUri: "https://maitv-vod.lab.eyevinn.technology/slate-consuo.mp4/master.m3u8",
|
|
128
|
-
slateRepetitions: 10,
|
|
129
|
-
redisUrl: "redis://127.0.0.1",
|
|
130
|
-
};
|
|
131
|
-
|
|
132
|
-
const engine = new ChannelEngine(refAssetManager, engineOptions);
|
|
133
|
-
engine.start();
|
|
134
|
-
engine.listen(process.env.port || 8000);
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
## Live Mixing (BETA)
|
|
139
|
-
|
|
140
|
-
This feature gives the possibility to mix in a true live stream in a Channel Engine powered linear channel (VOD2Live).
|
|
141
|
-
|
|
142
|
-
A beta-version of live-mixing with high availability support is available in the Channel Engine. This allows you to use a new component which can let you break in to a scheduled VOD event or Live stream event at any speficied time on top of the usual vod-to-live content.
|
|
143
|
-
To enable live-mixing, create a class which implements the following interface.
|
|
144
|
-
|
|
145
|
-
```
|
|
146
|
-
class MyStreamSwitchManager {
|
|
147
|
-
getSchedule(channelId) -> [ { eventId, assetId, title, type, start_time, end_time, uri, duration } ]
|
|
148
|
-
}
|
|
149
|
-
```
|
|
150
|
-
When using **Live Mixing** in **High-Availablilty** mode, it is important to know that the class's `getSchedule(channelId)` function will be called by each channel-engine instance. Meaning that it is crucial that the implementation of this function will return the same response for each and every channel-engine instance, as they are expecting to be recieving identical lists in order to be synced up for live mixing.
|
|
151
|
-
|
|
152
|
-
The class's `getSchedule(channelId)` function should return a promise containing the list of events as an object in the following format below:
|
|
153
|
-
|
|
154
|
-
```
|
|
155
|
-
{
|
|
156
|
-
"eventId": {
|
|
157
|
-
"type": "string",
|
|
158
|
-
"description": "Generated ID of the event"
|
|
159
|
-
},
|
|
160
|
-
"assetId": {
|
|
161
|
-
"type": "string",
|
|
162
|
-
"description": "The ID of the asset in the schedule event"
|
|
163
|
-
},
|
|
164
|
-
"title": {
|
|
165
|
-
"type": "string",
|
|
166
|
-
"description": "Title of the asset"
|
|
167
|
-
},
|
|
168
|
-
"type": {
|
|
169
|
-
"type": "number",
|
|
170
|
-
"description": "Type of event (1=LIVE and 2=VOD)"
|
|
171
|
-
},
|
|
172
|
-
"start_time": {
|
|
173
|
-
"type": "number",
|
|
174
|
-
"description": "UTC Start time of the event as a Unix Timestamp (in milliseconds)"
|
|
175
|
-
},
|
|
176
|
-
"end_time": {
|
|
177
|
-
"type": "number",
|
|
178
|
-
"description": "UTC End time of the event as a Unix Timestamp (in milliseconds)"
|
|
179
|
-
},
|
|
180
|
-
"uri": {
|
|
181
|
-
"type": "string",
|
|
182
|
-
"description": "The URI to the VOD asset or Live Stream"
|
|
183
|
-
},
|
|
184
|
-
"duration": {
|
|
185
|
-
"type": "number",
|
|
186
|
-
"description": "The duration of the asset (in milliseconds) NOTE: Not required for Live Stream events"
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
Below are examples of a Live stream event and a VOD event respectively:
|
|
192
|
-
```
|
|
193
|
-
{
|
|
194
|
-
eventId: "eeecd5ce-d2d2-48db-b1b3-233957f7d69e",
|
|
195
|
-
assetId: "live-asset-4",
|
|
196
|
-
title: "My scheduled Live stream event",
|
|
197
|
-
type: 1,
|
|
198
|
-
start_time: 1631003900000,
|
|
199
|
-
end_time: 1631003921000,
|
|
200
|
-
uri: "https://cph-p2p-msl.akamaized.net/hls/live/2000341/test/master.m3u8",
|
|
201
|
-
}
|
|
202
|
-
```
|
|
203
|
-
```
|
|
204
|
-
{
|
|
205
|
-
eventId: "26453eea-0ac2-4b89-a87a-73d369920874",
|
|
206
|
-
assetId: "vod-asset-13",
|
|
207
|
-
title: "My scheduled VOD event",
|
|
208
|
-
type: 2,
|
|
209
|
-
start_time: 1631004100000,
|
|
210
|
-
end_time: 1631004121000,
|
|
211
|
-
uri: "https://maitv-vod.lab.eyevinn.technology/VINN.mp4/master.m3u8",
|
|
212
|
-
duration: 2 * 60 * 1000,
|
|
213
|
-
}
|
|
214
|
-
```
|
|
215
|
-
(*Important Note: When it comes to VOD events. Desired `duration` has priority over `end_time`. Meaning that you will only resume VOD2Live content after the asset in the VOD event has finished. This may change in the future.*)
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
Then create an instance of the class and reference it as the `streamSwitchManager` in your engineOptions, just like you'd do with the channel manager.
|
|
220
|
-
|
|
221
|
-
```
|
|
222
|
-
const MyStreamSwitchManager = new MyStreamSwitchManager();
|
|
223
|
-
|
|
224
|
-
const engineOptions = {
|
|
225
|
-
heartbeat: '/',
|
|
226
|
-
averageSegmentDuration: 2000,
|
|
227
|
-
channelManager: MyChannelManager,
|
|
228
|
-
defaultSlateUri: "https://maitv-vod.lab.eyevinn.technology/slate-consuo.mp4/master.m3u8",
|
|
229
|
-
slateRepetitions: 10,
|
|
230
|
-
redisUrl: "redis://127.0.0.1",
|
|
231
|
-
streamSwitchManager: MyStreamSwitchManager,
|
|
232
|
-
};
|
|
233
|
-
|
|
234
|
-
const engine = new ChannelEngine(refAssetManager, engineOptions);
|
|
235
|
-
engine.start();
|
|
236
|
-
engine.listen(process.env.port || 8000);
|
|
237
|
-
```
|
|
238
|
-
|
|
239
|
-
### Stream Switch Manager & The StreamSwitcher
|
|
240
|
-
When building a Stream Switch Manager it is good to know the basics of how the **StreamSwitcher** component in Channel Engine works.
|
|
241
|
-
Each channel will have it's own **StreamSwitcher** component in the Channel Engine which will continiously, at a set time interval, call the `getSchedule()` function in the StreamSwitchManager to get the list of scheduled events.
|
|
242
|
-
|
|
243
|
-
*Note: For now, all channels read from the same event schedule*
|
|
10
|
+

|
|
244
11
|
|
|
12
|
+
A live demo and example is available here: [https://vod2live.eyevinn.technology](https://vod2live.eyevinn.technology)
|
|
245
13
|
|
|
246
|
-
|
|
247
|
-
By default, if no StreamSwitchManager is used, or if the returned schedule list is empty, or if the next event in the schedule list has its `start_time` in the future, the **StreamSwitcher** will have the channel broadcast the VOD2Live feed.
|
|
14
|
+
## Features
|
|
248
15
|
|
|
16
|
+
- Produce 24/7 HLS live channels based on already transcoded HLS VODs
|
|
17
|
+
- Produce a personalized 24/7 HLS live channel unique for each viewer
|
|
18
|
+
- Mix VOD2Live channel with a "real" live HLS stream
|
|
19
|
+
- Develop adapters to plugin with custom scheduling endpoints
|
|
20
|
+
- And much more!
|
|
249
21
|
|
|
250
|
-
|
|
22
|
+
## System Requirements
|
|
251
23
|
|
|
24
|
+
Supported Node.js Versions
|
|
252
25
|
|
|
253
|
-
|
|
254
|
-
|
|
26
|
+
| Version | Supported |
|
|
27
|
+
| ------- | --------- |
|
|
28
|
+
| 14.x | Yes |
|
|
29
|
+
| 16.x | Yes |
|
|
30
|
+
| 18.x | No |
|
|
255
31
|
|
|
32
|
+
## Usage
|
|
256
33
|
|
|
257
|
-
|
|
34
|
+
Follow [this tutorial](https://vod2live.docs.eyevinn.technology/getting-started.html) to get started building your own FAST channel engine.
|
|
258
35
|
|
|
259
36
|
## Support
|
|
260
37
|
|
|
261
|
-
|
|
38
|
+
Join our [community on Slack](http://slack.streamingtech.se) where you can post any questions regarding any of our open source projects. Eyevinn's consulting business can also offer you:
|
|
262
39
|
|
|
263
|
-
|
|
40
|
+
- Further development of this component
|
|
41
|
+
- Customization and integration of this component into your platform
|
|
42
|
+
- Support and maintenance agreement
|
|
264
43
|
|
|
265
|
-
Eyevinn Technology
|
|
44
|
+
## About Eyevinn Technology
|
|
266
45
|
|
|
267
|
-
|
|
46
|
+
[Eyevinn Technology](https://www.eyevinntechnology.se) is an independent consultant firm specialized in video and streaming. Independent in a way that we are not commercially tied to any platform or technology vendor. As our way to innovate and push the industry forward we develop proof-of-concepts and tools. The things we learn and the code we write we share with the industry in [blogs](https://dev.to/video) and by open sourcing the code we have written.
|
|
268
47
|
|
|
269
48
|
Want to know more about Eyevinn and how it is to work here. Contact us at work@eyevinn.se!
|
|
49
|
+
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eyevinn-channel-engine",
|
|
3
|
-
"version": "3.3.
|
|
3
|
+
"version": "3.3.10",
|
|
4
4
|
"description": "OTT TV Channel Engine",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -13,9 +13,10 @@
|
|
|
13
13
|
},
|
|
14
14
|
"author": "Eyevinn Technology AB <work@eyevinn.se>",
|
|
15
15
|
"contributors": [
|
|
16
|
-
"Jonas
|
|
16
|
+
"Jonas Birmé <jonas.birme@eyevinn.se> (Eyevinn Technology AB)",
|
|
17
17
|
"Alan Allard <alan.allard@eyevinn.se> (Eyevinn Technology AB)",
|
|
18
|
-
"Craig McEldowney <craig@ottera.tv>"
|
|
18
|
+
"Craig McEldowney <craig@ottera.tv>",
|
|
19
|
+
"Nicholas Frederiksen <nicholas.frederiksen@eyevinn.se> (Eyevinn Technology AB)"
|
|
19
20
|
],
|
|
20
21
|
"repository": "https://github.com/Eyevinn/channel-engine",
|
|
21
22
|
"license": "Apache-2.0",
|