eyevinn-channel-engine 3.0.0 → 3.0.4
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 +11 -5
- package/engine/server.js +24 -10
- package/engine/session.js +21 -7
- package/engine/session_live.js +117 -131
- package/engine/session_live_state.js +1 -1
- package/engine/stream_switcher.js +234 -121
- package/package.json +5 -4
- package/server-livemix.js +195 -0
- package/server.js +36 -128
- package/spec/engine/init_switching_spec.js +4 -2
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Reference implementation of Channel Engine library
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const ChannelEngine = require("./index.js");
|
|
6
|
+
const { v4: uuidv4 } = require('uuid');
|
|
7
|
+
|
|
8
|
+
const STITCH_ENDPOINT = process.env.STITCH_ENDPOINT || "http://lambda.eyevinn.technology/stitch/master.m3u8";
|
|
9
|
+
class RefAssetManager {
|
|
10
|
+
constructor(opts) {
|
|
11
|
+
if (process.env.TEST_CHANNELS) {
|
|
12
|
+
this.assets = {};
|
|
13
|
+
this.pos = {};
|
|
14
|
+
|
|
15
|
+
const testChannelsCount = parseInt(process.env.TEST_CHANNELS, 10);
|
|
16
|
+
for (let i = 0; i < testChannelsCount; i++) {
|
|
17
|
+
const channelId = `${i + 1}`;
|
|
18
|
+
this.assets[channelId] = [
|
|
19
|
+
{ id: 1, title: "Tears of Steel", uri: "https://maitv-vod.lab.eyevinn.technology/tearsofsteel_4k.mov/master.m3u8" },
|
|
20
|
+
{ id: 2, title: "Unhinged Trailer", uri: "https://maitv-vod.lab.eyevinn.technology/UNHINGED_Trailer_2020.mp4/master.m3u8" },
|
|
21
|
+
{ id: 3, title: "Morbius Trailer", uri: "https://maitv-vod.lab.eyevinn.technology/MORBIUS_Trailer_2020.mp4/master.m3u8" },
|
|
22
|
+
{ id: 4, title: "TV Plus Joachim", uri: "https://maitv-vod.lab.eyevinn.technology/tvplus-ad-joachim.mov/master.m3u8" },
|
|
23
|
+
{ id: 5, title: "The Outpost Trailer", uri: "https://maitv-vod.lab.eyevinn.technology/THE_OUTPOST_Trailer_2020.mp4/master.m3u8" },
|
|
24
|
+
{ id: 6, title: "TV Plus Megha", uri: "https://maitv-vod.lab.eyevinn.technology/tvplus-ad-megha.mov/master.m3u8" },
|
|
25
|
+
];
|
|
26
|
+
this.pos[channelId] = 2;
|
|
27
|
+
}
|
|
28
|
+
} else {
|
|
29
|
+
this.assets = {
|
|
30
|
+
'1': [
|
|
31
|
+
{ id: 1, title: "Tears of Steel", uri: "https://maitv-vod.lab.eyevinn.technology/tearsofsteel_4k.mov/master.m3u8" },
|
|
32
|
+
{ id: 2, title: "Morbius Trailer", uri: "https://maitv-vod.lab.eyevinn.technology/MORBIUS_Trailer_2020.mp4/master.m3u8" },
|
|
33
|
+
{ id: 3, title: "The Outpost Trailer", uri: "https://maitv-vod.lab.eyevinn.technology/THE_OUTPOST_Trailer_2020.mp4/master.m3u8" },
|
|
34
|
+
{ id: 4, title: "Unhinged Trailer", uri: "https://maitv-vod.lab.eyevinn.technology/UNHINGED_Trailer_2020.mp4/master.m3u8" },
|
|
35
|
+
{ id: 5, title: "TV Plus Megha", uri: "https://maitv-vod.lab.eyevinn.technology/tvplus-ad-megha.mov/master.m3u8" },
|
|
36
|
+
{ id: 6, title: "TV Plus Joachim", uri: "https://maitv-vod.lab.eyevinn.technology/tvplus-ad-joachim.mov/master.m3u8" },
|
|
37
|
+
]
|
|
38
|
+
};
|
|
39
|
+
this.pos = {
|
|
40
|
+
'1': 1
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/* @param {Object} vodRequest
|
|
46
|
+
* {
|
|
47
|
+
* sessionId,
|
|
48
|
+
* category,
|
|
49
|
+
* playlistId
|
|
50
|
+
* }
|
|
51
|
+
*/
|
|
52
|
+
getNextVod(vodRequest) {
|
|
53
|
+
return new Promise((resolve, reject) => {
|
|
54
|
+
const channelId = vodRequest.playlistId;
|
|
55
|
+
if (this.assets[channelId]) {
|
|
56
|
+
let vod = this.assets[channelId][this.pos[channelId]++];
|
|
57
|
+
if (this.pos[channelId] > this.assets[channelId].length - 1) {
|
|
58
|
+
this.pos[channelId] = 0;
|
|
59
|
+
}
|
|
60
|
+
const payload = {
|
|
61
|
+
uri: vod.uri,
|
|
62
|
+
breaks: [
|
|
63
|
+
{
|
|
64
|
+
pos: 0,
|
|
65
|
+
duration: 15 * 1000,
|
|
66
|
+
url: "https://maitv-vod.lab.eyevinn.technology/ads/apotea-15s.mp4/master.m3u8"
|
|
67
|
+
}
|
|
68
|
+
]
|
|
69
|
+
};
|
|
70
|
+
const buff = Buffer.from(JSON.stringify(payload));
|
|
71
|
+
const encodedPayload = buff.toString("base64");
|
|
72
|
+
const vodResponse = {
|
|
73
|
+
id: vod.id,
|
|
74
|
+
title: vod.title,
|
|
75
|
+
uri: STITCH_ENDPOINT + "?payload=" + encodedPayload
|
|
76
|
+
};
|
|
77
|
+
resolve(vodResponse);
|
|
78
|
+
} else {
|
|
79
|
+
reject("Invalid channelId provided");
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
handleError(err, vodResponse) {
|
|
85
|
+
console.error(err.message);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
class RefChannelManager {
|
|
90
|
+
constructor(opts) {
|
|
91
|
+
this.channels = [];
|
|
92
|
+
if (process.env.TEST_CHANNELS) {
|
|
93
|
+
const testChannelsCount = parseInt(process.env.TEST_CHANNELS, 10);
|
|
94
|
+
for (let i = 0; i < testChannelsCount; i++) {
|
|
95
|
+
this.channels.push({ id: `${i + 1}`, profile: this._getProfile() });
|
|
96
|
+
}
|
|
97
|
+
} else {
|
|
98
|
+
this.channels = [{ id: "1", profile: this._getProfile() }];
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
getChannels() {
|
|
103
|
+
return this.channels;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
_getProfile() {
|
|
107
|
+
return [
|
|
108
|
+
{ bw: 8242000, codecs: 'avc1.4d001f,mp4a.40.2', resolution: [1024, 458] },
|
|
109
|
+
{ bw: 1274000, codecs: 'avc1.4d001f,mp4a.40.2', resolution: [640, 286] },
|
|
110
|
+
{ bw: 742000, codecs: 'avc1.4d001f,mp4a.40.2', resolution: [480, 214] },
|
|
111
|
+
]
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
const StreamType = Object.freeze({
|
|
115
|
+
LIVE: 1,
|
|
116
|
+
VOD: 2,
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
class StreamSwitchManager {
|
|
120
|
+
constructor() {
|
|
121
|
+
this.schedule = {};
|
|
122
|
+
if (process.env.TEST_CHANNELS) {
|
|
123
|
+
const testChannelsCount = parseInt(process.env.TEST_CHANNELS, 10);
|
|
124
|
+
for (let i = 0; i < testChannelsCount; i++) {
|
|
125
|
+
const channelId = `${i + 1}`;
|
|
126
|
+
this.schedule[channelId] = [];
|
|
127
|
+
}
|
|
128
|
+
} else {
|
|
129
|
+
this.schedule = {
|
|
130
|
+
'1': []
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
generateID() {
|
|
136
|
+
return uuidv4();
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
getSchedule(channelId) {
|
|
140
|
+
return new Promise((resolve, reject) => {
|
|
141
|
+
if (this.schedule[channelId]) {
|
|
142
|
+
const tsNow = Date.now();
|
|
143
|
+
const streamDuration = 60 * 1000;
|
|
144
|
+
const startOffset = tsNow + streamDuration;
|
|
145
|
+
const endTime = startOffset + streamDuration;
|
|
146
|
+
// Break in with live and scheduled VOD content after 60 seconds of VOD2Live the first time Channel Engine starts
|
|
147
|
+
// Required: "assetId", "start_time", "end_time", "uri", "duration"
|
|
148
|
+
// "duration" is only required for StreamType.VOD
|
|
149
|
+
this.schedule[channelId] = this.schedule[channelId].filter((obj) => obj.end_time >= tsNow);
|
|
150
|
+
if (this.schedule[channelId].length === 0) {
|
|
151
|
+
this.schedule[channelId].push({
|
|
152
|
+
eventId: this.generateID(),
|
|
153
|
+
assetId: this.generateID(),
|
|
154
|
+
title: "Live stream test",
|
|
155
|
+
type: StreamType.LIVE,
|
|
156
|
+
start_time: startOffset,
|
|
157
|
+
end_time: endTime,
|
|
158
|
+
uri: "https://cph-p2p-msl.akamaized.net/hls/live/2000341/test/master.m3u8",
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
eventId: this.generateID(),
|
|
162
|
+
assetId: this.generateID(),
|
|
163
|
+
title: "Scheduled VOD test",
|
|
164
|
+
type: StreamType.VOD,
|
|
165
|
+
start_time: (endTime + 100*1000),
|
|
166
|
+
end_time: (endTime + 100*1000) + streamDuration,
|
|
167
|
+
uri: "https://maitv-vod.lab.eyevinn.technology/COME_TO_DADDY_Trailer_2020.mp4/master.m3u8",
|
|
168
|
+
duration: streamDuration,
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
resolve(this.schedule[channelId]);
|
|
172
|
+
} else {
|
|
173
|
+
reject("Invalid channelId provided");
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const refAssetManager = new RefAssetManager();
|
|
180
|
+
const refChannelManager = new RefChannelManager();
|
|
181
|
+
const refStreamSwitchManager = new StreamSwitchManager();
|
|
182
|
+
|
|
183
|
+
const engineOptions = {
|
|
184
|
+
heartbeat: "/",
|
|
185
|
+
averageSegmentDuration: 2000,
|
|
186
|
+
channelManager: refChannelManager,
|
|
187
|
+
streamSwitchManager: refStreamSwitchManager,
|
|
188
|
+
defaultSlateUri: "https://maitv-vod.lab.eyevinn.technology/slate-consuo.mp4/master.m3u8",
|
|
189
|
+
slateRepetitions: 10,
|
|
190
|
+
redisUrl: process.env.REDIS_URL,
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
const engine = new ChannelEngine(refAssetManager, engineOptions);
|
|
194
|
+
engine.start();
|
|
195
|
+
engine.listen(process.env.PORT || 8000);
|
package/server.js
CHANGED
|
@@ -3,46 +3,34 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
const ChannelEngine = require("./index.js");
|
|
6
|
-
const { v4: uuidv4 } = require('uuid');
|
|
7
6
|
|
|
8
|
-
const STITCH_ENDPOINT =
|
|
7
|
+
const STITCH_ENDPOINT =
|
|
8
|
+
process.env.STITCH_ENDPOINT ||
|
|
9
|
+
"http://lambda.eyevinn.technology/stitch/master.m3u8";
|
|
9
10
|
class RefAssetManager {
|
|
10
11
|
constructor(opts) {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
} else {
|
|
29
|
-
this.assets = {
|
|
30
|
-
'1': [
|
|
31
|
-
{ id: 1, title: "Tears of Steel", uri: "https://maitv-vod.lab.eyevinn.technology/tearsofsteel_4k.mov/master.m3u8" },
|
|
32
|
-
{ id: 2, title: "Morbius Trailer", uri: "https://maitv-vod.lab.eyevinn.technology/MORBIUS_Trailer_2020.mp4/master.m3u8" },
|
|
33
|
-
{ id: 3, title: "The Outpost Trailer", uri: "https://maitv-vod.lab.eyevinn.technology/THE_OUTPOST_Trailer_2020.mp4/master.m3u8" },
|
|
34
|
-
{ id: 4, title: "Unhinged Trailer", uri: "https://maitv-vod.lab.eyevinn.technology/UNHINGED_Trailer_2020.mp4/master.m3u8" },
|
|
35
|
-
{ id: 5, title: "TV Plus Megha", uri: "https://maitv-vod.lab.eyevinn.technology/tvplus-ad-megha.mov/master.m3u8" },
|
|
36
|
-
{ id: 6, title: "TV Plus Joachim", uri: "https://maitv-vod.lab.eyevinn.technology/tvplus-ad-joachim.mov/master.m3u8" },
|
|
37
|
-
]
|
|
38
|
-
};
|
|
39
|
-
this.pos = {
|
|
40
|
-
'1': 1
|
|
41
|
-
};
|
|
42
|
-
}
|
|
12
|
+
this.assets = {
|
|
13
|
+
1: [
|
|
14
|
+
{
|
|
15
|
+
id: 1,
|
|
16
|
+
title: "Tears of Steel",
|
|
17
|
+
uri: "https://maitv-vod.lab.eyevinn.technology/tearsofsteel_4k.mov/master.m3u8",
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
id: 2,
|
|
21
|
+
title: "VINN",
|
|
22
|
+
uri: "https://maitv-vod.lab.eyevinn.technology/VINN.mp4/master.m3u8",
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
};
|
|
26
|
+
this.pos = {
|
|
27
|
+
1: 1,
|
|
28
|
+
};
|
|
43
29
|
}
|
|
44
30
|
|
|
45
|
-
|
|
31
|
+
/**
|
|
32
|
+
*
|
|
33
|
+
* @param {Object} vodRequest
|
|
46
34
|
* {
|
|
47
35
|
* sessionId,
|
|
48
36
|
* category,
|
|
@@ -63,16 +51,16 @@ class RefAssetManager {
|
|
|
63
51
|
{
|
|
64
52
|
pos: 100,
|
|
65
53
|
duration: 15 * 1000,
|
|
66
|
-
url: "https://maitv-vod.lab.eyevinn.technology/ads/6cd7d768_e214_4ebc_9f14_7ed89710115e_mp4/master.m3u8"
|
|
67
|
-
}
|
|
68
|
-
]
|
|
54
|
+
url: "https://maitv-vod.lab.eyevinn.technology/ads/6cd7d768_e214_4ebc_9f14_7ed89710115e_mp4/master.m3u8",
|
|
55
|
+
},
|
|
56
|
+
],
|
|
69
57
|
};
|
|
70
58
|
const buff = Buffer.from(JSON.stringify(payload));
|
|
71
59
|
const encodedPayload = buff.toString("base64");
|
|
72
60
|
const vodResponse = {
|
|
73
61
|
id: vod.id,
|
|
74
62
|
title: vod.title,
|
|
75
|
-
uri: STITCH_ENDPOINT + "?payload=" + encodedPayload
|
|
63
|
+
uri: STITCH_ENDPOINT + "?payload=" + encodedPayload,
|
|
76
64
|
};
|
|
77
65
|
resolve(vodResponse);
|
|
78
66
|
} else {
|
|
@@ -80,116 +68,36 @@ class RefAssetManager {
|
|
|
80
68
|
}
|
|
81
69
|
});
|
|
82
70
|
}
|
|
83
|
-
|
|
84
|
-
handleError(err, vodResponse) {
|
|
85
|
-
console.error(err.message);
|
|
86
|
-
}
|
|
87
71
|
}
|
|
88
72
|
|
|
89
73
|
class RefChannelManager {
|
|
90
|
-
constructor(opts) {
|
|
91
|
-
this.channels = [];
|
|
92
|
-
if (process.env.TEST_CHANNELS) {
|
|
93
|
-
const testChannelsCount = parseInt(process.env.TEST_CHANNELS, 10);
|
|
94
|
-
for (let i = 0; i < testChannelsCount; i++) {
|
|
95
|
-
this.channels.push({ id: `${i + 1}`, profile: this._getProfile() });
|
|
96
|
-
}
|
|
97
|
-
} else {
|
|
98
|
-
this.channels = [{ id: "1", profile: this._getProfile() }];
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
74
|
getChannels() {
|
|
103
|
-
return this.
|
|
75
|
+
//return [ { id: '1', profile: this._getProfile() }, { id: 'faulty', profile: this._getProfile() } ];
|
|
76
|
+
return [{ id: "1", profile: this._getProfile() }];
|
|
104
77
|
}
|
|
105
78
|
|
|
106
79
|
_getProfile() {
|
|
107
80
|
return [
|
|
108
|
-
{ bw:
|
|
109
|
-
{ bw:
|
|
110
|
-
{ bw:
|
|
111
|
-
]
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
const StreamType = Object.freeze({
|
|
115
|
-
LIVE: 1,
|
|
116
|
-
VOD: 2,
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
class StreamSwitchManager {
|
|
120
|
-
constructor() {
|
|
121
|
-
this.schedule = {};
|
|
122
|
-
if (process.env.TEST_CHANNELS) {
|
|
123
|
-
const testChannelsCount = parseInt(process.env.TEST_CHANNELS, 10);
|
|
124
|
-
for (let i = 0; i < testChannelsCount; i++) {
|
|
125
|
-
const channelId = `${i + 1}`;
|
|
126
|
-
this.schedule[channelId] = [];
|
|
127
|
-
}
|
|
128
|
-
} else {
|
|
129
|
-
this.schedule = {
|
|
130
|
-
'1': []
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
generateID() {
|
|
136
|
-
return uuidv4();
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
getSchedule(channelId) {
|
|
140
|
-
return new Promise((resolve, reject) => {
|
|
141
|
-
if (this.schedule[channelId]) {
|
|
142
|
-
const tsNow = Date.now();
|
|
143
|
-
const streamDuration = 60 * 1000;
|
|
144
|
-
const startOffset = tsNow + streamDuration;
|
|
145
|
-
const endTime = startOffset + streamDuration;
|
|
146
|
-
// Break in with live and scheduled VOD content after 60 seconds of VOD2Live the first time Channel Engine starts
|
|
147
|
-
// Required: "assetId", "start_time", "end_time", "uri", "duration"
|
|
148
|
-
// "duration" is only required for StreamType.VOD
|
|
149
|
-
this.schedule[channelId] = this.schedule[channelId].filter((obj) => obj.end_time >= tsNow);
|
|
150
|
-
if (this.schedule[channelId].length === 0) {
|
|
151
|
-
this.schedule[channelId].push({
|
|
152
|
-
eventId: this.generateID(),
|
|
153
|
-
assetId: this.generateID(),
|
|
154
|
-
title: "Live stream test",
|
|
155
|
-
type: StreamType.LIVE,
|
|
156
|
-
start_time: startOffset,
|
|
157
|
-
end_time: endTime,
|
|
158
|
-
uri: "https://test2.frankspeech.com/live/Test2/playlist.m3u8",
|
|
159
|
-
},
|
|
160
|
-
{
|
|
161
|
-
eventId: this.generateID(),
|
|
162
|
-
assetId: this.generateID(),
|
|
163
|
-
title: "Scheduled VOD test",
|
|
164
|
-
type: StreamType.VOD,
|
|
165
|
-
start_time: (endTime + 100*1000),
|
|
166
|
-
end_time: (endTime + 100*1000) + streamDuration,
|
|
167
|
-
uri: "https://maitv-vod.lab.eyevinn.technology/COME_TO_DADDY_Trailer_2020.mp4/master.m3u8",
|
|
168
|
-
duration: streamDuration,
|
|
169
|
-
});
|
|
170
|
-
}
|
|
171
|
-
resolve(this.schedule[channelId]);
|
|
172
|
-
} else {
|
|
173
|
-
reject("Invalid channelId provided");
|
|
174
|
-
}
|
|
175
|
-
});
|
|
81
|
+
{ bw: 6134000, codecs: "avc1.4d001f,mp4a.40.2", resolution: [1024, 458] },
|
|
82
|
+
{ bw: 2323000, codecs: "avc1.4d001f,mp4a.40.2", resolution: [640, 286] },
|
|
83
|
+
{ bw: 1313000, codecs: "avc1.4d001f,mp4a.40.2", resolution: [480, 214] },
|
|
84
|
+
];
|
|
176
85
|
}
|
|
177
86
|
}
|
|
178
87
|
|
|
179
88
|
const refAssetManager = new RefAssetManager();
|
|
180
89
|
const refChannelManager = new RefChannelManager();
|
|
181
|
-
const refStreamSwitchManager = new StreamSwitchManager();
|
|
182
90
|
|
|
183
91
|
const engineOptions = {
|
|
184
92
|
heartbeat: "/",
|
|
185
93
|
averageSegmentDuration: 2000,
|
|
186
94
|
channelManager: refChannelManager,
|
|
187
|
-
|
|
188
|
-
|
|
95
|
+
defaultSlateUri:
|
|
96
|
+
"https://maitv-vod.lab.eyevinn.technology/slate-consuo.mp4/master.m3u8",
|
|
189
97
|
slateRepetitions: 10,
|
|
190
98
|
redisUrl: process.env.REDIS_URL,
|
|
191
99
|
};
|
|
192
100
|
|
|
193
101
|
const engine = new ChannelEngine(refAssetManager, engineOptions);
|
|
194
102
|
engine.start();
|
|
195
|
-
engine.listen(process.env.
|
|
103
|
+
engine.listen(process.env.port || 8000);
|
|
@@ -353,7 +353,7 @@ describe("The initialize switching", () => {
|
|
|
353
353
|
discSeq: 0,
|
|
354
354
|
});
|
|
355
355
|
expect(Object.keys(tSegments)).toEqual(Object.keys(currVodSegments));
|
|
356
|
-
currVodSegments[1313000].push({ discontinuity: true });
|
|
356
|
+
currVodSegments[1313000].push({ discontinuity: true, cue: { in: true } });
|
|
357
357
|
expect(tSegments[1313000]).toEqual(currVodSegments[1313000]);
|
|
358
358
|
nock.cleanAll();
|
|
359
359
|
}, 10000);
|
|
@@ -407,7 +407,7 @@ describe("The initialize switching", () => {
|
|
|
407
407
|
uri: "http://mock.mock.com/180000/seg10.ts",
|
|
408
408
|
});
|
|
409
409
|
expect(sessionCurrentSegs["1313000"][size - 1 - 1]).toEqual({
|
|
410
|
-
discontinuity: true,
|
|
410
|
+
discontinuity: true, cue: { in: true }
|
|
411
411
|
});
|
|
412
412
|
expect(sessionCurrentSegs["1313000"][size - 1]).toEqual({
|
|
413
413
|
duration: 7.5,
|
|
@@ -462,6 +462,7 @@ describe("The initialize switching", () => {
|
|
|
462
462
|
});
|
|
463
463
|
expect(sessionCurrentSegs["1313000"][size - 1 - 1]).toEqual({
|
|
464
464
|
discontinuity: true,
|
|
465
|
+
cue: { in: true }
|
|
465
466
|
});
|
|
466
467
|
expect(
|
|
467
468
|
sessionCurrentSegs["1313000"][size - 1].daterange["planned-duration"]
|
|
@@ -781,6 +782,7 @@ describe("The initialize switching", () => {
|
|
|
781
782
|
});
|
|
782
783
|
expect(newVodSegments["1313000"][size - 1 - 1 - 1]).toEqual({
|
|
783
784
|
discontinuity: true,
|
|
785
|
+
cue: { in: true }
|
|
784
786
|
});
|
|
785
787
|
expect(
|
|
786
788
|
newVodSegments["1313000"][size - 1 - 1].daterange["planned-duration"]
|