@eluvio/elv-client-js 4.0.114 → 4.0.116
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/dist/ElvClient-min.js +68 -0
- package/dist/ElvClient-node-min.js +67 -0
- package/dist/ElvFrameClient-min.js +60 -0
- package/dist/ElvPermissionsClient-min.js +60 -0
- package/dist/ElvWalletClient-min.js +68 -0
- package/dist/ElvWalletClient-node-min.js +67 -0
- package/dist/src/AuthorizationClient.js +2166 -0
- package/dist/src/ContentObjectAudit.js +175 -0
- package/dist/src/ContentObjectVerification.js +281 -0
- package/dist/src/Crypto.js +412 -0
- package/dist/src/ElvClient.js +2063 -0
- package/dist/src/ElvWallet.js +247 -0
- package/dist/src/EthClient.js +1153 -0
- package/dist/src/FrameClient.js +484 -0
- package/dist/src/HttpClient.js +314 -0
- package/dist/src/Id.js +20 -0
- package/dist/src/LogMessage.js +25 -0
- package/dist/src/PermissionsClient.js +1556 -0
- package/dist/src/RemoteSigner.js +383 -0
- package/dist/src/UserProfileClient.js +1465 -0
- package/dist/src/Utils.js +893 -0
- package/dist/src/Validation.js +121 -0
- package/dist/src/abr_profiles/abr_profile_live_drm.js +1661 -0
- package/dist/src/abr_profiles/abr_profile_live_to_vod.js +1606 -0
- package/dist/src/client/ABRPublishing.js +1018 -0
- package/dist/src/client/AccessGroups.js +1503 -0
- package/dist/src/client/ContentAccess.js +5202 -0
- package/dist/src/client/ContentManagement.js +2680 -0
- package/dist/src/client/Contracts.js +1520 -0
- package/dist/src/client/Files.js +2181 -0
- package/dist/src/client/LiveConf.js +567 -0
- package/dist/src/client/LiveStream.js +2638 -0
- package/dist/src/client/NFT.js +162 -0
- package/dist/src/client/NTP.js +581 -0
- package/dist/src/contracts/v2/AccessIndexor.js +831 -0
- package/dist/src/contracts/v2/Accessible.js +31 -0
- package/dist/src/contracts/v2/BaseAccessControlGroup.js +1263 -0
- package/dist/src/contracts/v2/BaseAccessWallet.js +1609 -0
- package/dist/src/contracts/v2/BaseAccessWalletFactory.js +93 -0
- package/dist/src/contracts/v2/BaseContent.js +1076 -0
- package/dist/src/contracts/v2/BaseContentFactory.js +219 -0
- package/dist/src/contracts/v2/BaseContentSpace.js +1352 -0
- package/dist/src/contracts/v2/BaseContentType.js +364 -0
- package/dist/src/contracts/v2/BaseFactory.js +107 -0
- package/dist/src/contracts/v2/BaseGroupFactory.js +93 -0
- package/dist/src/contracts/v2/BaseLibrary.js +1041 -0
- package/dist/src/contracts/v2/BaseLibraryFactory.js +96 -0
- package/dist/src/contracts/v2/Certifyer.js +86 -0
- package/dist/src/contracts/v2/Container.js +540 -0
- package/dist/src/contracts/v2/Content.js +443 -0
- package/dist/src/contracts/v2/Editable.js +306 -0
- package/dist/src/contracts/v2/ExternalUserWallet.js +379 -0
- package/dist/src/contracts/v2/IFactorySpace.js +57 -0
- package/dist/src/contracts/v2/IKmsSpace.js +52 -0
- package/dist/src/contracts/v2/INodeSpace.js +18 -0
- package/dist/src/contracts/v2/IUserSpace.js +18 -0
- package/dist/src/contracts/v2/LvRecordableStream.js +1037 -0
- package/dist/src/contracts/v2/LvRecording.js +627 -0
- package/dist/src/contracts/v2/LvStreamRightsHolder.js +562 -0
- package/dist/src/contracts/v2/MetaObject.js +119 -0
- package/dist/src/contracts/v2/Node.js +167 -0
- package/dist/src/contracts/v2/NodeSpace.js +273 -0
- package/dist/src/contracts/v2/Ownable.js +87 -0
- package/dist/src/contracts/v2/PaymentService.js +627 -0
- package/dist/src/contracts/v2/Precompile.js +15 -0
- package/dist/src/contracts/v2/Transactable.js +82 -0
- package/dist/src/contracts/v2/UserSpace.js +29 -0
- package/dist/src/contracts/v2/Utils.js +18 -0
- package/dist/src/contracts/v2/Verifier.js +53 -0
- package/dist/src/contracts/v2/strings.js +4 -0
- package/dist/src/contracts/v3/AccessIndexor.js +774 -0
- package/dist/src/contracts/v3/Accessible.js +232 -0
- package/dist/src/contracts/v3/Adminable.js +107 -0
- package/dist/src/contracts/v3/AvailsDelivery.js +586 -0
- package/dist/src/contracts/v3/BaseAccessControlGroup.js +1603 -0
- package/dist/src/contracts/v3/BaseAccessWallet.js +1628 -0
- package/dist/src/contracts/v3/BaseAccessWalletFactory.js +112 -0
- package/dist/src/contracts/v3/BaseContent.js +1312 -0
- package/dist/src/contracts/v3/BaseContentFactory.js +183 -0
- package/dist/src/contracts/v3/BaseContentFactoryExt.js +175 -0
- package/dist/src/contracts/v3/BaseContentSpace.js +1515 -0
- package/dist/src/contracts/v3/BaseContentType.js +527 -0
- package/dist/src/contracts/v3/BaseFactory.js +126 -0
- package/dist/src/contracts/v3/BaseGroupFactory.js +112 -0
- package/dist/src/contracts/v3/BaseLibrary.js +1204 -0
- package/dist/src/contracts/v3/BaseLibraryFactory.js +115 -0
- package/dist/src/contracts/v3/BaseTenantSpace.js +1587 -0
- package/dist/src/contracts/v3/Certifyer.js +86 -0
- package/dist/src/contracts/v3/Container.js +739 -0
- package/dist/src/contracts/v3/Content.js +438 -0
- package/dist/src/contracts/v3/CounterObject.js +243 -0
- package/dist/src/contracts/v3/Editable.js +519 -0
- package/dist/src/contracts/v3/EncToken.js +4 -0
- package/dist/src/contracts/v3/ExternalUserWallet.js +587 -0
- package/dist/src/contracts/v3/IAdmin.js +18 -0
- package/dist/src/contracts/v3/IFactorySpace.js +57 -0
- package/dist/src/contracts/v3/IKmsSpace.js +52 -0
- package/dist/src/contracts/v3/INodeSpace.js +18 -0
- package/dist/src/contracts/v3/IUserSpace.js +32 -0
- package/dist/src/contracts/v3/LvRecordableStream.js +1032 -0
- package/dist/src/contracts/v3/LvRecording.js +650 -0
- package/dist/src/contracts/v3/LvStreamRightsHolder.js +557 -0
- package/dist/src/contracts/v3/MetaObject.js +144 -0
- package/dist/src/contracts/v3/Node.js +178 -0
- package/dist/src/contracts/v3/NodeSpace.js +284 -0
- package/dist/src/contracts/v3/Ownable.js +98 -0
- package/dist/src/contracts/v3/PaymentService.js +622 -0
- package/dist/src/contracts/v3/Precompile.js +26 -0
- package/dist/src/contracts/v3/TenantFuncsBase.js +351 -0
- package/dist/src/contracts/v3/Transactable.js +82 -0
- package/dist/src/contracts/v3/UserSpace.js +43 -0
- package/dist/src/contracts/v3/Utils.js +18 -0
- package/dist/src/contracts/v3/Verifier.js +53 -0
- package/dist/src/contracts/v3/strings.js +4 -0
- package/dist/src/contracts/v3b/BaseAccessControlGroup.js +1704 -0
- package/dist/src/events/Topics.js +1793 -0
- package/dist/src/index.js +8 -0
- package/dist/src/walletClient/ClientMethods.js +3102 -0
- package/dist/src/walletClient/Configuration.js +38 -0
- package/dist/src/walletClient/Notifications.js +168 -0
- package/dist/src/walletClient/Profile.js +332 -0
- package/dist/src/walletClient/Utils.js +281 -0
- package/dist/src/walletClient/index.js +2109 -0
- package/package.json +1 -1
- package/src/AuthorizationClient.js +24 -16
- package/src/ElvClient.js +19 -0
- package/src/client/ContentAccess.js +20 -2
- package/src/client/LiveConf.js +10 -8
- package/src/client/LiveStream.js +6 -4
|
@@ -0,0 +1,567 @@
|
|
|
1
|
+
var _defineProperty = require("@babel/runtime/helpers/defineProperty");
|
|
2
|
+
var _classCallCheck = require("@babel/runtime/helpers/classCallCheck");
|
|
3
|
+
var _createClass = require("@babel/runtime/helpers/createClass");
|
|
4
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
5
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
6
|
+
/* eslint no-console: 0 */
|
|
7
|
+
|
|
8
|
+
var DefaultABRLadder = {
|
|
9
|
+
"video": [{
|
|
10
|
+
bit_rate: 14000000,
|
|
11
|
+
codecs: "avc1.640028,mp4a.40.2",
|
|
12
|
+
height: 2160,
|
|
13
|
+
width: 3840
|
|
14
|
+
}, {
|
|
15
|
+
bit_rate: 9500000,
|
|
16
|
+
codecs: "avc1.640028,mp4a.40.2",
|
|
17
|
+
height: 1080,
|
|
18
|
+
width: 1920
|
|
19
|
+
}, {
|
|
20
|
+
bit_rate: 4500000,
|
|
21
|
+
codecs: "avc1.640028,mp4a.40.2",
|
|
22
|
+
height: 720,
|
|
23
|
+
width: 1280
|
|
24
|
+
}, {
|
|
25
|
+
bit_rate: 2000000,
|
|
26
|
+
codecs: "avc1.640028,mp4a.40.2",
|
|
27
|
+
height: 540,
|
|
28
|
+
width: 960
|
|
29
|
+
}, {
|
|
30
|
+
bit_rate: 900000,
|
|
31
|
+
codecs: "avc1.640028,mp4a.40.2",
|
|
32
|
+
height: 540,
|
|
33
|
+
width: 960
|
|
34
|
+
}],
|
|
35
|
+
"audio": [{
|
|
36
|
+
bit_rate: 192000,
|
|
37
|
+
channels: 2,
|
|
38
|
+
codecs: "mp4a.40.2"
|
|
39
|
+
}, {
|
|
40
|
+
bit_rate: 384000,
|
|
41
|
+
channels: 6,
|
|
42
|
+
codecs: "mp4a.40.2"
|
|
43
|
+
}]
|
|
44
|
+
};
|
|
45
|
+
var LiveconfTemplate = {
|
|
46
|
+
live_recording: {
|
|
47
|
+
fabric_config: {
|
|
48
|
+
ingress_node_api: "",
|
|
49
|
+
ingress_node_id: ""
|
|
50
|
+
},
|
|
51
|
+
playout_config: {
|
|
52
|
+
dvr_enabled: true,
|
|
53
|
+
dvr_max_duration: 0,
|
|
54
|
+
rebroadcast_start_time_sec_epoch: 0,
|
|
55
|
+
vod_enabled: false
|
|
56
|
+
},
|
|
57
|
+
recording_config: {
|
|
58
|
+
recording_params: {
|
|
59
|
+
description: "",
|
|
60
|
+
ladder_specs: [],
|
|
61
|
+
listen: true,
|
|
62
|
+
live_delay_nano: 2000000000,
|
|
63
|
+
max_duration_sec: -1,
|
|
64
|
+
name: "",
|
|
65
|
+
origin_url: "",
|
|
66
|
+
part_ttl: 3600,
|
|
67
|
+
playout_type: "live",
|
|
68
|
+
source_timescale: null,
|
|
69
|
+
reconnect_timeout: 600,
|
|
70
|
+
xc_params: {
|
|
71
|
+
audio_bitrate: 384000,
|
|
72
|
+
audio_index: [0, 0, 0, 0, 0, 0, 0, 0],
|
|
73
|
+
audio_seg_duration_ts: null,
|
|
74
|
+
connection_timeout: 600,
|
|
75
|
+
ecodec2: "aac",
|
|
76
|
+
enc_height: null,
|
|
77
|
+
enc_width: null,
|
|
78
|
+
filter_descriptor: "",
|
|
79
|
+
force_keyint: null,
|
|
80
|
+
format: "fmp4-segment",
|
|
81
|
+
listen: true,
|
|
82
|
+
n_audio: 1,
|
|
83
|
+
preset: "faster",
|
|
84
|
+
sample_rate: 48000,
|
|
85
|
+
seg_duration: null,
|
|
86
|
+
skip_decoding: false,
|
|
87
|
+
start_segment_str: "1",
|
|
88
|
+
stream_id: -1,
|
|
89
|
+
sync_audio_to_stream_id: -1,
|
|
90
|
+
video_bitrate: null,
|
|
91
|
+
video_seg_duration_ts: null,
|
|
92
|
+
video_time_base: null,
|
|
93
|
+
video_frame_duration_ts: null,
|
|
94
|
+
xc_type: 3
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
var LiveConf = /*#__PURE__*/function () {
|
|
101
|
+
"use strict";
|
|
102
|
+
|
|
103
|
+
function LiveConf(probeData, nodeId, nodeUrl, includeAVSegDurations, overwriteOriginUrl, syncAudioToVideo) {
|
|
104
|
+
_classCallCheck(this, LiveConf);
|
|
105
|
+
this.probeData = probeData;
|
|
106
|
+
this.nodeId = nodeId;
|
|
107
|
+
this.nodeUrl = nodeUrl;
|
|
108
|
+
this.includeAVSegDurations = includeAVSegDurations;
|
|
109
|
+
this.overwriteOriginUrl = overwriteOriginUrl;
|
|
110
|
+
this.syncAudioToVideo = syncAudioToVideo;
|
|
111
|
+
}
|
|
112
|
+
return _createClass(LiveConf, [{
|
|
113
|
+
key: "probeKind",
|
|
114
|
+
value: function probeKind() {
|
|
115
|
+
var fileNameSplit = this.probeData.format.filename.split(":");
|
|
116
|
+
return fileNameSplit[0];
|
|
117
|
+
}
|
|
118
|
+
}, {
|
|
119
|
+
key: "getStreamDataForCodecType",
|
|
120
|
+
value: function getStreamDataForCodecType(codecType) {
|
|
121
|
+
var stream = null;
|
|
122
|
+
for (var index = 0; index < this.probeData.streams.length; index++) {
|
|
123
|
+
if (this.probeData.streams[index].codec_type == codecType) {
|
|
124
|
+
stream = this.probeData.streams[index];
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return stream;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Return all audio streams found in the probe
|
|
131
|
+
// Used by generateAudioStreamsConfig()
|
|
132
|
+
}, {
|
|
133
|
+
key: "getAudioStreamsFromProbe",
|
|
134
|
+
value: function getAudioStreamsFromProbe() {
|
|
135
|
+
var audioStreams = {};
|
|
136
|
+
for (var index = 0; index < this.probeData.streams.length; index++) {
|
|
137
|
+
if (this.probeData.streams[index].codec_type == "audio") {
|
|
138
|
+
audioStreams[index] = {
|
|
139
|
+
recordingBitrate: Math.max(this.probeData.streams[index].bit_rate, 128000),
|
|
140
|
+
recordingChannels: this.probeData.streams[index].channels,
|
|
141
|
+
playoutLabel: "Audio ".concat(index)
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return audioStreams;
|
|
146
|
+
}
|
|
147
|
+
}, {
|
|
148
|
+
key: "getFrameRate",
|
|
149
|
+
value: function getFrameRate() {
|
|
150
|
+
var videoStream = this.getStreamDataForCodecType("video");
|
|
151
|
+
var frameRate = videoStream.r_frame_rate || videoStream.frame_rate;
|
|
152
|
+
return frameRate.split("/");
|
|
153
|
+
}
|
|
154
|
+
}, {
|
|
155
|
+
key: "isFrameRateWhole",
|
|
156
|
+
value: function isFrameRateWhole() {
|
|
157
|
+
var frameRate = this.getFrameRate();
|
|
158
|
+
return frameRate[1] == "1";
|
|
159
|
+
}
|
|
160
|
+
}, {
|
|
161
|
+
key: "getForceKeyint",
|
|
162
|
+
value: function getForceKeyint() {
|
|
163
|
+
var frameRate = this.getFrameRate();
|
|
164
|
+
var roundedFrameRate = Math.round(frameRate[0] / frameRate[1]);
|
|
165
|
+
if (roundedFrameRate > 30) {
|
|
166
|
+
return roundedFrameRate;
|
|
167
|
+
} else {
|
|
168
|
+
return roundedFrameRate * 2;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/*
|
|
173
|
+
* Calculates mez segment durations based on input stream parameters
|
|
174
|
+
*
|
|
175
|
+
* Live input formats have fixed timebase:
|
|
176
|
+
* - MPEG-TS/SRT input stream timebase is 90000
|
|
177
|
+
* - RTMP input stream timebase is 1000 and gets translated to 16000 if not otherwise specified
|
|
178
|
+
*
|
|
179
|
+
* This causes frame duration irregularities for certain frame rates.
|
|
180
|
+
* For example RTMP 60fps has frames of durations 16 and 17. MPEG-TS 59.94fps has frames of
|
|
181
|
+
* durations 1001 and 1002.
|
|
182
|
+
*
|
|
183
|
+
* Live mez segmentation requires that the segment be cut at the specific number of frames, and when
|
|
184
|
+
* the frame durations are irregular we adjust both the video timebase and the video frame duration
|
|
185
|
+
* to make the math possible. This adjustment is also required for live-to-vod conversion.
|
|
186
|
+
*
|
|
187
|
+
* For example for MPEG-TS 59.94fps, the mez segment timebase needs to be 60000
|
|
188
|
+
* (and resulting frame duration is 1001) and for RTMP 60fps the timebase needs to be 15360 (resulting frame
|
|
189
|
+
* duration is 256).
|
|
190
|
+
*
|
|
191
|
+
* @sourceTimescale - adjusted source video stream timescale (eg. MPEGTS 90000, RTMP 16000 )
|
|
192
|
+
* @sampleRate - audio sample rate (commonly 48000 but can be different)
|
|
193
|
+
* @audioCodec - audio codec as a string (eg. "aac")
|
|
194
|
+
* @return - segment encoding parameters
|
|
195
|
+
*/
|
|
196
|
+
}, {
|
|
197
|
+
key: "calcSegDuration",
|
|
198
|
+
value: function calcSegDuration(_ref) {
|
|
199
|
+
var sourceTimescale = _ref.sourceTimescale,
|
|
200
|
+
sampleRate = _ref.sampleRate,
|
|
201
|
+
audioCodec = _ref.audioCodec;
|
|
202
|
+
var seg = {};
|
|
203
|
+
switch (this.probeKind()) {
|
|
204
|
+
case "rtmp":
|
|
205
|
+
seg = this.calcSegDurationRtmp({
|
|
206
|
+
sourceTimescale: sourceTimescale,
|
|
207
|
+
sampleRate: sampleRate,
|
|
208
|
+
audioCodec: audioCodec
|
|
209
|
+
});
|
|
210
|
+
break;
|
|
211
|
+
case "udp":
|
|
212
|
+
case "srt":
|
|
213
|
+
seg = this.calcSegDurationMpegts({
|
|
214
|
+
sourceTimescale: sourceTimescale,
|
|
215
|
+
sampleRate: sampleRate,
|
|
216
|
+
audioCodec: audioCodec
|
|
217
|
+
});
|
|
218
|
+
break;
|
|
219
|
+
default:
|
|
220
|
+
throw "protocol not supported - " + this.probeKind();
|
|
221
|
+
}
|
|
222
|
+
if (audioCodec == "aac") {
|
|
223
|
+
seg.audio = 29.76 * sampleRate;
|
|
224
|
+
} else {
|
|
225
|
+
seg.audio = 29.76 * 48000; // Other codecs are resampled @48000
|
|
226
|
+
}
|
|
227
|
+
return seg;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/*
|
|
231
|
+
* Calculate output timebase from the encoder (codec) timebase. The videoTimeBase parameter
|
|
232
|
+
* represents the encoder timebase. The format muxer will change it so it is greater than 10000.
|
|
233
|
+
*/
|
|
234
|
+
}, {
|
|
235
|
+
key: "calcOutputTimebase",
|
|
236
|
+
value: function calcOutputTimebase(codecTimebase) {
|
|
237
|
+
var outputTimebase = codecTimebase;
|
|
238
|
+
while (outputTimebase < 10000) outputTimebase = outputTimebase * 2;
|
|
239
|
+
return outputTimebase;
|
|
240
|
+
}
|
|
241
|
+
}, {
|
|
242
|
+
key: "calcSegDurationMpegts",
|
|
243
|
+
value: function calcSegDurationMpegts(_ref2) {
|
|
244
|
+
var sourceTimescale = _ref2.sourceTimescale;
|
|
245
|
+
var videoStream = this.getStreamDataForCodecType("video");
|
|
246
|
+
var frameRate = videoStream.frame_rate;
|
|
247
|
+
|
|
248
|
+
// PENDING(SS) - calculate frame duration here
|
|
249
|
+
// let frameRateNum = 0;
|
|
250
|
+
var seg = {
|
|
251
|
+
// videoFrameDurationTs: sourceTimescale / frameRateNum
|
|
252
|
+
};
|
|
253
|
+
switch (frameRate) {
|
|
254
|
+
case "24":
|
|
255
|
+
seg.video = sourceTimescale * 30;
|
|
256
|
+
seg.keyint = 48;
|
|
257
|
+
seg.duration = "30";
|
|
258
|
+
break;
|
|
259
|
+
case "25":
|
|
260
|
+
seg.video = sourceTimescale * 30;
|
|
261
|
+
seg.keyint = 50;
|
|
262
|
+
seg.duration = "30";
|
|
263
|
+
break;
|
|
264
|
+
case "30":
|
|
265
|
+
seg.video = sourceTimescale * 30;
|
|
266
|
+
seg.keyint = 60;
|
|
267
|
+
seg.duration = "30";
|
|
268
|
+
break;
|
|
269
|
+
case "30000/1001":
|
|
270
|
+
//seg.videoFrameDurationTs = 3003;
|
|
271
|
+
seg.video = sourceTimescale * 30;
|
|
272
|
+
seg.keyint = 60;
|
|
273
|
+
seg.duration = "30.03";
|
|
274
|
+
break;
|
|
275
|
+
case "48":
|
|
276
|
+
//seg.videoFrameDurationTs = 1875;
|
|
277
|
+
seg.video = sourceTimescale * 30;
|
|
278
|
+
seg.keyint = 96;
|
|
279
|
+
seg.duration = "30";
|
|
280
|
+
break;
|
|
281
|
+
case "50":
|
|
282
|
+
//seg.videoFrameDurationTs = 1800;
|
|
283
|
+
seg.video = sourceTimescale * 30;
|
|
284
|
+
seg.keyint = 100;
|
|
285
|
+
seg.duration = "30";
|
|
286
|
+
break;
|
|
287
|
+
case "60":
|
|
288
|
+
//seg.videoFrameDurationTs = 1500;
|
|
289
|
+
seg.video = sourceTimescale * 30;
|
|
290
|
+
seg.keyint = 120;
|
|
291
|
+
seg.duration = "30";
|
|
292
|
+
break;
|
|
293
|
+
case "60000/1001":
|
|
294
|
+
seg.videoTimeBase = 60000;
|
|
295
|
+
seg.video = seg.videoTimeBase * 30.03;
|
|
296
|
+
seg.keyint = 120;
|
|
297
|
+
seg.duration = "30.03";
|
|
298
|
+
break;
|
|
299
|
+
default:
|
|
300
|
+
throw "unsupported frame rate for MPEGTS - " + frameRate;
|
|
301
|
+
}
|
|
302
|
+
return seg;
|
|
303
|
+
}
|
|
304
|
+
}, {
|
|
305
|
+
key: "calcSegDurationRtmp",
|
|
306
|
+
value: function calcSegDurationRtmp(_ref3) {
|
|
307
|
+
var sourceTimescale = _ref3.sourceTimescale;
|
|
308
|
+
var videoStream = this.getStreamDataForCodecType("video");
|
|
309
|
+
var frameRate = videoStream.frame_rate;
|
|
310
|
+
var seg = {};
|
|
311
|
+
switch (frameRate) {
|
|
312
|
+
case "24":
|
|
313
|
+
seg.videoTimeBase = 768; // Note 1536 produces low output bitrate
|
|
314
|
+
seg.videoFrameDurationTs = 512;
|
|
315
|
+
seg.video = this.calcOutputTimebase(seg.videoTimeBase) * 30;
|
|
316
|
+
seg.keyint = 48;
|
|
317
|
+
seg.duration = "30";
|
|
318
|
+
break;
|
|
319
|
+
case "25":
|
|
320
|
+
seg.video = sourceTimescale * 30;
|
|
321
|
+
seg.keyint = 50;
|
|
322
|
+
seg.duration = "30";
|
|
323
|
+
break;
|
|
324
|
+
case "30":
|
|
325
|
+
seg.videoTimeBase = 960; // Output timebase: 15360
|
|
326
|
+
seg.videoFrameDurationTs = 512;
|
|
327
|
+
seg.video = this.calcOutputTimebase(seg.videoTimeBase) * 30;
|
|
328
|
+
seg.keyint = 60;
|
|
329
|
+
seg.duration = "30";
|
|
330
|
+
break;
|
|
331
|
+
case "30000/1001":
|
|
332
|
+
seg.video = sourceTimescale * 30.03;
|
|
333
|
+
seg.keyint = 60;
|
|
334
|
+
seg.duration = "30.03";
|
|
335
|
+
break;
|
|
336
|
+
case "48":
|
|
337
|
+
seg.videoTimeBase = 1536; // Output timebase: 12288
|
|
338
|
+
seg.videoFrameDurationTs = 256;
|
|
339
|
+
seg.video = this.calcOutputTimebase(seg.videoTimeBase) * 30;
|
|
340
|
+
seg.keyint = 96;
|
|
341
|
+
seg.duration = "30";
|
|
342
|
+
break;
|
|
343
|
+
case "50":
|
|
344
|
+
seg.video = sourceTimescale * 30;
|
|
345
|
+
seg.keyint = 100;
|
|
346
|
+
seg.duration = "30";
|
|
347
|
+
break;
|
|
348
|
+
case "60":
|
|
349
|
+
seg.videoTimeBase = 960; // Output timebase: 15360
|
|
350
|
+
seg.videoFrameDurationTs = 256;
|
|
351
|
+
seg.video = this.calcOutputTimebase(seg.videoTimeBase) * 30;
|
|
352
|
+
seg.keyint = 120;
|
|
353
|
+
seg.duration = "30";
|
|
354
|
+
break;
|
|
355
|
+
case "60000/1001":
|
|
356
|
+
seg.video = sourceTimescale * 30.03;
|
|
357
|
+
seg.keyint = 120;
|
|
358
|
+
seg.duration = "30.03";
|
|
359
|
+
break;
|
|
360
|
+
default:
|
|
361
|
+
throw "unsupported frame rate for RTMP - " + frameRate;
|
|
362
|
+
}
|
|
363
|
+
return seg;
|
|
364
|
+
}
|
|
365
|
+
}, {
|
|
366
|
+
key: "syncAudioToStreamIdValue",
|
|
367
|
+
value: function syncAudioToStreamIdValue() {
|
|
368
|
+
var sync_id = -1;
|
|
369
|
+
var videoStream = this.getStreamDataForCodecType("video");
|
|
370
|
+
switch (this.probeKind()) {
|
|
371
|
+
case "udp":
|
|
372
|
+
case "srt":
|
|
373
|
+
sync_id = videoStream.stream_id;
|
|
374
|
+
break;
|
|
375
|
+
case "rtmp":
|
|
376
|
+
sync_id = videoStream.stream_index;
|
|
377
|
+
break;
|
|
378
|
+
}
|
|
379
|
+
return sync_id;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/*
|
|
383
|
+
* Generate audio streams recording configuration based on the optional custom settings.
|
|
384
|
+
* If no custom "audio" section is present, record all the acceptable audio streams found in the probe
|
|
385
|
+
*/
|
|
386
|
+
}, {
|
|
387
|
+
key: "generateAudioStreamsConfig",
|
|
388
|
+
value: function generateAudioStreamsConfig(_ref4) {
|
|
389
|
+
var customSettings = _ref4.customSettings;
|
|
390
|
+
var audioStreams = {};
|
|
391
|
+
if (customSettings && customSettings.audio && Object.keys(customSettings.audio).length > 0) {
|
|
392
|
+
for (var i = 0; i < Object.keys(customSettings.audio).length; i++) {
|
|
393
|
+
var audioIdx = Object.keys(customSettings.audio)[i];
|
|
394
|
+
var audio = customSettings.audio[audioIdx];
|
|
395
|
+
audioStreams[audioIdx] = {
|
|
396
|
+
recordingBitrate: audio.recording_bitrate || 192000,
|
|
397
|
+
recordingChannels: audio.recording_channels || 2
|
|
398
|
+
};
|
|
399
|
+
if (audio.playout) {
|
|
400
|
+
audioStreams[audioIdx].playoutLabel = audio.playout_label || "Audio ".concat(audioIdx);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
// If no audio streams specified in custom config, set up all the suitable audio streams in the probe
|
|
406
|
+
if (!customSettings.audio || Object.keys(customSettings.audio).length == 0) {
|
|
407
|
+
audioStreams = this.getAudioStreamsFromProbe();
|
|
408
|
+
}
|
|
409
|
+
return audioStreams;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
/*
|
|
413
|
+
* Generate the live recording config as required by QFAB, based on defaults and optional custom settings.
|
|
414
|
+
*/
|
|
415
|
+
}, {
|
|
416
|
+
key: "generateLiveConf",
|
|
417
|
+
value: function generateLiveConf(_ref5) {
|
|
418
|
+
var customSettings = _ref5.customSettings;
|
|
419
|
+
// gather required data
|
|
420
|
+
var conf = JSON.parse(JSON.stringify(LiveconfTemplate));
|
|
421
|
+
var fileName = this.overwriteOriginUrl || this.probeData.format.filename;
|
|
422
|
+
var audioStreams = this.generateAudioStreamsConfig({
|
|
423
|
+
customSettings: customSettings
|
|
424
|
+
});
|
|
425
|
+
|
|
426
|
+
// Retrieve one audio stream from the probe to read the sample rate and codec name
|
|
427
|
+
var audioStream = this.getStreamDataForCodecType("audio");
|
|
428
|
+
var sampleRate = parseInt(audioStream.sample_rate);
|
|
429
|
+
var audioCodec = audioStream.codec_name;
|
|
430
|
+
var videoStream = this.getStreamDataForCodecType("video");
|
|
431
|
+
var sourceTimescale;
|
|
432
|
+
|
|
433
|
+
// Fill in liveconf all formats have in common
|
|
434
|
+
conf.live_recording.fabric_config.ingress_node_api = this.nodeUrl || null;
|
|
435
|
+
conf.live_recording.fabric_config.ingress_node_id = this.nodeId || null;
|
|
436
|
+
conf.live_recording.recording_config.recording_params.description;
|
|
437
|
+
conf.live_recording.recording_config.recording_params.origin_url = fileName;
|
|
438
|
+
conf.live_recording.recording_config.recording_params.description = "Ingest stream ".concat(fileName);
|
|
439
|
+
conf.live_recording.recording_config.recording_params.name = "Ingest stream ".concat(fileName);
|
|
440
|
+
conf.live_recording.recording_config.recording_params.xc_params.sample_rate = sampleRate;
|
|
441
|
+
conf.live_recording.recording_config.recording_params.xc_params.enc_height = videoStream.height;
|
|
442
|
+
conf.live_recording.recording_config.recording_params.xc_params.enc_width = videoStream.width;
|
|
443
|
+
for (var i = 0; i < Object.keys(audioStreams).length; i++) {
|
|
444
|
+
conf.live_recording.recording_config.recording_params.xc_params.audio_index[i] = parseInt(Object.keys(audioStreams)[i]);
|
|
445
|
+
}
|
|
446
|
+
if (this.syncAudioToVideo) {
|
|
447
|
+
conf.live_recording.recording_config.recording_params.xc_params.sync_audio_to_stream_id = this.syncAudioToStreamIdValue();
|
|
448
|
+
}
|
|
449
|
+
if (customSettings.edge_write_token) {
|
|
450
|
+
conf.live_recording.fabric_config.edge_write_token = customSettings.edge_write_token;
|
|
451
|
+
}
|
|
452
|
+
if (customSettings.part_ttl) {
|
|
453
|
+
conf.live_recording.recording_config.recording_params.part_ttl = customSettings.part_ttl;
|
|
454
|
+
}
|
|
455
|
+
if (customSettings.connection_timeout) {
|
|
456
|
+
conf.live_recording.recording_config.recording_params.xc_params.connection_timeout = customSettings.connection_timeout;
|
|
457
|
+
}
|
|
458
|
+
if (customSettings.reconnect_timeout) {
|
|
459
|
+
conf.live_recording.recording_config.recording_params.reconnect_timeout = customSettings.reconnect_timeout;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
// Fill in specifics for protocol
|
|
463
|
+
switch (this.probeKind()) {
|
|
464
|
+
case "udp":
|
|
465
|
+
sourceTimescale = 90000;
|
|
466
|
+
conf.live_recording.recording_config.recording_params.source_timescale = sourceTimescale;
|
|
467
|
+
break;
|
|
468
|
+
case "srt":
|
|
469
|
+
sourceTimescale = 90000;
|
|
470
|
+
conf.live_recording.recording_config.recording_params.source_timescale = sourceTimescale;
|
|
471
|
+
conf.live_recording.recording_config.recording_params.live_delay_nano = 4000000000;
|
|
472
|
+
break;
|
|
473
|
+
case "rtmp":
|
|
474
|
+
sourceTimescale = 16000;
|
|
475
|
+
conf.live_recording.recording_config.recording_params.source_timescale = sourceTimescale;
|
|
476
|
+
break;
|
|
477
|
+
case "hls":
|
|
478
|
+
console.log("HLS detected. Not yet implemented");
|
|
479
|
+
break;
|
|
480
|
+
default:
|
|
481
|
+
console.log("Unsupported media", this.probeKind());
|
|
482
|
+
break;
|
|
483
|
+
}
|
|
484
|
+
var segDurations = this.calcSegDuration({
|
|
485
|
+
sourceTimescale: sourceTimescale,
|
|
486
|
+
sampleRate: sampleRate,
|
|
487
|
+
audioCodec: audioCodec
|
|
488
|
+
});
|
|
489
|
+
|
|
490
|
+
// Segment conditioning parameters
|
|
491
|
+
conf.live_recording.recording_config.recording_params.xc_params.seg_duration = segDurations.duration;
|
|
492
|
+
conf.live_recording.recording_config.recording_params.xc_params.audio_seg_duration_ts = segDurations.audio;
|
|
493
|
+
conf.live_recording.recording_config.recording_params.xc_params.video_seg_duration_ts = segDurations.video;
|
|
494
|
+
conf.live_recording.recording_config.recording_params.xc_params.force_keyint = segDurations.keyint;
|
|
495
|
+
|
|
496
|
+
// Optional override output timebase and frame duration (ts)
|
|
497
|
+
if (segDurations.videoTimeBase) {
|
|
498
|
+
conf.live_recording.recording_config.recording_params.xc_params.video_time_base = segDurations.videoTimeBase;
|
|
499
|
+
|
|
500
|
+
// Note 'source_timescale' needs to be set to the output timebase and is used by playout
|
|
501
|
+
conf.live_recording.recording_config.recording_params.source_timescale = this.calcOutputTimebase(segDurations.videoTimeBase);
|
|
502
|
+
}
|
|
503
|
+
if (segDurations.videoFrameDurationTs) {
|
|
504
|
+
conf.live_recording.recording_config.recording_params.xc_params.video_frame_duration_ts = segDurations.videoFrameDurationTs;
|
|
505
|
+
}
|
|
506
|
+
var ladderProfile = customSettings.ladder_profile || DefaultABRLadder;
|
|
507
|
+
conf.live_recording.recording_config.recording_params.xc_params.enc_height = videoStream.height;
|
|
508
|
+
conf.live_recording.recording_config.recording_params.xc_params.enc_width = videoStream.width;
|
|
509
|
+
|
|
510
|
+
// Determine video recording bitrate and ABR ladder
|
|
511
|
+
var topLadderRate = 0;
|
|
512
|
+
for (var _i = 0; _i < ladderProfile.video.length; _i++) {
|
|
513
|
+
var elem = ladderProfile.video[_i];
|
|
514
|
+
if (elem.height > videoStream.height) continue;
|
|
515
|
+
if (elem.bit_rate > topLadderRate) {
|
|
516
|
+
topLadderRate = elem.bit_rate;
|
|
517
|
+
}
|
|
518
|
+
elem.media_type = 1;
|
|
519
|
+
elem.stream_name = "video";
|
|
520
|
+
elem.stream_index = 0;
|
|
521
|
+
elem.representation = "videovideo_" + elem.width + "x" + elem.height + "_h264@" + elem.bit_rate;
|
|
522
|
+
conf.live_recording.recording_config.recording_params.ladder_specs.push(elem);
|
|
523
|
+
}
|
|
524
|
+
// Currently the recording bitrate is the top bitrate of the ladder (it will be configurable separately in the future)
|
|
525
|
+
conf.live_recording.recording_config.recording_params.xc_params.video_bitrate = topLadderRate;
|
|
526
|
+
|
|
527
|
+
// Determine audio recording bitrate and ABR ladder
|
|
528
|
+
var globalAudioBitrate = 0;
|
|
529
|
+
var nAudio = 0;
|
|
530
|
+
for (var _i2 = 0; _i2 < Object.keys(audioStreams).length; _i2++) {
|
|
531
|
+
var audioLadderSpec = {};
|
|
532
|
+
var audioIndex = Object.keys(audioStreams)[_i2];
|
|
533
|
+
var audio = audioStreams[audioIndex];
|
|
534
|
+
|
|
535
|
+
// Find ladder rung for the specific channel layout (2 or 6 channels)
|
|
536
|
+
for (var j = 0; j < ladderProfile.audio.length; j++) {
|
|
537
|
+
var _elem = ladderProfile.audio[j];
|
|
538
|
+
if (_elem.channels == audio.recordingChannels) {
|
|
539
|
+
audioLadderSpec = _objectSpread({}, _elem);
|
|
540
|
+
break;
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
if (Object.keys(audioLadderSpec).length === 0) {
|
|
544
|
+
// If no channels layout match, just use the first element in the ladder
|
|
545
|
+
audioLadderSpec = _objectSpread({}, ladderProfile.audio[0]);
|
|
546
|
+
}
|
|
547
|
+
audioLadderSpec.representation = "audioaudio_aac@".concat(audioLadderSpec.bit_rate);
|
|
548
|
+
audioLadderSpec.channels = audio.recordingChannels;
|
|
549
|
+
audioLadderSpec.stream_index = parseInt(audioIndex);
|
|
550
|
+
audioLadderSpec.stream_name = "audio_".concat(audioIndex);
|
|
551
|
+
audioLadderSpec.stream_label = audio.playoutLabel ? audio.playoutLabel : null;
|
|
552
|
+
audioLadderSpec.media_type = 2;
|
|
553
|
+
conf.live_recording.recording_config.recording_params.ladder_specs.push(audioLadderSpec);
|
|
554
|
+
if (audio.recordingBitrate > globalAudioBitrate) {
|
|
555
|
+
globalAudioBitrate = audio.recordingBitrate;
|
|
556
|
+
}
|
|
557
|
+
nAudio++;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
// Global recording bitrate for all audio streams
|
|
561
|
+
conf.live_recording.recording_config.recording_params.xc_params.audio_bitrate = globalAudioBitrate;
|
|
562
|
+
conf.live_recording.recording_config.recording_params.xc_params.n_audio = nAudio;
|
|
563
|
+
return conf;
|
|
564
|
+
}
|
|
565
|
+
}]);
|
|
566
|
+
}();
|
|
567
|
+
exports.LiveConf = LiveConf;
|