@ffmpeg-oneclick/core 0.1.2
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/README.md +208 -0
- package/dist/index.cjs +9996 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +725 -0
- package/dist/index.d.ts +725 -0
- package/dist/index.js +9962 -0
- package/dist/index.js.map +1 -0
- package/package.json +82 -0
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,725 @@
|
|
|
1
|
+
import EventEmitter from 'events';
|
|
2
|
+
import { Readable, Writable, Transform } from 'stream';
|
|
3
|
+
|
|
4
|
+
interface ProgressInfo {
|
|
5
|
+
percent: number;
|
|
6
|
+
eta: number;
|
|
7
|
+
frames: number;
|
|
8
|
+
time: number;
|
|
9
|
+
bitrate: number;
|
|
10
|
+
fps: number;
|
|
11
|
+
size: number;
|
|
12
|
+
}
|
|
13
|
+
interface FFmpegResult {
|
|
14
|
+
output: string;
|
|
15
|
+
duration: number;
|
|
16
|
+
size: number;
|
|
17
|
+
command: string;
|
|
18
|
+
logs: string;
|
|
19
|
+
}
|
|
20
|
+
interface VideoMetadata {
|
|
21
|
+
duration: number;
|
|
22
|
+
width: number;
|
|
23
|
+
height: number;
|
|
24
|
+
fps: number;
|
|
25
|
+
videoCodec: string;
|
|
26
|
+
audioCodec: string;
|
|
27
|
+
videoBitrate: number;
|
|
28
|
+
audioBitrate: number;
|
|
29
|
+
audioSampleRate: number;
|
|
30
|
+
audioChannels: number;
|
|
31
|
+
}
|
|
32
|
+
type HardwareAcceleration = 'auto' | 'none' | 'nvenc' | 'qsv' | 'vce' | 'videotoolbox';
|
|
33
|
+
type InputType = string | Buffer | NodeJS.ReadableStream;
|
|
34
|
+
type OutputType = string | NodeJS.WritableStream;
|
|
35
|
+
interface FFmpegEventListeners {
|
|
36
|
+
start?: (command: string) => void;
|
|
37
|
+
progress?: (progress: ProgressInfo) => void;
|
|
38
|
+
end?: (result: FFmpegResult) => void;
|
|
39
|
+
error?: (error: Error) => void;
|
|
40
|
+
stdout?: (data: string) => void;
|
|
41
|
+
stderr?: (data: string) => void;
|
|
42
|
+
}
|
|
43
|
+
interface FFmpegOptions {
|
|
44
|
+
ffmpegPath?: string;
|
|
45
|
+
ffprobePath?: string;
|
|
46
|
+
hardwareAcceleration?: HardwareAcceleration;
|
|
47
|
+
threads?: number;
|
|
48
|
+
timeout?: number;
|
|
49
|
+
logLevel?: 'quiet' | 'error' | 'warning' | 'info' | 'verbose' | 'debug';
|
|
50
|
+
cache?: CacheOptions$1;
|
|
51
|
+
}
|
|
52
|
+
interface CacheOptions$1 {
|
|
53
|
+
enabled?: boolean;
|
|
54
|
+
dir?: string;
|
|
55
|
+
ttl?: number;
|
|
56
|
+
maxSize?: number;
|
|
57
|
+
}
|
|
58
|
+
interface VideoFilterOptions {
|
|
59
|
+
scale?: string | {
|
|
60
|
+
width: number;
|
|
61
|
+
height: number;
|
|
62
|
+
};
|
|
63
|
+
crop?: {
|
|
64
|
+
x: number;
|
|
65
|
+
y: number;
|
|
66
|
+
width: number;
|
|
67
|
+
height: number;
|
|
68
|
+
};
|
|
69
|
+
rotate?: number;
|
|
70
|
+
hflip?: boolean;
|
|
71
|
+
vflip?: boolean;
|
|
72
|
+
blur?: number;
|
|
73
|
+
sharpen?: number;
|
|
74
|
+
brightness?: number;
|
|
75
|
+
contrast?: number;
|
|
76
|
+
saturation?: number;
|
|
77
|
+
}
|
|
78
|
+
interface AudioFilterOptions {
|
|
79
|
+
volume?: number;
|
|
80
|
+
denoise?: boolean;
|
|
81
|
+
normalize?: boolean;
|
|
82
|
+
}
|
|
83
|
+
declare enum ErrorCode {
|
|
84
|
+
INPUT_NOT_FOUND = 1001,
|
|
85
|
+
INPUT_INVALID_FORMAT = 1002,
|
|
86
|
+
INPUT_CORRUPTED = 1003,
|
|
87
|
+
INPUT_UNSUPPORTED = 1004,
|
|
88
|
+
OUTPUT_PATH_INVALID = 2001,
|
|
89
|
+
OUTPUT_WRITE_FAILED = 2002,
|
|
90
|
+
OUTPUT_ALREADY_EXISTS = 2003,
|
|
91
|
+
FFMPEG_NOT_FOUND = 3001,
|
|
92
|
+
FFMPEG_EXECUTION_FAILED = 3002,
|
|
93
|
+
FFMPEG_TIMEOUT = 3003,
|
|
94
|
+
FFMPEG_INVALID_COMMAND = 3004,
|
|
95
|
+
INVALID_PARAMETER = 4001,
|
|
96
|
+
INCOMPATIBLE_OPTIONS = 4002,
|
|
97
|
+
MISSING_REQUIRED_OPTION = 4003,
|
|
98
|
+
OUT_OF_MEMORY = 5001,
|
|
99
|
+
INSUFFICIENT_DISK_SPACE = 5002,
|
|
100
|
+
PERMISSION_DENIED = 5003
|
|
101
|
+
}
|
|
102
|
+
interface FFmpegError extends Error {
|
|
103
|
+
code: ErrorCode;
|
|
104
|
+
details?: Record<string, unknown>;
|
|
105
|
+
suggestion?: string;
|
|
106
|
+
retryable: boolean;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
interface CacheOptions {
|
|
110
|
+
enabled: boolean;
|
|
111
|
+
dir?: string;
|
|
112
|
+
ttl?: number;
|
|
113
|
+
maxSize?: number;
|
|
114
|
+
}
|
|
115
|
+
declare class CacheManager {
|
|
116
|
+
private options;
|
|
117
|
+
private cacheDir;
|
|
118
|
+
private manifestPath;
|
|
119
|
+
private manifest;
|
|
120
|
+
private hits;
|
|
121
|
+
private misses;
|
|
122
|
+
private manifestDirty;
|
|
123
|
+
private saveTimer;
|
|
124
|
+
private lockOptions;
|
|
125
|
+
constructor(options?: CacheOptions);
|
|
126
|
+
private initCacheDir;
|
|
127
|
+
private loadManifest;
|
|
128
|
+
private markDirty;
|
|
129
|
+
private saveManifest;
|
|
130
|
+
generateParamsHash(inputPath: string, options: Record<string, any>): string;
|
|
131
|
+
getCacheKey(inputPath: string, options: Record<string, any>): string;
|
|
132
|
+
has(key: string): boolean;
|
|
133
|
+
get(key: string): string | null;
|
|
134
|
+
set(key: string, inputPath: string, outputPath: string, options: Record<string, any>): void;
|
|
135
|
+
delete(key: string): void;
|
|
136
|
+
clear(): void;
|
|
137
|
+
getStats(): {
|
|
138
|
+
count: number;
|
|
139
|
+
totalSize: number;
|
|
140
|
+
oldestEntry: number;
|
|
141
|
+
newestEntry: number;
|
|
142
|
+
hits: number;
|
|
143
|
+
misses: number;
|
|
144
|
+
hitRate: number;
|
|
145
|
+
};
|
|
146
|
+
cleanupExpired(): void;
|
|
147
|
+
private evictIfNeeded;
|
|
148
|
+
getHitRate(): number;
|
|
149
|
+
flush(): Promise<void>;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
declare class ChainableFFmpeg {
|
|
153
|
+
private wrapper;
|
|
154
|
+
private commandBuilder;
|
|
155
|
+
private inputValue;
|
|
156
|
+
private outputValue;
|
|
157
|
+
private listeners;
|
|
158
|
+
private cacheManager?;
|
|
159
|
+
private cacheEnabled;
|
|
160
|
+
constructor(options?: FFmpegOptions);
|
|
161
|
+
input(input: InputType): this;
|
|
162
|
+
output(output: OutputType): this;
|
|
163
|
+
videoCodec(codec: string): this;
|
|
164
|
+
audioCodec(codec: string): this;
|
|
165
|
+
videoBitrate(bitrate: string | number): this;
|
|
166
|
+
audioBitrate(bitrate: string | number): this;
|
|
167
|
+
audioFrequency(frequency: number): this;
|
|
168
|
+
audioChannels(channels: number): this;
|
|
169
|
+
volume(volume: number): this;
|
|
170
|
+
fps(fps: number): this;
|
|
171
|
+
size(size: string | {
|
|
172
|
+
width: number;
|
|
173
|
+
height: number;
|
|
174
|
+
}): this;
|
|
175
|
+
hardwareAccelerate(type: HardwareAcceleration): this;
|
|
176
|
+
threads(count: number): this;
|
|
177
|
+
duration(seconds: number): this;
|
|
178
|
+
startTime(seconds: number): this;
|
|
179
|
+
trim(start: number, end: number): this;
|
|
180
|
+
concat(inputs: string[]): this;
|
|
181
|
+
concatWithoutAudio(inputs: string[]): this;
|
|
182
|
+
rotate(angle: number): this;
|
|
183
|
+
flip(): this;
|
|
184
|
+
flop(): this;
|
|
185
|
+
crop(x: number, y: number, width: number, height: number): this;
|
|
186
|
+
screenshot(timestamp: number, output: string): this;
|
|
187
|
+
screenshots(options: {
|
|
188
|
+
timestamps: number[];
|
|
189
|
+
filenameTemplate?: string;
|
|
190
|
+
outputDir?: string;
|
|
191
|
+
format?: 'jpg' | 'png' | 'bmp';
|
|
192
|
+
quality?: number;
|
|
193
|
+
}): this;
|
|
194
|
+
thumbnails(options: {
|
|
195
|
+
count: number;
|
|
196
|
+
filenameTemplate?: string;
|
|
197
|
+
outputDir?: string;
|
|
198
|
+
format?: 'jpg' | 'png';
|
|
199
|
+
width?: number;
|
|
200
|
+
}): this;
|
|
201
|
+
format(format: string): this;
|
|
202
|
+
hls(options?: {
|
|
203
|
+
segmentDuration?: number;
|
|
204
|
+
playlistName?: string;
|
|
205
|
+
segmentName?: string;
|
|
206
|
+
listSize?: number;
|
|
207
|
+
fmp4?: boolean;
|
|
208
|
+
}): this;
|
|
209
|
+
dash(options?: {
|
|
210
|
+
segmentDuration?: number;
|
|
211
|
+
manifestName?: string;
|
|
212
|
+
segmentName?: string;
|
|
213
|
+
live?: boolean;
|
|
214
|
+
}): this;
|
|
215
|
+
toHLS(output: string, options?: {
|
|
216
|
+
segmentDuration?: number;
|
|
217
|
+
playlistName?: string;
|
|
218
|
+
segmentName?: string;
|
|
219
|
+
listSize?: number;
|
|
220
|
+
fmp4?: boolean;
|
|
221
|
+
}): Promise<FFmpegResult>;
|
|
222
|
+
toDASH(output: string, options?: {
|
|
223
|
+
segmentDuration?: number;
|
|
224
|
+
manifestName?: string;
|
|
225
|
+
segmentName?: string;
|
|
226
|
+
live?: boolean;
|
|
227
|
+
}): Promise<FFmpegResult>;
|
|
228
|
+
videoFilters(options: VideoFilterOptions): this;
|
|
229
|
+
audioFilters(options: AudioFilterOptions): this;
|
|
230
|
+
mix(audioInputs: Array<{
|
|
231
|
+
input: string | number;
|
|
232
|
+
volume?: number;
|
|
233
|
+
startTime?: number;
|
|
234
|
+
duration?: number;
|
|
235
|
+
}>, options?: {
|
|
236
|
+
codec?: string;
|
|
237
|
+
bitrate?: string | number;
|
|
238
|
+
}): this;
|
|
239
|
+
watermark(watermarkPath: string, options?: {
|
|
240
|
+
position?: 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight' | 'center' | {
|
|
241
|
+
x: number;
|
|
242
|
+
y: number;
|
|
243
|
+
};
|
|
244
|
+
opacity?: number;
|
|
245
|
+
scale?: number;
|
|
246
|
+
}): this;
|
|
247
|
+
textWatermark(text: string, options?: {
|
|
248
|
+
fontFile?: string;
|
|
249
|
+
fontSize?: number;
|
|
250
|
+
fontColor?: string;
|
|
251
|
+
position?: 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight' | 'center' | {
|
|
252
|
+
x: number;
|
|
253
|
+
y: number;
|
|
254
|
+
};
|
|
255
|
+
opacity?: number;
|
|
256
|
+
borderColor?: string;
|
|
257
|
+
borderWidth?: number;
|
|
258
|
+
shadowColor?: string;
|
|
259
|
+
shadowOffset?: number;
|
|
260
|
+
}): this;
|
|
261
|
+
metadata(key: string, value: string): this;
|
|
262
|
+
noMetadata(): this;
|
|
263
|
+
autoRotate(): Promise<this>;
|
|
264
|
+
outputOption(option: string, value?: string): this;
|
|
265
|
+
inputOption(option: string, value?: string): this;
|
|
266
|
+
cache(options?: Partial<CacheOptions>): this;
|
|
267
|
+
on<K extends keyof FFmpegEventListeners>(event: K, listener: NonNullable<FFmpegEventListeners[K]>): this;
|
|
268
|
+
run(): Promise<FFmpegResult>;
|
|
269
|
+
getCommand(): string;
|
|
270
|
+
kill(): void;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
declare function createFFmpegError(code: ErrorCode, message: string, options?: {
|
|
274
|
+
details?: Record<string, unknown>;
|
|
275
|
+
suggestion?: string;
|
|
276
|
+
retryable?: boolean;
|
|
277
|
+
cause?: Error;
|
|
278
|
+
}): FFmpegError;
|
|
279
|
+
declare function getErrorSuggestion(code: ErrorCode): string;
|
|
280
|
+
|
|
281
|
+
declare class CommandBuilder {
|
|
282
|
+
private inputArgs;
|
|
283
|
+
private outputArgs;
|
|
284
|
+
private inputFiles;
|
|
285
|
+
private outputFiles;
|
|
286
|
+
private complexFilters;
|
|
287
|
+
private mappings;
|
|
288
|
+
private metadata;
|
|
289
|
+
addInput(input: string): this;
|
|
290
|
+
addInputOption(option: string, value?: string): this;
|
|
291
|
+
setOutput(output: string): this;
|
|
292
|
+
addOutputOption(option: string, value?: string): this;
|
|
293
|
+
setVideoCodec(codec: string): this;
|
|
294
|
+
setAudioCodec(codec: string): this;
|
|
295
|
+
setVideoBitrate(bitrate: string | number): this;
|
|
296
|
+
setAudioBitrate(bitrate: string | number): this;
|
|
297
|
+
setAudioFrequency(frequency: number): this;
|
|
298
|
+
setAudioChannels(channels: number): this;
|
|
299
|
+
setVolume(volume: number): this;
|
|
300
|
+
setFPS(fps: number): this;
|
|
301
|
+
setSize(size: string | {
|
|
302
|
+
width: number;
|
|
303
|
+
height: number;
|
|
304
|
+
}): this;
|
|
305
|
+
setHardwareAcceleration(type: HardwareAcceleration): this;
|
|
306
|
+
setThreads(threads: number): this;
|
|
307
|
+
setDuration(seconds: number): this;
|
|
308
|
+
setStartTime(seconds: number): this;
|
|
309
|
+
concat(inputs: string[]): this;
|
|
310
|
+
concatWithoutAudio(inputs: string[]): this;
|
|
311
|
+
rotate(angle: number): this;
|
|
312
|
+
flip(): this;
|
|
313
|
+
flop(): this;
|
|
314
|
+
addVideoFilter(filter: string): this;
|
|
315
|
+
addAudioFilter(filter: string): this;
|
|
316
|
+
addWatermark(watermarkPath: string, options?: {
|
|
317
|
+
position?: 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight' | 'center' | {
|
|
318
|
+
x: number;
|
|
319
|
+
y: number;
|
|
320
|
+
};
|
|
321
|
+
opacity?: number;
|
|
322
|
+
scale?: number;
|
|
323
|
+
}): this;
|
|
324
|
+
private calculateTextPosition;
|
|
325
|
+
addTextWatermark(text: string, options?: {
|
|
326
|
+
fontFile?: string;
|
|
327
|
+
fontSize?: number;
|
|
328
|
+
fontColor?: string;
|
|
329
|
+
position?: 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight' | 'center' | {
|
|
330
|
+
x: number;
|
|
331
|
+
y: number;
|
|
332
|
+
};
|
|
333
|
+
opacity?: number;
|
|
334
|
+
borderColor?: string;
|
|
335
|
+
borderWidth?: number;
|
|
336
|
+
shadowColor?: string;
|
|
337
|
+
shadowOffset?: number;
|
|
338
|
+
}): this;
|
|
339
|
+
private buildScaleFilter;
|
|
340
|
+
private buildCropFilter;
|
|
341
|
+
private buildColorFilters;
|
|
342
|
+
private buildGeometryFilters;
|
|
343
|
+
private buildBlurSharpenFilters;
|
|
344
|
+
applyVideoFilters(options: VideoFilterOptions): this;
|
|
345
|
+
applyAudioFilters(options: AudioFilterOptions): this;
|
|
346
|
+
addMetadata(key: string, value: string): this;
|
|
347
|
+
removeAllMetadata(): this;
|
|
348
|
+
setHLS(options?: {
|
|
349
|
+
segmentDuration?: number;
|
|
350
|
+
playlistName?: string;
|
|
351
|
+
segmentName?: string;
|
|
352
|
+
listSize?: number;
|
|
353
|
+
fmp4?: boolean;
|
|
354
|
+
}): this;
|
|
355
|
+
setDASH(options?: {
|
|
356
|
+
segmentDuration?: number;
|
|
357
|
+
manifestName?: string;
|
|
358
|
+
segmentName?: string;
|
|
359
|
+
live?: boolean;
|
|
360
|
+
}): this;
|
|
361
|
+
setFormat(format: string): this;
|
|
362
|
+
overwrite(): this;
|
|
363
|
+
noOverwrite(): this;
|
|
364
|
+
build(): string[];
|
|
365
|
+
buildString(): string;
|
|
366
|
+
getOptions(): Record<string, any>;
|
|
367
|
+
reset(): void;
|
|
368
|
+
mixAudio(audioInputs: Array<{
|
|
369
|
+
input: string | number;
|
|
370
|
+
volume?: number;
|
|
371
|
+
startTime?: number;
|
|
372
|
+
duration?: number;
|
|
373
|
+
}>, options?: {
|
|
374
|
+
codec?: string;
|
|
375
|
+
bitrate?: string | number;
|
|
376
|
+
}): this;
|
|
377
|
+
screenshot(timestamp: number, output: string): this;
|
|
378
|
+
screenshots(options: {
|
|
379
|
+
timestamps: number[];
|
|
380
|
+
filenameTemplate?: string;
|
|
381
|
+
outputDir?: string;
|
|
382
|
+
format?: 'jpg' | 'png' | 'bmp';
|
|
383
|
+
quality?: number;
|
|
384
|
+
}): this;
|
|
385
|
+
thumbnails(options: {
|
|
386
|
+
count: number;
|
|
387
|
+
filenameTemplate?: string;
|
|
388
|
+
outputDir?: string;
|
|
389
|
+
format?: 'jpg' | 'png';
|
|
390
|
+
width?: number;
|
|
391
|
+
}): this;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
declare class FFmpegWrapper extends EventEmitter {
|
|
395
|
+
private options;
|
|
396
|
+
private commandBuilder;
|
|
397
|
+
private progressParser;
|
|
398
|
+
private process;
|
|
399
|
+
private killed;
|
|
400
|
+
private startTime;
|
|
401
|
+
private inputDuration;
|
|
402
|
+
constructor(options?: FFmpegOptions);
|
|
403
|
+
private getFFmpegPath;
|
|
404
|
+
private getFFprobePath;
|
|
405
|
+
private getInputDuration;
|
|
406
|
+
private validateInputOutput;
|
|
407
|
+
private setupInputOutput;
|
|
408
|
+
private setupOptions;
|
|
409
|
+
private handleStderr;
|
|
410
|
+
private handleInputStreams;
|
|
411
|
+
private handleOutputStreams;
|
|
412
|
+
private buildResult;
|
|
413
|
+
private handleExecutionError;
|
|
414
|
+
run(input: InputType, output: OutputType): Promise<FFmpegResult>;
|
|
415
|
+
kill(): void;
|
|
416
|
+
cleanup(): void;
|
|
417
|
+
destroy(): void;
|
|
418
|
+
getMetadata(input: string): Promise<VideoMetadata>;
|
|
419
|
+
getCommandBuilder(): CommandBuilder;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
declare class ProgressParser {
|
|
423
|
+
private lastProgress;
|
|
424
|
+
private parseFrames;
|
|
425
|
+
private parseFps;
|
|
426
|
+
private parseTime;
|
|
427
|
+
private parseBitrate;
|
|
428
|
+
private parseSize;
|
|
429
|
+
parseLine(line: string): Partial<ProgressInfo> | null;
|
|
430
|
+
calculatePercent(currentTime: number, totalTime: number): number;
|
|
431
|
+
calculateETA(currentTime: number, totalTime: number, speed: number): number;
|
|
432
|
+
getLastProgress(): Partial<ProgressInfo>;
|
|
433
|
+
reset(): void;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
type HardwareAccelType = 'nvenc' | 'qsv' | 'vce' | 'videotoolbox' | 'none';
|
|
437
|
+
interface HardwareAccelInfo {
|
|
438
|
+
type: HardwareAccelType;
|
|
439
|
+
available: boolean;
|
|
440
|
+
encoder?: string;
|
|
441
|
+
decoder?: string;
|
|
442
|
+
info?: string;
|
|
443
|
+
}
|
|
444
|
+
declare class HardwareAccelDetector {
|
|
445
|
+
private ffmpegPath;
|
|
446
|
+
private cache;
|
|
447
|
+
constructor(ffmpegPath?: string);
|
|
448
|
+
detectAll(): Promise<HardwareAccelInfo[]>;
|
|
449
|
+
detect(type: HardwareAccelType): Promise<HardwareAccelInfo>;
|
|
450
|
+
private detectHardwareAccel;
|
|
451
|
+
private detectNVENC;
|
|
452
|
+
private detectQSV;
|
|
453
|
+
private detectVCE;
|
|
454
|
+
private detectVideoToolbox;
|
|
455
|
+
getBest(): Promise<HardwareAccelInfo>;
|
|
456
|
+
clearCache(): void;
|
|
457
|
+
}
|
|
458
|
+
declare function getHardwareAccelDetector(ffmpegPath?: string): HardwareAccelDetector;
|
|
459
|
+
declare function detectBestHardwareAccel(ffmpegPath?: string): Promise<HardwareAccelInfo>;
|
|
460
|
+
|
|
461
|
+
type TaskPriority = 'high' | 'normal' | 'low';
|
|
462
|
+
type TaskStatus = 'pending' | 'running' | 'paused' | 'completed' | 'failed' | 'cancelled';
|
|
463
|
+
interface Task<T = any> {
|
|
464
|
+
id: string;
|
|
465
|
+
priority: TaskPriority;
|
|
466
|
+
status: TaskStatus;
|
|
467
|
+
run: (signal?: AbortSignal) => Promise<T>;
|
|
468
|
+
result?: T;
|
|
469
|
+
error?: Error;
|
|
470
|
+
createdAt: number;
|
|
471
|
+
startedAt?: number;
|
|
472
|
+
completedAt?: number;
|
|
473
|
+
progress?: number;
|
|
474
|
+
abortController?: AbortController;
|
|
475
|
+
}
|
|
476
|
+
interface QueueOptions {
|
|
477
|
+
maxConcurrent?: number;
|
|
478
|
+
autoStart?: boolean;
|
|
479
|
+
timeout?: number;
|
|
480
|
+
}
|
|
481
|
+
declare class ConcurrentQueue extends EventEmitter {
|
|
482
|
+
private maxConcurrent;
|
|
483
|
+
private autoStart;
|
|
484
|
+
private timeout;
|
|
485
|
+
private queue;
|
|
486
|
+
private running;
|
|
487
|
+
private completedTasks;
|
|
488
|
+
private maxHistorySize;
|
|
489
|
+
private paused;
|
|
490
|
+
private taskIdCounter;
|
|
491
|
+
constructor(options?: QueueOptions);
|
|
492
|
+
add<T>(run: (signal?: AbortSignal) => Promise<T>, priority?: TaskPriority): string;
|
|
493
|
+
private insertTask;
|
|
494
|
+
private process;
|
|
495
|
+
private addToHistory;
|
|
496
|
+
private generateTaskId;
|
|
497
|
+
pause(): void;
|
|
498
|
+
resume(): void;
|
|
499
|
+
cancel(taskId: string): boolean;
|
|
500
|
+
clear(): void;
|
|
501
|
+
getTask(taskId: string): Task | undefined;
|
|
502
|
+
getStats(): {
|
|
503
|
+
pending: number;
|
|
504
|
+
running: number;
|
|
505
|
+
completed: number;
|
|
506
|
+
failed: number;
|
|
507
|
+
total: number;
|
|
508
|
+
};
|
|
509
|
+
waitAll(): Promise<void>;
|
|
510
|
+
setMaxConcurrent(max: number): void;
|
|
511
|
+
isPaused(): boolean;
|
|
512
|
+
isEmpty(): boolean;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
interface PresetConfig {
|
|
516
|
+
name: string;
|
|
517
|
+
description?: string;
|
|
518
|
+
videoCodec?: string;
|
|
519
|
+
audioCodec?: string;
|
|
520
|
+
videoBitrate?: string | number;
|
|
521
|
+
audioBitrate?: string | number;
|
|
522
|
+
fps?: number;
|
|
523
|
+
size?: string | {
|
|
524
|
+
width: number;
|
|
525
|
+
height: number;
|
|
526
|
+
};
|
|
527
|
+
format?: string;
|
|
528
|
+
options?: Record<string, any>;
|
|
529
|
+
processor?: (instance: ChainableFFmpeg, options?: any) => ChainableFFmpeg;
|
|
530
|
+
}
|
|
531
|
+
declare class PresetManager {
|
|
532
|
+
private presets;
|
|
533
|
+
constructor();
|
|
534
|
+
private registerCompressionPresets;
|
|
535
|
+
private registerPlatformPresets;
|
|
536
|
+
private registerFormatPresets;
|
|
537
|
+
private registerStreamingPresets;
|
|
538
|
+
private registerScreenshotPresets;
|
|
539
|
+
private registerBuiltInPresets;
|
|
540
|
+
register(name: string, config: PresetConfig): void;
|
|
541
|
+
private isValidBitrate;
|
|
542
|
+
get(name: string): PresetConfig | undefined;
|
|
543
|
+
list(): Array<{
|
|
544
|
+
name: string;
|
|
545
|
+
config: PresetConfig;
|
|
546
|
+
}>;
|
|
547
|
+
private applyConfig;
|
|
548
|
+
private validateAndGetPreset;
|
|
549
|
+
apply(input: string, output: string, presetName: string, options?: any): ChainableFFmpeg;
|
|
550
|
+
applyAsync(input: string, output: string, presetName: string, options?: any): Promise<ChainableFFmpeg>;
|
|
551
|
+
compressVideo(input: string, output: string, quality?: 'high' | 'medium' | 'low'): Promise<any>;
|
|
552
|
+
toGif(input: string, output: string, options?: {
|
|
553
|
+
startTime?: number;
|
|
554
|
+
duration?: number;
|
|
555
|
+
fps?: number;
|
|
556
|
+
size?: string;
|
|
557
|
+
}): Promise<any>;
|
|
558
|
+
extractAudio(input: string, output: string, bitrate?: string): Promise<any>;
|
|
559
|
+
webOptimized(input: string, output: string): Promise<any>;
|
|
560
|
+
mobileFriendly(input: string, output: string): Promise<any>;
|
|
561
|
+
createThumbnail(input: string, output: string, time?: number): Promise<any>;
|
|
562
|
+
}
|
|
563
|
+
declare const presets: PresetManager;
|
|
564
|
+
|
|
565
|
+
type StreamType = 'readable' | 'writable' | 'duplex' | 'transform';
|
|
566
|
+
interface StreamHandlerOptions {
|
|
567
|
+
highWaterMark?: number;
|
|
568
|
+
autoEnd?: boolean;
|
|
569
|
+
autoDestroy?: boolean;
|
|
570
|
+
encoding?: BufferEncoding;
|
|
571
|
+
timeout?: number;
|
|
572
|
+
}
|
|
573
|
+
declare class StreamHandler {
|
|
574
|
+
private options;
|
|
575
|
+
private inputStreams;
|
|
576
|
+
private outputStreams;
|
|
577
|
+
private eventListeners;
|
|
578
|
+
constructor(options?: StreamHandlerOptions);
|
|
579
|
+
detectInputType(input: any): 'file' | 'buffer' | 'stream' | 'url' | 'unknown';
|
|
580
|
+
detectOutputType(output: any): 'file' | 'stream' | 'unknown';
|
|
581
|
+
createInputStream(input: any): Promise<Readable>;
|
|
582
|
+
createOutputStream(output: any): Promise<Writable>;
|
|
583
|
+
pipeStreams(source: Readable, destination: Writable, options?: {
|
|
584
|
+
end?: boolean;
|
|
585
|
+
}): Promise<void>;
|
|
586
|
+
private trackListener;
|
|
587
|
+
cleanup(): void;
|
|
588
|
+
createTransformStream(transformer: (chunk: Buffer, encoding: BufferEncoding) => Buffer | string | null): Transform;
|
|
589
|
+
readStreamToBuffer(stream: Readable): Promise<Buffer>;
|
|
590
|
+
writeBufferToStream(buffer: Buffer, stream: Writable): Promise<void>;
|
|
591
|
+
validateStream(stream: any, type: 'readable' | 'writable'): boolean;
|
|
592
|
+
waitForStreamEnd(stream: Readable | Writable): Promise<void>;
|
|
593
|
+
destroyStream(stream: Readable | Writable, error?: Error): void;
|
|
594
|
+
pauseStream(stream: Readable): void;
|
|
595
|
+
resumeStream(stream: Readable): void;
|
|
596
|
+
getStreamStats(stream: Readable | Writable): {
|
|
597
|
+
bytesRead?: number;
|
|
598
|
+
bytesWritten?: number;
|
|
599
|
+
isPaused?: boolean;
|
|
600
|
+
isEnded?: boolean;
|
|
601
|
+
};
|
|
602
|
+
}
|
|
603
|
+
declare function getStreamHandler(options?: StreamHandlerOptions): StreamHandler;
|
|
604
|
+
|
|
605
|
+
interface MetadataInfo {
|
|
606
|
+
format: {
|
|
607
|
+
filename: string;
|
|
608
|
+
format_name: string;
|
|
609
|
+
format_long_name: string;
|
|
610
|
+
duration: number;
|
|
611
|
+
bit_rate: number;
|
|
612
|
+
size: number;
|
|
613
|
+
tags?: Record<string, string>;
|
|
614
|
+
};
|
|
615
|
+
streams: StreamInfo[];
|
|
616
|
+
chapters?: ChapterInfo[];
|
|
617
|
+
}
|
|
618
|
+
interface StreamInfo {
|
|
619
|
+
index: number;
|
|
620
|
+
codec_name: string;
|
|
621
|
+
codec_long_name?: string;
|
|
622
|
+
codec_type: 'video' | 'audio' | 'subtitle' | 'data' | 'attachment';
|
|
623
|
+
stream_index?: number;
|
|
624
|
+
width?: number;
|
|
625
|
+
height?: number;
|
|
626
|
+
fps?: number;
|
|
627
|
+
aspect_ratio?: string;
|
|
628
|
+
pix_fmt?: string;
|
|
629
|
+
level?: number;
|
|
630
|
+
profile?: string;
|
|
631
|
+
bit_rate?: number;
|
|
632
|
+
sample_rate?: number;
|
|
633
|
+
channels?: number;
|
|
634
|
+
channel_layout?: string;
|
|
635
|
+
bits_per_sample?: number;
|
|
636
|
+
rotation?: number;
|
|
637
|
+
tags?: Record<string, string>;
|
|
638
|
+
displaymatrix?: string;
|
|
639
|
+
[key: string]: any;
|
|
640
|
+
}
|
|
641
|
+
interface ChapterInfo {
|
|
642
|
+
id: number;
|
|
643
|
+
start_time: number;
|
|
644
|
+
end_time: number;
|
|
645
|
+
tags?: Record<string, string>;
|
|
646
|
+
}
|
|
647
|
+
declare class MetadataProcessor {
|
|
648
|
+
private ffprobePath;
|
|
649
|
+
constructor(ffprobePath?: string);
|
|
650
|
+
getMetadata(input: string): Promise<MetadataInfo>;
|
|
651
|
+
private detectRotation;
|
|
652
|
+
getVideoStream(input: string): Promise<StreamInfo | null>;
|
|
653
|
+
getAudioStream(input: string, index?: number): Promise<StreamInfo | null>;
|
|
654
|
+
needsAutoRotate(input: string): Promise<boolean>;
|
|
655
|
+
getAutoRotateFilter(input: string): Promise<string | null>;
|
|
656
|
+
getClearRotationCommand(): string[];
|
|
657
|
+
getDuration(input: string): Promise<number>;
|
|
658
|
+
getResolution(input: string): Promise<{
|
|
659
|
+
width: number;
|
|
660
|
+
height: number;
|
|
661
|
+
}>;
|
|
662
|
+
getFrameRate(input: string): Promise<number>;
|
|
663
|
+
getAudioSampleRate(input: string): Promise<number>;
|
|
664
|
+
getAudioChannels(input: string): Promise<number>;
|
|
665
|
+
hasAudio(input: string): Promise<boolean>;
|
|
666
|
+
hasVideo(input: string): Promise<boolean>;
|
|
667
|
+
getAllAudioStreams(input: string): Promise<StreamInfo[]>;
|
|
668
|
+
getAllSubtitleStreams(input: string): Promise<StreamInfo[]>;
|
|
669
|
+
}
|
|
670
|
+
declare function getMetadataProcessor(ffprobePath?: string): MetadataProcessor;
|
|
671
|
+
|
|
672
|
+
interface PluginDependency {
|
|
673
|
+
name: string;
|
|
674
|
+
version: string;
|
|
675
|
+
}
|
|
676
|
+
interface Plugin {
|
|
677
|
+
name: string;
|
|
678
|
+
version: string;
|
|
679
|
+
description?: string;
|
|
680
|
+
author?: string;
|
|
681
|
+
dependencies?: PluginDependency[];
|
|
682
|
+
install: (context: PluginContext) => void | Promise<void>;
|
|
683
|
+
uninstall?: () => void | Promise<void>;
|
|
684
|
+
}
|
|
685
|
+
interface PluginContext {
|
|
686
|
+
registerPreset: (name: string, config: PresetConfig) => void;
|
|
687
|
+
registerProcessor: (name: string, handler: ProcessorHandler) => void;
|
|
688
|
+
registerChainMethod: (name: string, method: (this: ChainableFFmpeg, ...args: any[]) => ChainableFFmpeg) => void;
|
|
689
|
+
registerBuilderMethod: (name: string, method: (this: any, ...args: any[]) => any) => void;
|
|
690
|
+
getVersion: () => string;
|
|
691
|
+
extendTypes?: (types: any) => any;
|
|
692
|
+
}
|
|
693
|
+
type ProcessorHandler = (instance: ChainableFFmpeg, options?: any) => ChainableFFmpeg | Promise<ChainableFFmpeg>;
|
|
694
|
+
declare class PluginManager {
|
|
695
|
+
private plugins;
|
|
696
|
+
private processors;
|
|
697
|
+
private presetConfigs;
|
|
698
|
+
private pluginResources;
|
|
699
|
+
install(plugin: Plugin): Promise<void>;
|
|
700
|
+
uninstall(pluginName: string): Promise<void>;
|
|
701
|
+
getPlugin(name: string): Plugin | undefined;
|
|
702
|
+
listPlugins(): Plugin[];
|
|
703
|
+
getProcessor(name: string): ProcessorHandler | undefined;
|
|
704
|
+
getPresetConfig(name: string): PresetConfig | undefined;
|
|
705
|
+
listPresetConfigs(): Array<{
|
|
706
|
+
name: string;
|
|
707
|
+
config: PresetConfig;
|
|
708
|
+
}>;
|
|
709
|
+
applyProcessor(name: string, instance: ChainableFFmpeg, options?: any): Promise<ChainableFFmpeg>;
|
|
710
|
+
has(name: string): boolean;
|
|
711
|
+
clear(): Promise<void>;
|
|
712
|
+
getStats(): {
|
|
713
|
+
pluginCount: number;
|
|
714
|
+
processorCount: number;
|
|
715
|
+
presetCount: number;
|
|
716
|
+
};
|
|
717
|
+
private checkVersionSatisfied;
|
|
718
|
+
}
|
|
719
|
+
declare function getPluginManager(): PluginManager;
|
|
720
|
+
declare function usePlugin(plugin: Plugin): Promise<void>;
|
|
721
|
+
|
|
722
|
+
declare function ffmpeg(input?: InputType, options?: FFmpegOptions): ChainableFFmpeg;
|
|
723
|
+
declare function getMetadata(input: string, options?: FFmpegOptions): Promise<VideoMetadata>;
|
|
724
|
+
|
|
725
|
+
export { type AudioFilterOptions, CacheManager, type CacheOptions$1 as CacheOptions, ChainableFFmpeg, type ChapterInfo, CommandBuilder, ConcurrentQueue, ErrorCode, type FFmpegError, type FFmpegEventListeners, type FFmpegOptions, type FFmpegResult, FFmpegWrapper, HardwareAccelDetector, type HardwareAccelInfo, type HardwareAccelType, type HardwareAcceleration, type InputType, type MetadataInfo, MetadataProcessor, type OutputType, type Plugin, type PluginContext, PluginManager, type PresetConfig, PresetManager, type ProcessorHandler, type ProgressInfo, ProgressParser, type QueueOptions, StreamHandler, type StreamHandlerOptions, type StreamInfo, type StreamType, type Task, type TaskPriority, type TaskStatus, type VideoFilterOptions, type VideoMetadata, createFFmpegError, ffmpeg as default, detectBestHardwareAccel, ffmpeg, getErrorSuggestion, getHardwareAccelDetector, getMetadata, getMetadataProcessor, getPluginManager, getStreamHandler, presets, usePlugin };
|