@editframe/assets 0.16.8-beta.0 → 0.17.6-beta.0
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/DecoderManager.d.ts +62 -0
- package/dist/DecoderManager.js +114 -0
- package/dist/EncodedAsset.d.ts +58 -16
- package/dist/EncodedAsset.js +436 -565
- package/dist/FrameBuffer.d.ts +62 -0
- package/dist/FrameBuffer.js +89 -0
- package/dist/MP4File.d.ts +9 -1
- package/dist/MP4File.js +205 -219
- package/dist/MP4SampleAnalyzer.d.ts +59 -0
- package/dist/MP4SampleAnalyzer.js +119 -0
- package/dist/Probe.d.ts +1 -0
- package/dist/Probe.js +273 -309
- package/dist/SeekStrategy.d.ts +82 -0
- package/dist/SeekStrategy.js +101 -0
- package/dist/VideoRenderOptions.js +31 -33
- package/dist/idempotentTask.js +78 -78
- package/dist/index.js +1 -15
- package/dist/md5.js +35 -51
- package/dist/memoize.js +9 -12
- package/dist/mp4FileWritable.js +16 -18
- package/dist/tasks/cacheImage.js +13 -15
- package/dist/tasks/findOrCreateCaptions.js +18 -21
- package/dist/tasks/generateTrack.js +45 -63
- package/dist/tasks/generateTrackFragmentIndex.js +88 -101
- package/package.json +4 -4
- package/types.json +1 -1
package/dist/Probe.js
CHANGED
|
@@ -1,321 +1,285 @@
|
|
|
1
|
+
import debug from "debug";
|
|
1
2
|
import { exec, spawn } from "node:child_process";
|
|
2
3
|
import { promisify } from "node:util";
|
|
3
4
|
import { createReadStream } from "node:fs";
|
|
4
|
-
import * as z from "zod";
|
|
5
|
-
import debug from "debug";
|
|
5
|
+
import * as z$1 from "zod";
|
|
6
6
|
const execPromise = promisify(exec);
|
|
7
7
|
const log = debug("ef:assets:probe");
|
|
8
|
-
const AudioStreamSchema = z.object({
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
8
|
+
const AudioStreamSchema = z$1.object({
|
|
9
|
+
index: z$1.number(),
|
|
10
|
+
codec_name: z$1.string(),
|
|
11
|
+
codec_long_name: z$1.string(),
|
|
12
|
+
codec_type: z$1.literal("audio"),
|
|
13
|
+
codec_tag_string: z$1.string(),
|
|
14
|
+
codec_tag: z$1.string(),
|
|
15
|
+
sample_fmt: z$1.string(),
|
|
16
|
+
sample_rate: z$1.string(),
|
|
17
|
+
channels: z$1.number(),
|
|
18
|
+
channel_layout: z$1.string().optional(),
|
|
19
|
+
bits_per_sample: z$1.number(),
|
|
20
|
+
initial_padding: z$1.number().optional(),
|
|
21
|
+
r_frame_rate: z$1.string(),
|
|
22
|
+
avg_frame_rate: z$1.string(),
|
|
23
|
+
time_base: z$1.string(),
|
|
24
|
+
start_pts: z$1.number().optional(),
|
|
25
|
+
start_time: z$1.coerce.number().optional(),
|
|
26
|
+
duration_ts: z$1.number(),
|
|
27
|
+
duration: z$1.coerce.number(),
|
|
28
|
+
bit_rate: z$1.string(),
|
|
29
|
+
disposition: z$1.record(z$1.unknown())
|
|
30
30
|
});
|
|
31
|
-
const VideoStreamSchema = z.object({
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
31
|
+
const VideoStreamSchema = z$1.object({
|
|
32
|
+
index: z$1.number(),
|
|
33
|
+
codec_name: z$1.string(),
|
|
34
|
+
codec_long_name: z$1.string(),
|
|
35
|
+
codec_type: z$1.literal("video"),
|
|
36
|
+
codec_tag_string: z$1.string(),
|
|
37
|
+
codec_tag: z$1.string(),
|
|
38
|
+
width: z$1.number(),
|
|
39
|
+
height: z$1.number(),
|
|
40
|
+
coded_width: z$1.number(),
|
|
41
|
+
coded_height: z$1.number(),
|
|
42
|
+
r_frame_rate: z$1.string(),
|
|
43
|
+
avg_frame_rate: z$1.string(),
|
|
44
|
+
time_base: z$1.string(),
|
|
45
|
+
start_pts: z$1.number().optional(),
|
|
46
|
+
start_time: z$1.coerce.number().optional(),
|
|
47
|
+
duration_ts: z$1.number().optional(),
|
|
48
|
+
duration: z$1.coerce.number().optional(),
|
|
49
|
+
bit_rate: z$1.string().optional(),
|
|
50
|
+
disposition: z$1.record(z$1.unknown())
|
|
51
51
|
});
|
|
52
|
-
const ProbeFormatSchema = z.object({
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
52
|
+
const ProbeFormatSchema = z$1.object({
|
|
53
|
+
filename: z$1.string(),
|
|
54
|
+
nb_streams: z$1.number(),
|
|
55
|
+
nb_programs: z$1.number(),
|
|
56
|
+
format_name: z$1.string(),
|
|
57
|
+
format_long_name: z$1.string(),
|
|
58
|
+
start_time: z$1.string().optional(),
|
|
59
|
+
duration: z$1.string().optional(),
|
|
60
|
+
size: z$1.string().optional(),
|
|
61
|
+
bit_rate: z$1.string().optional(),
|
|
62
|
+
probe_score: z$1.number()
|
|
63
63
|
});
|
|
64
|
-
const DataStreamSchema = z.object({
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
64
|
+
const DataStreamSchema = z$1.object({
|
|
65
|
+
index: z$1.number(),
|
|
66
|
+
codec_type: z$1.literal("data"),
|
|
67
|
+
duration: z$1.string().optional()
|
|
68
68
|
});
|
|
69
|
-
const StreamSchema = z.discriminatedUnion("codec_type", [
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
69
|
+
const StreamSchema = z$1.discriminatedUnion("codec_type", [
|
|
70
|
+
AudioStreamSchema,
|
|
71
|
+
VideoStreamSchema,
|
|
72
|
+
DataStreamSchema
|
|
73
73
|
]);
|
|
74
|
-
const ProbeSchema = z.object({
|
|
75
|
-
|
|
76
|
-
|
|
74
|
+
const ProbeSchema = z$1.object({
|
|
75
|
+
streams: z$1.array(StreamSchema),
|
|
76
|
+
format: ProbeFormatSchema
|
|
77
77
|
});
|
|
78
|
-
class Probe {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
285
|
-
});
|
|
286
|
-
ffmpegConformer.stderr.on("data", (data) => {
|
|
287
|
-
log("CONFORMER: ", data.toString());
|
|
288
|
-
});
|
|
289
|
-
const ffmpegFragmentArgs = [
|
|
290
|
-
"-i",
|
|
291
|
-
"-",
|
|
292
|
-
"-c",
|
|
293
|
-
"copy",
|
|
294
|
-
"-f",
|
|
295
|
-
"mp4",
|
|
296
|
-
...fragmenterArgs,
|
|
297
|
-
"pipe:1"
|
|
298
|
-
];
|
|
299
|
-
log("Running ffmpeg", ffmpegFragmentArgs);
|
|
300
|
-
const ffmpegFragmenter = spawn("ffmpeg", ffmpegFragmentArgs, {
|
|
301
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
302
|
-
});
|
|
303
|
-
ffmpegConformer.stdout.pipe(ffmpegFragmenter.stdin);
|
|
304
|
-
ffmpegFragmenter.stderr.on("data", (data) => {
|
|
305
|
-
log("FRAGMENTER: ", data.toString());
|
|
306
|
-
});
|
|
307
|
-
ffmpegConformer.on("error", (error) => {
|
|
308
|
-
ffmpegFragmenter.stdout.emit("error", error);
|
|
309
|
-
});
|
|
310
|
-
ffmpegFragmenter.on("error", (error) => {
|
|
311
|
-
ffmpegFragmenter.stdout.emit("error", error);
|
|
312
|
-
});
|
|
313
|
-
return ffmpegFragmenter.stdout;
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
export {
|
|
317
|
-
AudioStreamSchema,
|
|
318
|
-
DataStreamSchema,
|
|
319
|
-
Probe,
|
|
320
|
-
VideoStreamSchema
|
|
78
|
+
var Probe = class Probe {
|
|
79
|
+
static async probePath(absolutePath) {
|
|
80
|
+
const probeCommand = `ffprobe -v error -show_format -show_streams -of json ${absolutePath}`;
|
|
81
|
+
log("Probing", probeCommand);
|
|
82
|
+
const probeResult = await execPromise(probeCommand);
|
|
83
|
+
log("Probe result", probeResult.stdout);
|
|
84
|
+
log("Probe stderr", probeResult.stderr);
|
|
85
|
+
const json = JSON.parse(probeResult.stdout);
|
|
86
|
+
return new Probe(absolutePath, json);
|
|
87
|
+
}
|
|
88
|
+
static async probeStream(stream) {
|
|
89
|
+
const probe = spawn("ffprobe", [
|
|
90
|
+
"-i",
|
|
91
|
+
"-",
|
|
92
|
+
"-v",
|
|
93
|
+
"error",
|
|
94
|
+
"-show_format",
|
|
95
|
+
"-show_streams",
|
|
96
|
+
"-of",
|
|
97
|
+
"json"
|
|
98
|
+
], { stdio: [
|
|
99
|
+
"pipe",
|
|
100
|
+
"pipe",
|
|
101
|
+
"pipe"
|
|
102
|
+
] });
|
|
103
|
+
const chunks = [];
|
|
104
|
+
const processExit = new Promise((_, reject) => {
|
|
105
|
+
probe.on("exit", (code) => {
|
|
106
|
+
if (code !== 0) reject(/* @__PURE__ */ new Error(`ffprobe exited with code ${code}`));
|
|
107
|
+
});
|
|
108
|
+
probe.on("error", (err) => reject(err));
|
|
109
|
+
});
|
|
110
|
+
probe.stderr.on("data", (data) => {
|
|
111
|
+
log(data.toString());
|
|
112
|
+
});
|
|
113
|
+
probe.stdout.on("data", (data) => {
|
|
114
|
+
chunks.push(data);
|
|
115
|
+
});
|
|
116
|
+
probe.stdin.on("error", (error) => {
|
|
117
|
+
if (error.code === "EPIPE") {
|
|
118
|
+
log("ffprobe closed input pipe");
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
log("ffprobe stdin error", error);
|
|
122
|
+
});
|
|
123
|
+
stream.pipe(probe.stdin);
|
|
124
|
+
try {
|
|
125
|
+
const json = await Promise.race([new Promise((resolve, reject) => {
|
|
126
|
+
probe.stdout.on("end", () => {
|
|
127
|
+
try {
|
|
128
|
+
const buffer = Buffer.concat(chunks).toString("utf8");
|
|
129
|
+
log("Got probe from stream", buffer);
|
|
130
|
+
resolve(JSON.parse(buffer));
|
|
131
|
+
} catch (error) {
|
|
132
|
+
reject(error);
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
}), processExit]);
|
|
136
|
+
return new Probe("pipe:0", json);
|
|
137
|
+
} finally {
|
|
138
|
+
stream.unpipe(probe.stdin);
|
|
139
|
+
probe.stdin.end();
|
|
140
|
+
stream.destroy();
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
constructor(absolutePath, rawData) {
|
|
144
|
+
this.absolutePath = absolutePath;
|
|
145
|
+
this.data = ProbeSchema.parse(rawData);
|
|
146
|
+
}
|
|
147
|
+
get audioStreams() {
|
|
148
|
+
return this.data.streams.filter((stream) => stream.codec_type === "audio");
|
|
149
|
+
}
|
|
150
|
+
get videoStreams() {
|
|
151
|
+
return this.data.streams.filter((stream) => stream.codec_type === "video");
|
|
152
|
+
}
|
|
153
|
+
get streams() {
|
|
154
|
+
return this.data.streams;
|
|
155
|
+
}
|
|
156
|
+
get format() {
|
|
157
|
+
return this.data.format;
|
|
158
|
+
}
|
|
159
|
+
get mustReencodeAudio() {
|
|
160
|
+
return this.audioStreams.some((stream) => stream.codec_name !== "aac");
|
|
161
|
+
}
|
|
162
|
+
get mustReencodeVideo() {
|
|
163
|
+
return false;
|
|
164
|
+
}
|
|
165
|
+
get mustRemux() {
|
|
166
|
+
return this.format.format_name !== "mp4" || this.data.streams.some((stream) => stream.codec_type !== "audio" && stream.codec_type !== "video");
|
|
167
|
+
}
|
|
168
|
+
get hasNonAudioOrVideoStreams() {
|
|
169
|
+
return this.data.streams.some((stream) => stream.codec_type !== "audio" && stream.codec_type !== "video");
|
|
170
|
+
}
|
|
171
|
+
get hasAudio() {
|
|
172
|
+
return this.audioStreams.length > 0;
|
|
173
|
+
}
|
|
174
|
+
get hasVideo() {
|
|
175
|
+
return this.videoStreams.length > 0;
|
|
176
|
+
}
|
|
177
|
+
get isAudioOnly() {
|
|
178
|
+
return this.audioStreams.length > 0 && this.videoStreams.length === 0;
|
|
179
|
+
}
|
|
180
|
+
get isMp3() {
|
|
181
|
+
return this.audioStreams.some((stream) => stream.codec_name === "mp3");
|
|
182
|
+
}
|
|
183
|
+
get isVideoOnly() {
|
|
184
|
+
return this.audioStreams.length === 0 && this.videoStreams.length > 0;
|
|
185
|
+
}
|
|
186
|
+
get mustProcess() {
|
|
187
|
+
return this.mustReencodeAudio || this.mustReencodeVideo || this.mustRemux;
|
|
188
|
+
}
|
|
189
|
+
get ffmpegAudioInputOptions() {
|
|
190
|
+
if (!this.hasAudio) return [];
|
|
191
|
+
if (this.isMp3) return ["-c:a", "mp3"];
|
|
192
|
+
return [];
|
|
193
|
+
}
|
|
194
|
+
get ffmpegVideoInputOptions() {
|
|
195
|
+
return [];
|
|
196
|
+
}
|
|
197
|
+
get ffmpegAudioOutputOptions() {
|
|
198
|
+
if (!this.hasAudio) return [];
|
|
199
|
+
if (this.mustReencodeAudio) return [
|
|
200
|
+
"-c:a",
|
|
201
|
+
"aac",
|
|
202
|
+
"-b:a",
|
|
203
|
+
"192k",
|
|
204
|
+
"-ar",
|
|
205
|
+
"48000"
|
|
206
|
+
];
|
|
207
|
+
return ["-c:a", "copy"];
|
|
208
|
+
}
|
|
209
|
+
get ffmpegVideoOutputOptions() {
|
|
210
|
+
if (!this.hasVideo) return [];
|
|
211
|
+
if (this.mustReencodeVideo) return [
|
|
212
|
+
"-c:v",
|
|
213
|
+
"h264",
|
|
214
|
+
"-bsf:v",
|
|
215
|
+
"filter_units=remove_types=6",
|
|
216
|
+
"-pix_fmt",
|
|
217
|
+
"yuv420p"
|
|
218
|
+
];
|
|
219
|
+
return [
|
|
220
|
+
"-c:v",
|
|
221
|
+
"copy",
|
|
222
|
+
"-bsf:v",
|
|
223
|
+
"filter_units=remove_types=6"
|
|
224
|
+
];
|
|
225
|
+
}
|
|
226
|
+
createConformingReadstream() {
|
|
227
|
+
if (this.absolutePath === "pipe:0") throw new Error("Cannot create conforming readstream from pipe");
|
|
228
|
+
if (!this.mustProcess) return createReadStream(this.absolutePath);
|
|
229
|
+
const fragmenterArgs = this.isAudioOnly ? [
|
|
230
|
+
"-movflags",
|
|
231
|
+
"frag_keyframe",
|
|
232
|
+
"-frag_duration",
|
|
233
|
+
"4000000"
|
|
234
|
+
] : ["-movflags", "frag_keyframe"];
|
|
235
|
+
const ffmpegConformanceArgs = [
|
|
236
|
+
...this.ffmpegAudioInputOptions,
|
|
237
|
+
...this.ffmpegVideoInputOptions,
|
|
238
|
+
"-i",
|
|
239
|
+
this.absolutePath,
|
|
240
|
+
...this.ffmpegAudioOutputOptions,
|
|
241
|
+
...this.ffmpegVideoOutputOptions,
|
|
242
|
+
"-f",
|
|
243
|
+
"mp4",
|
|
244
|
+
...fragmenterArgs,
|
|
245
|
+
"pipe:1"
|
|
246
|
+
];
|
|
247
|
+
log("Running ffmpeg", ffmpegConformanceArgs);
|
|
248
|
+
const ffmpegConformer = spawn("ffmpeg", ffmpegConformanceArgs, { stdio: [
|
|
249
|
+
"ignore",
|
|
250
|
+
"pipe",
|
|
251
|
+
"pipe"
|
|
252
|
+
] });
|
|
253
|
+
ffmpegConformer.stderr.on("data", (data) => {
|
|
254
|
+
log("CONFORMER: ", data.toString());
|
|
255
|
+
});
|
|
256
|
+
const ffmpegFragmentArgs = [
|
|
257
|
+
"-i",
|
|
258
|
+
"-",
|
|
259
|
+
"-c",
|
|
260
|
+
"copy",
|
|
261
|
+
"-f",
|
|
262
|
+
"mp4",
|
|
263
|
+
...fragmenterArgs,
|
|
264
|
+
"pipe:1"
|
|
265
|
+
];
|
|
266
|
+
log("Running ffmpeg", ffmpegFragmentArgs);
|
|
267
|
+
const ffmpegFragmenter = spawn("ffmpeg", ffmpegFragmentArgs, { stdio: [
|
|
268
|
+
"pipe",
|
|
269
|
+
"pipe",
|
|
270
|
+
"pipe"
|
|
271
|
+
] });
|
|
272
|
+
ffmpegConformer.stdout.pipe(ffmpegFragmenter.stdin);
|
|
273
|
+
ffmpegFragmenter.stderr.on("data", (data) => {
|
|
274
|
+
log("FRAGMENTER: ", data.toString());
|
|
275
|
+
});
|
|
276
|
+
ffmpegConformer.on("error", (error) => {
|
|
277
|
+
ffmpegFragmenter.stdout.emit("error", error);
|
|
278
|
+
});
|
|
279
|
+
ffmpegFragmenter.on("error", (error) => {
|
|
280
|
+
ffmpegFragmenter.stdout.emit("error", error);
|
|
281
|
+
});
|
|
282
|
+
return ffmpegFragmenter.stdout;
|
|
283
|
+
}
|
|
321
284
|
};
|
|
285
|
+
export { Probe };
|