node-av 1.2.0 → 1.3.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/README.md +0 -21
- package/dist/api/bitstream-filter.d.ts +3 -0
- package/dist/api/bitstream-filter.js +5 -2
- package/dist/api/bitstream-filter.js.map +1 -1
- package/dist/api/decoder.d.ts +5 -0
- package/dist/api/decoder.js +7 -2
- package/dist/api/decoder.js.map +1 -1
- package/dist/api/encoder.d.ts +11 -6
- package/dist/api/encoder.js +13 -8
- package/dist/api/encoder.js.map +1 -1
- package/dist/api/filter-presets.d.ts +1267 -15
- package/dist/api/filter-presets.js +1387 -17
- package/dist/api/filter-presets.js.map +1 -1
- package/dist/api/filter.d.ts +28 -0
- package/dist/api/filter.js +30 -2
- package/dist/api/filter.js.map +1 -1
- package/dist/api/hardware.d.ts +24 -2
- package/dist/api/hardware.js +65 -8
- package/dist/api/hardware.js.map +1 -1
- package/dist/api/io-stream.d.ts +6 -0
- package/dist/api/io-stream.js +6 -0
- package/dist/api/io-stream.js.map +1 -1
- package/dist/api/media-input.d.ts +1 -0
- package/dist/api/media-input.js.map +1 -1
- package/dist/api/media-output.d.ts +4 -0
- package/dist/api/media-output.js +4 -0
- package/dist/api/media-output.js.map +1 -1
- package/dist/api/pipeline.d.ts +193 -0
- package/dist/api/pipeline.js +17 -0
- package/dist/api/pipeline.js.map +1 -1
- package/dist/api/types.d.ts +5 -0
- package/dist/api/utilities/audio-sample.d.ts +0 -8
- package/dist/api/utilities/audio-sample.js +0 -8
- package/dist/api/utilities/audio-sample.js.map +1 -1
- package/dist/api/utilities/channel-layout.d.ts +0 -8
- package/dist/api/utilities/channel-layout.js +0 -8
- package/dist/api/utilities/channel-layout.js.map +1 -1
- package/dist/api/utilities/image.d.ts +0 -8
- package/dist/api/utilities/image.js +0 -8
- package/dist/api/utilities/image.js.map +1 -1
- package/dist/api/utilities/index.d.ts +3 -3
- package/dist/api/utilities/index.js +3 -3
- package/dist/api/utilities/index.js.map +1 -1
- package/dist/api/utilities/media-type.d.ts +1 -9
- package/dist/api/utilities/media-type.js +1 -9
- package/dist/api/utilities/media-type.js.map +1 -1
- package/dist/api/utilities/pixel-format.d.ts +1 -9
- package/dist/api/utilities/pixel-format.js +1 -9
- package/dist/api/utilities/pixel-format.js.map +1 -1
- package/dist/api/utilities/sample-format.d.ts +1 -9
- package/dist/api/utilities/sample-format.js +1 -9
- package/dist/api/utilities/sample-format.js.map +1 -1
- package/dist/api/utilities/streaming.d.ts +0 -8
- package/dist/api/utilities/streaming.js +0 -8
- package/dist/api/utilities/streaming.js.map +1 -1
- package/dist/api/utilities/timestamp.d.ts +0 -8
- package/dist/api/utilities/timestamp.js +0 -8
- package/dist/api/utilities/timestamp.js.map +1 -1
- package/dist/api/utils.js +2 -0
- package/dist/api/utils.js.map +1 -1
- package/dist/constants/constants.d.ts +1 -1
- package/dist/constants/constants.js +2 -0
- package/dist/constants/constants.js.map +1 -1
- package/dist/lib/binding.d.ts +1 -0
- package/dist/lib/binding.js +2 -0
- package/dist/lib/binding.js.map +1 -1
- package/dist/lib/codec.d.ts +4 -4
- package/dist/lib/codec.js +4 -4
- package/dist/lib/error.d.ts +1 -1
- package/dist/lib/error.js +1 -1
- package/dist/lib/index.d.ts +1 -1
- package/dist/lib/index.js +1 -1
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/native-types.d.ts +1 -0
- package/dist/lib/option.d.ts +176 -0
- package/dist/lib/option.js +176 -0
- package/dist/lib/option.js.map +1 -1
- package/dist/lib/utilities.d.ts +64 -1
- package/dist/lib/utilities.js +65 -0
- package/dist/lib/utilities.js.map +1 -1
- package/install/ffmpeg.js +0 -11
- package/package.json +12 -14
- package/release_notes.md +24 -43
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { AV_HWDEVICE_TYPE_CUDA, AV_HWDEVICE_TYPE_D3D11VA, AV_HWDEVICE_TYPE_D3D12VA, AV_HWDEVICE_TYPE_DRM, AV_HWDEVICE_TYPE_DXVA2, AV_HWDEVICE_TYPE_MEDIACODEC, AV_HWDEVICE_TYPE_OPENCL, AV_HWDEVICE_TYPE_QSV, AV_HWDEVICE_TYPE_RKMPP, AV_HWDEVICE_TYPE_VAAPI, AV_HWDEVICE_TYPE_VDPAU, AV_HWDEVICE_TYPE_VIDEOTOOLBOX, AV_HWDEVICE_TYPE_VULKAN, AVFILTER_FLAG_HWDEVICE, } from '../constants/constants.js';
|
|
2
2
|
import { Filter } from '../lib/filter.js';
|
|
3
|
+
import { HardwareDeviceContext } from '../lib/hardware-device-context.js';
|
|
3
4
|
import { avGetPixFmtName, avGetSampleFmtName } from '../lib/utilities.js';
|
|
4
5
|
/**
|
|
5
6
|
* Base class for filter preset implementations.
|
|
@@ -28,6 +29,12 @@ export class FilterPresetBase {
|
|
|
28
29
|
* @param options - Additional scaling options (e.g., flags for algorithm)
|
|
29
30
|
* @returns Filter string or null if not supported
|
|
30
31
|
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```typescript
|
|
34
|
+
* presets.scale(1920, 1080) // Scale to Full HD
|
|
35
|
+
* presets.scale(640, 480, { flags: 'lanczos' }) // With specific algorithm
|
|
36
|
+
* ```
|
|
37
|
+
*
|
|
31
38
|
* @see {@link https://ffmpeg.org/ffmpeg-filters.html#scale | FFmpeg scale filter}
|
|
32
39
|
*/
|
|
33
40
|
scale(width, height, options) {
|
|
@@ -44,6 +51,12 @@ export class FilterPresetBase {
|
|
|
44
51
|
* @param y - Y coordinate of top-left corner (default: 0)
|
|
45
52
|
* @returns Filter string or null if not supported
|
|
46
53
|
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```typescript
|
|
56
|
+
* presets.crop(640, 480, 100, 100) // Crop 640x480 area starting at (100,100)
|
|
57
|
+
* presets.crop(1280, 720) // Crop from top-left corner
|
|
58
|
+
* ```
|
|
59
|
+
*
|
|
47
60
|
* @see {@link https://ffmpeg.org/ffmpeg-filters.html#crop | FFmpeg crop filter}
|
|
48
61
|
*/
|
|
49
62
|
crop(width, height, x = 0, y = 0) {
|
|
@@ -55,6 +68,12 @@ export class FilterPresetBase {
|
|
|
55
68
|
* @param fps - Target frames per second
|
|
56
69
|
* @returns Filter string or null if not supported
|
|
57
70
|
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```typescript
|
|
73
|
+
* presets.fps(30) // Convert to 30 FPS
|
|
74
|
+
* presets.fps(23.976) // Film frame rate
|
|
75
|
+
* ```
|
|
76
|
+
*
|
|
58
77
|
* @see {@link https://ffmpeg.org/ffmpeg-filters.html#fps | FFmpeg fps filter}
|
|
59
78
|
*/
|
|
60
79
|
fps(fps) {
|
|
@@ -96,6 +115,12 @@ export class FilterPresetBase {
|
|
|
96
115
|
* @param angle - Rotation angle in degrees
|
|
97
116
|
* @returns Filter string or null if not supported
|
|
98
117
|
*
|
|
118
|
+
* @example
|
|
119
|
+
* ```typescript
|
|
120
|
+
* presets.rotate(90) // Rotate 90 degrees clockwise
|
|
121
|
+
* presets.rotate(-45) // Rotate 45 degrees counter-clockwise
|
|
122
|
+
* ```
|
|
123
|
+
*
|
|
99
124
|
* @see {@link https://ffmpeg.org/ffmpeg-filters.html#rotate | FFmpeg rotate filter}
|
|
100
125
|
*/
|
|
101
126
|
rotate(angle) {
|
|
@@ -106,6 +131,11 @@ export class FilterPresetBase {
|
|
|
106
131
|
*
|
|
107
132
|
* @returns Filter string or null if not supported
|
|
108
133
|
*
|
|
134
|
+
* @example
|
|
135
|
+
* ```typescript
|
|
136
|
+
* presets.hflip() // Mirror horizontally
|
|
137
|
+
* ```
|
|
138
|
+
*
|
|
109
139
|
* @see {@link https://ffmpeg.org/ffmpeg-filters.html#hflip | FFmpeg hflip filter}
|
|
110
140
|
*/
|
|
111
141
|
hflip() {
|
|
@@ -116,6 +146,11 @@ export class FilterPresetBase {
|
|
|
116
146
|
*
|
|
117
147
|
* @returns Filter string or null if not supported
|
|
118
148
|
*
|
|
149
|
+
* @example
|
|
150
|
+
* ```typescript
|
|
151
|
+
* presets.vflip() // Flip upside down
|
|
152
|
+
* ```
|
|
153
|
+
*
|
|
119
154
|
* @see {@link https://ffmpeg.org/ffmpeg-filters.html#vflip | FFmpeg vflip filter}
|
|
120
155
|
*/
|
|
121
156
|
vflip() {
|
|
@@ -129,6 +164,12 @@ export class FilterPresetBase {
|
|
|
129
164
|
* @param duration - Fade duration in seconds
|
|
130
165
|
* @returns Filter string or null if not supported
|
|
131
166
|
*
|
|
167
|
+
* @example
|
|
168
|
+
* ```typescript
|
|
169
|
+
* presets.fade('in', 0, 2) // 2-second fade in from start
|
|
170
|
+
* presets.fade('out', 10, 1) // 1-second fade out at 10 seconds
|
|
171
|
+
* ```
|
|
172
|
+
*
|
|
132
173
|
* @see {@link https://ffmpeg.org/ffmpeg-filters.html#fade | FFmpeg fade filter}
|
|
133
174
|
*/
|
|
134
175
|
fade(type, start, duration) {
|
|
@@ -168,6 +209,12 @@ export class FilterPresetBase {
|
|
|
168
209
|
* @param factor - Volume multiplication factor (1.0 = unchanged, 2.0 = double)
|
|
169
210
|
* @returns Filter string or null if not supported
|
|
170
211
|
*
|
|
212
|
+
* @example
|
|
213
|
+
* ```typescript
|
|
214
|
+
* presets.volume(0.5) // Reduce volume by 50%
|
|
215
|
+
* presets.volume(1.5) // Increase volume by 50%
|
|
216
|
+
* ```
|
|
217
|
+
*
|
|
171
218
|
* @see {@link https://ffmpeg.org/ffmpeg-filters.html#volume | FFmpeg volume filter}
|
|
172
219
|
*/
|
|
173
220
|
volume(factor) {
|
|
@@ -204,6 +251,29 @@ export class FilterPresetBase {
|
|
|
204
251
|
filter += `:channel_layouts=${channelLayout}`;
|
|
205
252
|
return filter;
|
|
206
253
|
}
|
|
254
|
+
/**
|
|
255
|
+
* Creates an asetnsamples filter string to set the number of samples per frame.
|
|
256
|
+
* This is crucial for encoders like Opus that require specific frame sizes.
|
|
257
|
+
*
|
|
258
|
+
* @param samples - Number of samples per frame
|
|
259
|
+
* @param padding - Whether to pad or drop samples (default: true)
|
|
260
|
+
* @returns Filter string or null if not supported
|
|
261
|
+
*
|
|
262
|
+
* @example
|
|
263
|
+
* ```typescript
|
|
264
|
+
* // For Opus encoder (requires 960 samples)
|
|
265
|
+
* presets.asetnsamples(960);
|
|
266
|
+
*
|
|
267
|
+
* // Drop samples instead of padding
|
|
268
|
+
* presets.asetnsamples(1024, false);
|
|
269
|
+
* ```
|
|
270
|
+
*
|
|
271
|
+
* @see {@link https://ffmpeg.org/ffmpeg-filters.html#asetnsamples | FFmpeg asetnsamples filter}
|
|
272
|
+
*/
|
|
273
|
+
asetnsamples(samples, padding = true) {
|
|
274
|
+
const p = padding ? 1 : 0;
|
|
275
|
+
return `asetnsamples=n=${samples}:p=${p}`;
|
|
276
|
+
}
|
|
207
277
|
/**
|
|
208
278
|
* Creates an atempo filter string to change audio playback speed.
|
|
209
279
|
* Factor must be between 0.5 and 2.0. For larger changes, chain multiple atempo filters.
|
|
@@ -211,6 +281,12 @@ export class FilterPresetBase {
|
|
|
211
281
|
* @param factor - Tempo factor (0.5 = half speed, 2.0 = double speed)
|
|
212
282
|
* @returns Filter string or null if not supported
|
|
213
283
|
*
|
|
284
|
+
* @example
|
|
285
|
+
* ```typescript
|
|
286
|
+
* presets.atempo(1.5) // 1.5x speed
|
|
287
|
+
* presets.atempo(0.8) // Slow down to 80% speed
|
|
288
|
+
* ```
|
|
289
|
+
*
|
|
214
290
|
* @see {@link https://ffmpeg.org/ffmpeg-filters.html#atempo | FFmpeg atempo filter}
|
|
215
291
|
*/
|
|
216
292
|
atempo(factor) {
|
|
@@ -224,6 +300,12 @@ export class FilterPresetBase {
|
|
|
224
300
|
* @param duration - Fade duration in seconds
|
|
225
301
|
* @returns Filter string or null if not supported
|
|
226
302
|
*
|
|
303
|
+
* @example
|
|
304
|
+
* ```typescript
|
|
305
|
+
* presets.afade('in', 0, 3) // 3-second audio fade in
|
|
306
|
+
* presets.afade('out', 20, 2) // 2-second fade out at 20s
|
|
307
|
+
* ```
|
|
308
|
+
*
|
|
227
309
|
* @see {@link https://ffmpeg.org/ffmpeg-filters.html#afade | FFmpeg afade filter}
|
|
228
310
|
*/
|
|
229
311
|
afade(type, start, duration) {
|
|
@@ -236,11 +318,360 @@ export class FilterPresetBase {
|
|
|
236
318
|
* @param duration - How to determine output duration (default: 'longest')
|
|
237
319
|
* @returns Filter string or null if not supported
|
|
238
320
|
*
|
|
321
|
+
* @example
|
|
322
|
+
* ```typescript
|
|
323
|
+
* presets.amix(3, 'longest') // Mix 3 audio streams
|
|
324
|
+
* presets.amix(2, 'first') // Mix 2 streams, use first's duration
|
|
325
|
+
* ```
|
|
326
|
+
*
|
|
239
327
|
* @see {@link https://ffmpeg.org/ffmpeg-filters.html#amix | FFmpeg amix filter}
|
|
240
328
|
*/
|
|
241
329
|
amix(inputs = 2, duration = 'longest') {
|
|
242
330
|
return `amix=inputs=${inputs}:duration=${duration}`;
|
|
243
331
|
}
|
|
332
|
+
/**
|
|
333
|
+
* Creates a pad filter string to add padding to video.
|
|
334
|
+
* Essential for aspect ratio adjustments and letterboxing.
|
|
335
|
+
*
|
|
336
|
+
* @param width - Output width (can use expressions like 'iw+100')
|
|
337
|
+
* @param height - Output height (can use expressions like 'ih+100')
|
|
338
|
+
* @param x - X position of input video (default: '(ow-iw)/2' for center)
|
|
339
|
+
* @param y - Y position of input video (default: '(oh-ih)/2' for center)
|
|
340
|
+
* @param color - Padding color (default: 'black')
|
|
341
|
+
* @returns Filter string or null if not supported
|
|
342
|
+
*
|
|
343
|
+
* @example
|
|
344
|
+
* ```typescript
|
|
345
|
+
* // Add black bars for 16:9 aspect ratio
|
|
346
|
+
* presets.pad('iw', 'iw*9/16');
|
|
347
|
+
*
|
|
348
|
+
* // Add 50px padding on all sides
|
|
349
|
+
* presets.pad('iw+100', 'ih+100');
|
|
350
|
+
* ```
|
|
351
|
+
*
|
|
352
|
+
* @see {@link https://ffmpeg.org/ffmpeg-filters.html#pad | FFmpeg pad filter}
|
|
353
|
+
*/
|
|
354
|
+
pad(width, height, x, y, color = 'black') {
|
|
355
|
+
let filter = `pad=${width}:${height}`;
|
|
356
|
+
if (x !== undefined)
|
|
357
|
+
filter += `:${x}`;
|
|
358
|
+
if (y !== undefined)
|
|
359
|
+
filter += `:${y}`;
|
|
360
|
+
filter += `:${color}`;
|
|
361
|
+
return filter;
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Creates a trim filter string to cut a portion of the stream.
|
|
365
|
+
* Crucial for cutting segments from media.
|
|
366
|
+
*
|
|
367
|
+
* @param start - Start time in seconds
|
|
368
|
+
* @param end - End time in seconds (optional)
|
|
369
|
+
* @param duration - Duration in seconds (optional, alternative to end)
|
|
370
|
+
* @returns Filter string or null if not supported
|
|
371
|
+
*
|
|
372
|
+
* @example
|
|
373
|
+
* ```typescript
|
|
374
|
+
* presets.trim(10, 30) // Extract from 10s to 30s
|
|
375
|
+
* presets.trim(5, undefined, 10) // Extract 10s starting at 5s
|
|
376
|
+
* ```
|
|
377
|
+
*
|
|
378
|
+
* @see {@link https://ffmpeg.org/ffmpeg-filters.html#trim | FFmpeg trim filter}
|
|
379
|
+
*/
|
|
380
|
+
trim(start, end, duration) {
|
|
381
|
+
let filter = `trim=start=${start}`;
|
|
382
|
+
if (end !== undefined)
|
|
383
|
+
filter += `:end=${end}`;
|
|
384
|
+
if (duration !== undefined)
|
|
385
|
+
filter += `:duration=${duration}`;
|
|
386
|
+
return filter;
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* Creates a setpts filter string to change presentation timestamps.
|
|
390
|
+
* Essential for speed changes and timestamp manipulation.
|
|
391
|
+
*
|
|
392
|
+
* @param expression - PTS expression (e.g., 'PTS*2' for half speed, 'PTS/2' for double speed)
|
|
393
|
+
* @returns Filter string or null if not supported
|
|
394
|
+
*
|
|
395
|
+
* @example
|
|
396
|
+
* ```typescript
|
|
397
|
+
* // Double speed
|
|
398
|
+
* presets.setpts('PTS/2');
|
|
399
|
+
*
|
|
400
|
+
* // Half speed
|
|
401
|
+
* presets.setpts('PTS*2');
|
|
402
|
+
*
|
|
403
|
+
* // Reset timestamps
|
|
404
|
+
* presets.setpts('PTS-STARTPTS');
|
|
405
|
+
* ```
|
|
406
|
+
*
|
|
407
|
+
* @see {@link https://ffmpeg.org/ffmpeg-filters.html#setpts | FFmpeg setpts filter}
|
|
408
|
+
*/
|
|
409
|
+
setpts(expression) {
|
|
410
|
+
return `setpts=${expression}`;
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* Creates an asetpts filter string for audio timestamp manipulation.
|
|
414
|
+
*
|
|
415
|
+
* @param expression - PTS expression
|
|
416
|
+
* @returns Filter string or null if not supported
|
|
417
|
+
*
|
|
418
|
+
* @example
|
|
419
|
+
* ```typescript
|
|
420
|
+
* presets.asetpts('PTS-STARTPTS') // Reset timestamps to start from 0
|
|
421
|
+
* ```
|
|
422
|
+
*
|
|
423
|
+
* @see {@link https://ffmpeg.org/ffmpeg-filters.html#asetpts | FFmpeg asetpts filter}
|
|
424
|
+
*/
|
|
425
|
+
asetpts(expression) {
|
|
426
|
+
return `asetpts=${expression}`;
|
|
427
|
+
}
|
|
428
|
+
/**
|
|
429
|
+
* Creates a transpose filter string for rotation/flipping.
|
|
430
|
+
* More efficient than rotate for 90-degree rotations.
|
|
431
|
+
*
|
|
432
|
+
* @param mode - Transpose mode (0-3, or named constants)
|
|
433
|
+
* @returns Filter string or null if not supported
|
|
434
|
+
*
|
|
435
|
+
* @example
|
|
436
|
+
* ```typescript
|
|
437
|
+
* presets.transpose(1) // Rotate 90 degrees clockwise
|
|
438
|
+
* presets.transpose('cclock') // Rotate 90 degrees counter-clockwise
|
|
439
|
+
* ```
|
|
440
|
+
*
|
|
441
|
+
* @see {@link https://ffmpeg.org/ffmpeg-filters.html#transpose | FFmpeg transpose filter}
|
|
442
|
+
*/
|
|
443
|
+
transpose(mode) {
|
|
444
|
+
return `transpose=${mode}`;
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* Creates a setsar filter string to set sample aspect ratio.
|
|
448
|
+
* Important for correcting aspect ratio issues.
|
|
449
|
+
*
|
|
450
|
+
* @param ratio - Aspect ratio (e.g., '1:1', '16:9', or number)
|
|
451
|
+
* @returns Filter string or null if not supported
|
|
452
|
+
*
|
|
453
|
+
* @example
|
|
454
|
+
* ```typescript
|
|
455
|
+
* presets.setsar('1:1') // Square pixels
|
|
456
|
+
* presets.setsar(1.333) // 4:3 aspect ratio
|
|
457
|
+
* ```
|
|
458
|
+
*
|
|
459
|
+
* @see {@link https://ffmpeg.org/ffmpeg-filters.html#setsar | FFmpeg setsar/setdar filter}
|
|
460
|
+
*/
|
|
461
|
+
setsar(ratio) {
|
|
462
|
+
return `setsar=${ratio}`;
|
|
463
|
+
}
|
|
464
|
+
/**
|
|
465
|
+
* Creates a setdar filter string to set display aspect ratio.
|
|
466
|
+
*
|
|
467
|
+
* @param ratio - Aspect ratio (e.g., '16:9', '4:3')
|
|
468
|
+
* @returns Filter string or null if not supported
|
|
469
|
+
*
|
|
470
|
+
* @example
|
|
471
|
+
* ```typescript
|
|
472
|
+
* presets.setdar('16:9') // Widescreen
|
|
473
|
+
* presets.setdar('4:3') // Traditional TV aspect
|
|
474
|
+
* ```
|
|
475
|
+
*
|
|
476
|
+
* @see {@link https://ffmpeg.org/ffmpeg-filters.html#setsar | FFmpeg setsar/setdar filter}
|
|
477
|
+
*/
|
|
478
|
+
setdar(ratio) {
|
|
479
|
+
return `setdar=${ratio}`;
|
|
480
|
+
}
|
|
481
|
+
/**
|
|
482
|
+
* Creates an apad filter string to add audio padding.
|
|
483
|
+
* Useful for ensuring minimum audio duration.
|
|
484
|
+
*
|
|
485
|
+
* @param wholeDuration - Minimum duration in seconds (optional)
|
|
486
|
+
* @param padDuration - Amount of padding to add in seconds (optional)
|
|
487
|
+
* @returns Filter string or null if not supported
|
|
488
|
+
*
|
|
489
|
+
* @example
|
|
490
|
+
* ```typescript
|
|
491
|
+
* presets.apad(30) // Ensure at least 30 seconds total
|
|
492
|
+
* presets.apad(undefined, 5) // Add 5 seconds of padding
|
|
493
|
+
* ```
|
|
494
|
+
*
|
|
495
|
+
* @see {@link https://ffmpeg.org/ffmpeg-filters.html#apad | FFmpeg apad filter}
|
|
496
|
+
*/
|
|
497
|
+
apad(wholeDuration, padDuration) {
|
|
498
|
+
if (!wholeDuration && !padDuration)
|
|
499
|
+
return 'apad';
|
|
500
|
+
let filter = 'apad';
|
|
501
|
+
if (wholeDuration)
|
|
502
|
+
filter += `=whole_dur=${wholeDuration}`;
|
|
503
|
+
if (padDuration)
|
|
504
|
+
filter += wholeDuration ? `:pad_dur=${padDuration}` : `=pad_dur=${padDuration}`;
|
|
505
|
+
return filter;
|
|
506
|
+
}
|
|
507
|
+
/**
|
|
508
|
+
* Creates a deinterlace filter string.
|
|
509
|
+
* Essential for processing interlaced content.
|
|
510
|
+
*
|
|
511
|
+
* @param mode - Deinterlace mode (default: 'yadif')
|
|
512
|
+
* @returns Filter string or null if not supported
|
|
513
|
+
*
|
|
514
|
+
* @example
|
|
515
|
+
* ```typescript
|
|
516
|
+
* presets.deinterlace('yadif') // Standard deinterlacing
|
|
517
|
+
* presets.deinterlace('bwdif') // Bob Weaver deinterlacing
|
|
518
|
+
* ```
|
|
519
|
+
*
|
|
520
|
+
* @see {@link https://ffmpeg.org/ffmpeg-filters.html#yadif | FFmpeg yadif filter}
|
|
521
|
+
*/
|
|
522
|
+
deinterlace(mode = 'yadif') {
|
|
523
|
+
return mode;
|
|
524
|
+
}
|
|
525
|
+
/**
|
|
526
|
+
* Creates a select filter string to select specific frames.
|
|
527
|
+
* Powerful for extracting keyframes, specific frame types, etc.
|
|
528
|
+
*
|
|
529
|
+
* @param expression - Selection expression
|
|
530
|
+
* @returns Filter string or null if not supported
|
|
531
|
+
*
|
|
532
|
+
* @example
|
|
533
|
+
* ```typescript
|
|
534
|
+
* presets.select('eq(pict_type,I)') // Select only keyframes
|
|
535
|
+
* presets.select('not(mod(n,10))') // Select every 10th frame
|
|
536
|
+
* ```
|
|
537
|
+
*
|
|
538
|
+
* @see {@link https://ffmpeg.org/ffmpeg-filters.html#select | FFmpeg select filter}
|
|
539
|
+
*/
|
|
540
|
+
select(expression) {
|
|
541
|
+
return `select='${expression}'`;
|
|
542
|
+
}
|
|
543
|
+
/**
|
|
544
|
+
* Creates an aselect filter string for audio selection.
|
|
545
|
+
*
|
|
546
|
+
* @param expression - Selection expression
|
|
547
|
+
* @returns Filter string or null if not supported
|
|
548
|
+
*
|
|
549
|
+
* @example
|
|
550
|
+
* ```typescript
|
|
551
|
+
* presets.aselect('between(t,10,20)') // Select audio between 10-20 seconds
|
|
552
|
+
* ```
|
|
553
|
+
*
|
|
554
|
+
* @see {@link https://ffmpeg.org/ffmpeg-filters.html#aselect | FFmpeg aselect filter}
|
|
555
|
+
*/
|
|
556
|
+
aselect(expression) {
|
|
557
|
+
return `aselect='${expression}'`;
|
|
558
|
+
}
|
|
559
|
+
/**
|
|
560
|
+
* Creates a concat filter string to concatenate multiple inputs.
|
|
561
|
+
* Essential for joining multiple video/audio segments.
|
|
562
|
+
*
|
|
563
|
+
* @param n - Number of input segments
|
|
564
|
+
* @param v - Number of output video streams (0 or 1)
|
|
565
|
+
* @param a - Number of output audio streams (0 or 1)
|
|
566
|
+
* @returns Filter string or null if not supported
|
|
567
|
+
*
|
|
568
|
+
* @example
|
|
569
|
+
* ```typescript
|
|
570
|
+
* presets.concat(3, 1, 1) // Join 3 segments with video and audio
|
|
571
|
+
* presets.concat(2, 1, 0) // Join 2 video-only segments
|
|
572
|
+
* ```
|
|
573
|
+
*
|
|
574
|
+
* @see {@link https://ffmpeg.org/ffmpeg-filters.html#concat | FFmpeg concat filter}
|
|
575
|
+
*/
|
|
576
|
+
concat(n, v = 1, a = 1) {
|
|
577
|
+
return `concat=n=${n}:v=${v}:a=${a}`;
|
|
578
|
+
}
|
|
579
|
+
/**
|
|
580
|
+
* Creates an amerge filter string to merge multiple audio streams into one.
|
|
581
|
+
* Different from amix - this creates multi-channel output.
|
|
582
|
+
*
|
|
583
|
+
* @param inputs - Number of input streams
|
|
584
|
+
* @returns Filter string or null if not supported
|
|
585
|
+
*
|
|
586
|
+
* @example
|
|
587
|
+
* ```typescript
|
|
588
|
+
* presets.amerge(2) // Merge 2 mono streams to stereo
|
|
589
|
+
* presets.amerge(6) // Merge 6 channels for 5.1 surround
|
|
590
|
+
* ```
|
|
591
|
+
*
|
|
592
|
+
* @see {@link https://ffmpeg.org/ffmpeg-filters.html#amerge | FFmpeg amerge filter}
|
|
593
|
+
*/
|
|
594
|
+
amerge(inputs = 2) {
|
|
595
|
+
return `amerge=inputs=${inputs}`;
|
|
596
|
+
}
|
|
597
|
+
/**
|
|
598
|
+
* Creates a channelmap filter string to remap audio channels.
|
|
599
|
+
* Critical for audio channel manipulation.
|
|
600
|
+
*
|
|
601
|
+
* @param map - Channel mapping (e.g., '0-0|1-1' or 'FL-FR|FR-FL' to swap stereo)
|
|
602
|
+
* @returns Filter string or null if not supported
|
|
603
|
+
*
|
|
604
|
+
* @example
|
|
605
|
+
* ```typescript
|
|
606
|
+
* presets.channelmap('FL-FR|FR-FL') // Swap left and right channels
|
|
607
|
+
* presets.channelmap('0-0|0-1') // Duplicate mono to stereo
|
|
608
|
+
* ```
|
|
609
|
+
*
|
|
610
|
+
* @see {@link https://ffmpeg.org/ffmpeg-filters.html#channelmap | FFmpeg channelmap filter}
|
|
611
|
+
*/
|
|
612
|
+
channelmap(map) {
|
|
613
|
+
return `channelmap=${map}`;
|
|
614
|
+
}
|
|
615
|
+
/**
|
|
616
|
+
* Creates a channelsplit filter string to split audio channels.
|
|
617
|
+
*
|
|
618
|
+
* @param channelLayout - Channel layout to split (optional)
|
|
619
|
+
* @returns Filter string or null if not supported
|
|
620
|
+
*
|
|
621
|
+
* @example
|
|
622
|
+
* ```typescript
|
|
623
|
+
* presets.channelsplit('stereo') // Split stereo to 2 mono
|
|
624
|
+
* presets.channelsplit('5.1') // Split 5.1 to individual channels
|
|
625
|
+
* ```
|
|
626
|
+
*
|
|
627
|
+
* @see {@link https://ffmpeg.org/ffmpeg-filters.html#channelsplit | FFmpeg channelsplit filter}
|
|
628
|
+
*/
|
|
629
|
+
channelsplit(channelLayout) {
|
|
630
|
+
return channelLayout ? `channelsplit=channel_layout=${channelLayout}` : 'channelsplit';
|
|
631
|
+
}
|
|
632
|
+
/**
|
|
633
|
+
* Creates a loudnorm filter string for loudness normalization.
|
|
634
|
+
* Essential for broadcast compliance and consistent audio levels.
|
|
635
|
+
*
|
|
636
|
+
* @param I - Integrated loudness target (default: -24 LUFS)
|
|
637
|
+
* @param TP - True peak (default: -2 dBTP)
|
|
638
|
+
* @param LRA - Loudness range (default: 7 LU)
|
|
639
|
+
* @returns Filter string or null if not supported
|
|
640
|
+
*
|
|
641
|
+
* @example
|
|
642
|
+
* ```typescript
|
|
643
|
+
* presets.loudnorm(-23, -1, 7) // EBU R128 broadcast standard
|
|
644
|
+
* presets.loudnorm(-16, -1.5, 11) // Streaming platforms standard
|
|
645
|
+
* ```
|
|
646
|
+
*
|
|
647
|
+
* @see {@link https://ffmpeg.org/ffmpeg-filters.html#loudnorm | FFmpeg loudnorm filter}
|
|
648
|
+
*/
|
|
649
|
+
loudnorm(I = -24, TP = -2, LRA = 7) {
|
|
650
|
+
return `loudnorm=I=${I}:TP=${TP}:LRA=${LRA}`;
|
|
651
|
+
}
|
|
652
|
+
/**
|
|
653
|
+
* Creates a compand filter string for audio compression/expansion.
|
|
654
|
+
* Important for dynamic range control.
|
|
655
|
+
*
|
|
656
|
+
* @param attacks - Attack times
|
|
657
|
+
* @param decays - Decay times
|
|
658
|
+
* @param points - Transfer function points
|
|
659
|
+
* @param gain - Output gain
|
|
660
|
+
* @returns Filter string or null if not supported
|
|
661
|
+
*
|
|
662
|
+
* @example
|
|
663
|
+
* ```typescript
|
|
664
|
+
* presets.compand('0.3|0.3', '1|1', '-90/-60|-60/-40|-40/-30|-20/-20', 6)
|
|
665
|
+
* ```
|
|
666
|
+
*
|
|
667
|
+
* @see {@link https://ffmpeg.org/ffmpeg-filters.html#compand | FFmpeg compand filter}
|
|
668
|
+
*/
|
|
669
|
+
compand(attacks, decays, points, gain) {
|
|
670
|
+
let filter = `compand=attacks=${attacks}:decays=${decays}:points=${points}`;
|
|
671
|
+
if (gain !== undefined)
|
|
672
|
+
filter += `:gain=${gain}`;
|
|
673
|
+
return filter;
|
|
674
|
+
}
|
|
244
675
|
}
|
|
245
676
|
/**
|
|
246
677
|
* Filter chain builder for composing multiple filters.
|
|
@@ -263,6 +694,11 @@ export class FilterChain {
|
|
|
263
694
|
*
|
|
264
695
|
* @param filter - Filter string to add (ignored if null/undefined)
|
|
265
696
|
* @returns This instance for chaining
|
|
697
|
+
*
|
|
698
|
+
* @example
|
|
699
|
+
* ```typescript
|
|
700
|
+
* chain.add('scale=1920:1080')
|
|
701
|
+
* ```
|
|
266
702
|
*/
|
|
267
703
|
add(filter) {
|
|
268
704
|
if (filter) {
|
|
@@ -275,6 +711,11 @@ export class FilterChain {
|
|
|
275
711
|
*
|
|
276
712
|
* @param filter - Custom filter string
|
|
277
713
|
* @returns This instance for chaining
|
|
714
|
+
*
|
|
715
|
+
* @example
|
|
716
|
+
* ```typescript
|
|
717
|
+
* chain.custom('myfilter=param1:param2')
|
|
718
|
+
* ```
|
|
278
719
|
*/
|
|
279
720
|
custom(filter) {
|
|
280
721
|
return this.add(filter);
|
|
@@ -284,6 +725,11 @@ export class FilterChain {
|
|
|
284
725
|
*
|
|
285
726
|
* @param separator - Separator between filters (default: ',')
|
|
286
727
|
* @returns Combined filter string
|
|
728
|
+
*
|
|
729
|
+
* @example
|
|
730
|
+
* ```typescript
|
|
731
|
+
* const filterString = chain.build() // "scale=1920:1080,fps=30"
|
|
732
|
+
* ```
|
|
287
733
|
*/
|
|
288
734
|
build(separator = ',') {
|
|
289
735
|
return this.filters.join(separator);
|
|
@@ -292,6 +738,11 @@ export class FilterChain {
|
|
|
292
738
|
* Returns the filters as an array.
|
|
293
739
|
*
|
|
294
740
|
* @returns Array of filter strings
|
|
741
|
+
*
|
|
742
|
+
* @example
|
|
743
|
+
* ```typescript
|
|
744
|
+
* const filters = chain.toArray() // ["scale=1920:1080", "fps=30"]
|
|
745
|
+
* ```
|
|
295
746
|
*/
|
|
296
747
|
toArray() {
|
|
297
748
|
return [...this.filters];
|
|
@@ -328,22 +779,52 @@ export class ChainBuilderBase extends FilterChain {
|
|
|
328
779
|
* @param width - Target width
|
|
329
780
|
* @param height - Target height
|
|
330
781
|
* @param options - Additional scaling options
|
|
782
|
+
*
|
|
331
783
|
* @returns This instance for chaining
|
|
332
784
|
*
|
|
333
|
-
* @
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
785
|
+
* @example
|
|
786
|
+
* ```typescript
|
|
787
|
+
* const chain = FilterPresets.chain()
|
|
788
|
+
* .scale(1920, 1080)
|
|
789
|
+
* .build();
|
|
790
|
+
* ```
|
|
791
|
+
*
|
|
792
|
+
* @example
|
|
793
|
+
* ```typescript
|
|
794
|
+
* const chain = FilterPresets.chain()
|
|
795
|
+
* .scale(1280, 720, { flags: 'lanczos' })
|
|
796
|
+
* .build();
|
|
797
|
+
* ```
|
|
798
|
+
*
|
|
799
|
+
* @see {@link FilterPresetBase.scale}
|
|
800
|
+
*/
|
|
801
|
+
scale(width, height, options) {
|
|
802
|
+
return this.add(this.presets.scale(width, height, options));
|
|
803
|
+
}
|
|
804
|
+
/**
|
|
339
805
|
* Adds a crop filter to the chain.
|
|
340
806
|
*
|
|
341
807
|
* @param width - Crop width
|
|
342
808
|
* @param height - Crop height
|
|
343
809
|
* @param x - X position (default: 0)
|
|
344
810
|
* @param y - Y position (default: 0)
|
|
811
|
+
*
|
|
345
812
|
* @returns This instance for chaining
|
|
346
813
|
*
|
|
814
|
+
* @example
|
|
815
|
+
* ```typescript
|
|
816
|
+
* const chain = FilterPresets.chain()
|
|
817
|
+
* .crop(640, 480)
|
|
818
|
+
* .build();
|
|
819
|
+
* ```
|
|
820
|
+
*
|
|
821
|
+
* @example
|
|
822
|
+
* ```typescript
|
|
823
|
+
* const chain = FilterPresets.chain()
|
|
824
|
+
* .crop(1920, 1080, 100, 50)
|
|
825
|
+
* .build();
|
|
826
|
+
* ```
|
|
827
|
+
*
|
|
347
828
|
* @see {@link FilterPresetBase.crop}
|
|
348
829
|
*/
|
|
349
830
|
crop(width, height, x = 0, y = 0) {
|
|
@@ -353,8 +834,23 @@ export class ChainBuilderBase extends FilterChain {
|
|
|
353
834
|
* Adds an FPS filter to the chain.
|
|
354
835
|
*
|
|
355
836
|
* @param fps - Target frame rate
|
|
837
|
+
*
|
|
356
838
|
* @returns This instance for chaining
|
|
357
839
|
*
|
|
840
|
+
* @example
|
|
841
|
+
* ```typescript
|
|
842
|
+
* const chain = FilterPresets.chain()
|
|
843
|
+
* .fps(30)
|
|
844
|
+
* .build();
|
|
845
|
+
* ```
|
|
846
|
+
*
|
|
847
|
+
* @example
|
|
848
|
+
* ```typescript
|
|
849
|
+
* const chain = FilterPresets.chain()
|
|
850
|
+
* .fps(23.976)
|
|
851
|
+
* .build();
|
|
852
|
+
* ```
|
|
853
|
+
*
|
|
358
854
|
* @see {@link FilterPresetBase.fps}
|
|
359
855
|
*/
|
|
360
856
|
fps(fps) {
|
|
@@ -364,8 +860,23 @@ export class ChainBuilderBase extends FilterChain {
|
|
|
364
860
|
* Adds a format filter to the chain.
|
|
365
861
|
*
|
|
366
862
|
* @param pixelFormat - Target pixel format(s)
|
|
863
|
+
*
|
|
367
864
|
* @returns This instance for chaining
|
|
368
865
|
*
|
|
866
|
+
* @example
|
|
867
|
+
* ```typescript
|
|
868
|
+
* const chain = FilterPresets.chain()
|
|
869
|
+
* .format('yuv420p')
|
|
870
|
+
* .build();
|
|
871
|
+
* ```
|
|
872
|
+
*
|
|
873
|
+
* @example
|
|
874
|
+
* ```typescript
|
|
875
|
+
* const chain = FilterPresets.chain()
|
|
876
|
+
* .format(AV_PIX_FMT_RGB24)
|
|
877
|
+
* .build();
|
|
878
|
+
* ```
|
|
879
|
+
*
|
|
369
880
|
* @see {@link FilterPresetBase.format}
|
|
370
881
|
*/
|
|
371
882
|
format(pixelFormat) {
|
|
@@ -375,8 +886,23 @@ export class ChainBuilderBase extends FilterChain {
|
|
|
375
886
|
* Adds a rotate filter to the chain.
|
|
376
887
|
*
|
|
377
888
|
* @param angle - Rotation angle in degrees
|
|
889
|
+
*
|
|
378
890
|
* @returns This instance for chaining
|
|
379
891
|
*
|
|
892
|
+
* @example
|
|
893
|
+
* ```typescript
|
|
894
|
+
* const chain = FilterPresets.chain()
|
|
895
|
+
* .rotate(45)
|
|
896
|
+
* .build();
|
|
897
|
+
* ```
|
|
898
|
+
*
|
|
899
|
+
* @example
|
|
900
|
+
* ```typescript
|
|
901
|
+
* const chain = FilterPresets.chain()
|
|
902
|
+
* .rotate(-90)
|
|
903
|
+
* .build();
|
|
904
|
+
* ```
|
|
905
|
+
*
|
|
380
906
|
* @see {@link FilterPresetBase.rotate}
|
|
381
907
|
*/
|
|
382
908
|
rotate(angle) {
|
|
@@ -387,6 +913,13 @@ export class ChainBuilderBase extends FilterChain {
|
|
|
387
913
|
*
|
|
388
914
|
* @returns This instance for chaining
|
|
389
915
|
*
|
|
916
|
+
* @example
|
|
917
|
+
* ```typescript
|
|
918
|
+
* const chain = FilterPresets.chain()
|
|
919
|
+
* .hflip()
|
|
920
|
+
* .build();
|
|
921
|
+
* ```
|
|
922
|
+
*
|
|
390
923
|
* @see {@link FilterPresetBase.hflip}
|
|
391
924
|
*/
|
|
392
925
|
hflip() {
|
|
@@ -397,6 +930,13 @@ export class ChainBuilderBase extends FilterChain {
|
|
|
397
930
|
*
|
|
398
931
|
* @returns This instance for chaining
|
|
399
932
|
*
|
|
933
|
+
* @example
|
|
934
|
+
* ```typescript
|
|
935
|
+
* const chain = FilterPresets.chain()
|
|
936
|
+
* .vflip()
|
|
937
|
+
* .build();
|
|
938
|
+
* ```
|
|
939
|
+
*
|
|
400
940
|
* @see {@link FilterPresetBase.vflip}
|
|
401
941
|
*/
|
|
402
942
|
vflip() {
|
|
@@ -408,8 +948,23 @@ export class ChainBuilderBase extends FilterChain {
|
|
|
408
948
|
* @param type - Fade type ('in' or 'out')
|
|
409
949
|
* @param start - Start time in seconds
|
|
410
950
|
* @param duration - Fade duration in seconds
|
|
951
|
+
*
|
|
411
952
|
* @returns This instance for chaining
|
|
412
953
|
*
|
|
954
|
+
* @example
|
|
955
|
+
* ```typescript
|
|
956
|
+
* const chain = FilterPresets.chain()
|
|
957
|
+
* .fade('in', 0, 2)
|
|
958
|
+
* .build();
|
|
959
|
+
* ```
|
|
960
|
+
*
|
|
961
|
+
* @example
|
|
962
|
+
* ```typescript
|
|
963
|
+
* const chain = FilterPresets.chain()
|
|
964
|
+
* .fade('out', 10, 1.5)
|
|
965
|
+
* .build();
|
|
966
|
+
* ```
|
|
967
|
+
*
|
|
413
968
|
* @see {@link FilterPresetBase.fade}
|
|
414
969
|
*/
|
|
415
970
|
fade(type, start, duration) {
|
|
@@ -421,8 +976,23 @@ export class ChainBuilderBase extends FilterChain {
|
|
|
421
976
|
* @param x - X position (default: 0)
|
|
422
977
|
* @param y - Y position (default: 0)
|
|
423
978
|
* @param options - Additional overlay options
|
|
979
|
+
*
|
|
424
980
|
* @returns This instance for chaining
|
|
425
981
|
*
|
|
982
|
+
* @example
|
|
983
|
+
* ```typescript
|
|
984
|
+
* const chain = FilterPresets.chain()
|
|
985
|
+
* .overlay(100, 50)
|
|
986
|
+
* .build();
|
|
987
|
+
* ```
|
|
988
|
+
*
|
|
989
|
+
* @example
|
|
990
|
+
* ```typescript
|
|
991
|
+
* const chain = FilterPresets.chain()
|
|
992
|
+
* .overlay(10, 10, { enable: 'between(t,5,10)' })
|
|
993
|
+
* .build();
|
|
994
|
+
* ```
|
|
995
|
+
*
|
|
426
996
|
* @see {@link FilterPresetBase.overlay}
|
|
427
997
|
*/
|
|
428
998
|
overlay(x = 0, y = 0, options) {
|
|
@@ -432,8 +1002,23 @@ export class ChainBuilderBase extends FilterChain {
|
|
|
432
1002
|
* Adds a volume filter to the chain.
|
|
433
1003
|
*
|
|
434
1004
|
* @param factor - Volume factor
|
|
1005
|
+
*
|
|
435
1006
|
* @returns This instance for chaining
|
|
436
1007
|
*
|
|
1008
|
+
* @example
|
|
1009
|
+
* ```typescript
|
|
1010
|
+
* const chain = FilterPresets.chain()
|
|
1011
|
+
* .volume(0.5)
|
|
1012
|
+
* .build();
|
|
1013
|
+
* ```
|
|
1014
|
+
*
|
|
1015
|
+
* @example
|
|
1016
|
+
* ```typescript
|
|
1017
|
+
* const chain = FilterPresets.chain()
|
|
1018
|
+
* .volume(2.0)
|
|
1019
|
+
* .build();
|
|
1020
|
+
* ```
|
|
1021
|
+
*
|
|
437
1022
|
* @see {@link FilterPresetBase.volume}
|
|
438
1023
|
*/
|
|
439
1024
|
volume(factor) {
|
|
@@ -445,19 +1030,76 @@ export class ChainBuilderBase extends FilterChain {
|
|
|
445
1030
|
* @param sampleFormat - Target sample format
|
|
446
1031
|
* @param sampleRate - Target sample rate (optional)
|
|
447
1032
|
* @param channelLayout - Target channel layout (optional)
|
|
1033
|
+
*
|
|
448
1034
|
* @returns This instance for chaining
|
|
449
1035
|
*
|
|
1036
|
+
* @example
|
|
1037
|
+
* ```typescript
|
|
1038
|
+
* const chain = FilterPresets.chain()
|
|
1039
|
+
* .aformat(AV_SAMPLE_FMT_FLT, 48000, 'stereo')
|
|
1040
|
+
* .build();
|
|
1041
|
+
* ```
|
|
1042
|
+
*
|
|
1043
|
+
* @example
|
|
1044
|
+
* ```typescript
|
|
1045
|
+
* const chain = FilterPresets.chain()
|
|
1046
|
+
* .aformat('s16', 44100)
|
|
1047
|
+
* .build();
|
|
1048
|
+
* ```
|
|
1049
|
+
*
|
|
450
1050
|
* @see {@link FilterPresetBase.aformat}
|
|
451
1051
|
*/
|
|
452
1052
|
aformat(sampleFormat, sampleRate, channelLayout) {
|
|
453
1053
|
return this.add(this.presets.aformat(sampleFormat, sampleRate, channelLayout));
|
|
454
1054
|
}
|
|
1055
|
+
/**
|
|
1056
|
+
* Adds an asetnsamples filter to the chain.
|
|
1057
|
+
*
|
|
1058
|
+
* @param samples - Number of samples per frame
|
|
1059
|
+
* @param padding - Whether to pad or drop samples (default: true)
|
|
1060
|
+
*
|
|
1061
|
+
* @returns This instance for chaining
|
|
1062
|
+
*
|
|
1063
|
+
* @example
|
|
1064
|
+
* ```typescript
|
|
1065
|
+
* const chain = FilterPresets.chain()
|
|
1066
|
+
* .asetnsamples(960)
|
|
1067
|
+
* .build();
|
|
1068
|
+
* ```
|
|
1069
|
+
*
|
|
1070
|
+
* @example
|
|
1071
|
+
* ```typescript
|
|
1072
|
+
* const chain = FilterPresets.chain()
|
|
1073
|
+
* .asetnsamples(1024, false)
|
|
1074
|
+
* .build();
|
|
1075
|
+
* ```
|
|
1076
|
+
*
|
|
1077
|
+
* @see {@link FilterPresetBase.asetnsamples}
|
|
1078
|
+
*/
|
|
1079
|
+
asetnsamples(samples, padding = true) {
|
|
1080
|
+
return this.add(this.presets.asetnsamples(samples, padding));
|
|
1081
|
+
}
|
|
455
1082
|
/**
|
|
456
1083
|
* Adds an atempo filter to the chain.
|
|
457
1084
|
*
|
|
458
1085
|
* @param factor - Tempo factor (0.5 to 2.0)
|
|
1086
|
+
*
|
|
459
1087
|
* @returns This instance for chaining
|
|
460
1088
|
*
|
|
1089
|
+
* @example
|
|
1090
|
+
* ```typescript
|
|
1091
|
+
* const chain = FilterPresets.chain()
|
|
1092
|
+
* .atempo(1.5)
|
|
1093
|
+
* .build();
|
|
1094
|
+
* ```
|
|
1095
|
+
*
|
|
1096
|
+
* @example
|
|
1097
|
+
* ```typescript
|
|
1098
|
+
* const chain = FilterPresets.chain()
|
|
1099
|
+
* .atempo(0.8)
|
|
1100
|
+
* .build();
|
|
1101
|
+
* ```
|
|
1102
|
+
*
|
|
461
1103
|
* @see {@link FilterPresetBase.atempo}
|
|
462
1104
|
*/
|
|
463
1105
|
atempo(factor) {
|
|
@@ -469,8 +1111,23 @@ export class ChainBuilderBase extends FilterChain {
|
|
|
469
1111
|
* @param type - Fade type ('in' or 'out')
|
|
470
1112
|
* @param start - Start time in seconds
|
|
471
1113
|
* @param duration - Fade duration in seconds
|
|
1114
|
+
*
|
|
472
1115
|
* @returns This instance for chaining
|
|
473
1116
|
*
|
|
1117
|
+
* @example
|
|
1118
|
+
* ```typescript
|
|
1119
|
+
* const chain = FilterPresets.chain()
|
|
1120
|
+
* .afade('in', 0, 3)
|
|
1121
|
+
* .build();
|
|
1122
|
+
* ```
|
|
1123
|
+
*
|
|
1124
|
+
* @example
|
|
1125
|
+
* ```typescript
|
|
1126
|
+
* const chain = FilterPresets.chain()
|
|
1127
|
+
* .afade('out', 25, 2)
|
|
1128
|
+
* .build();
|
|
1129
|
+
* ```
|
|
1130
|
+
*
|
|
474
1131
|
* @see {@link FilterPresetBase.afade}
|
|
475
1132
|
*/
|
|
476
1133
|
afade(type, start, duration) {
|
|
@@ -481,24 +1138,323 @@ export class ChainBuilderBase extends FilterChain {
|
|
|
481
1138
|
*
|
|
482
1139
|
* @param inputs - Number of inputs (default: 2)
|
|
483
1140
|
* @param duration - Duration mode (default: 'longest')
|
|
1141
|
+
*
|
|
484
1142
|
* @returns This instance for chaining
|
|
485
1143
|
*
|
|
1144
|
+
* @example
|
|
1145
|
+
* ```typescript
|
|
1146
|
+
* const chain = FilterPresets.chain()
|
|
1147
|
+
* .amix(3, 'longest')
|
|
1148
|
+
* .build();
|
|
1149
|
+
* ```
|
|
1150
|
+
*
|
|
1151
|
+
* @example
|
|
1152
|
+
* ```typescript
|
|
1153
|
+
* const chain = FilterPresets.chain()
|
|
1154
|
+
* .amix(2, 'first')
|
|
1155
|
+
* .build();
|
|
1156
|
+
* ```
|
|
1157
|
+
*
|
|
486
1158
|
* @see {@link FilterPresetBase.amix}
|
|
487
1159
|
*/
|
|
488
1160
|
amix(inputs = 2, duration = 'longest') {
|
|
489
1161
|
return this.add(this.presets.amix(inputs, duration));
|
|
490
1162
|
}
|
|
1163
|
+
// ========== New Critical Filter Chain Methods ==========
|
|
1164
|
+
/**
|
|
1165
|
+
* Adds a pad filter to the chain.
|
|
1166
|
+
*
|
|
1167
|
+
* @param width - Target width
|
|
1168
|
+
* @param height - Target height
|
|
1169
|
+
* @param x - X position of input
|
|
1170
|
+
* @param y - Y position of input
|
|
1171
|
+
* @param color - Padding color
|
|
1172
|
+
*
|
|
1173
|
+
* @returns This instance for chaining
|
|
1174
|
+
*
|
|
1175
|
+
* @example
|
|
1176
|
+
* ```typescript
|
|
1177
|
+
* chain.pad('iw*2', 'ih*2') // Double the canvas size
|
|
1178
|
+
* ```
|
|
1179
|
+
*
|
|
1180
|
+
* @see {@link FilterPresetBase.pad}
|
|
1181
|
+
*/
|
|
1182
|
+
pad(width, height, x, y, color = 'black') {
|
|
1183
|
+
return this.add(this.presets.pad(width, height, x, y, color));
|
|
1184
|
+
}
|
|
1185
|
+
/**
|
|
1186
|
+
* Adds a trim filter to the chain.
|
|
1187
|
+
*
|
|
1188
|
+
* @param start - Start time in seconds
|
|
1189
|
+
* @param end - End time in seconds
|
|
1190
|
+
* @param duration - Duration in seconds
|
|
1191
|
+
*
|
|
1192
|
+
* @returns This instance for chaining
|
|
1193
|
+
*
|
|
1194
|
+
* @example
|
|
1195
|
+
* ```typescript
|
|
1196
|
+
* chain.trim(10, 20) // Extract 10 seconds from t=10 to t=20
|
|
1197
|
+
* ```
|
|
1198
|
+
*
|
|
1199
|
+
* @see {@link FilterPresetBase.trim}
|
|
1200
|
+
*/
|
|
1201
|
+
trim(start, end, duration) {
|
|
1202
|
+
return this.add(this.presets.trim(start, end, duration));
|
|
1203
|
+
}
|
|
1204
|
+
/**
|
|
1205
|
+
* Adds a setpts filter to the chain.
|
|
1206
|
+
*
|
|
1207
|
+
* @param expression - PTS expression
|
|
1208
|
+
*
|
|
1209
|
+
* @returns This instance for chaining
|
|
1210
|
+
*
|
|
1211
|
+
* @example
|
|
1212
|
+
* ```typescript
|
|
1213
|
+
* chain.setpts('PTS/2') // Double playback speed
|
|
1214
|
+
* ```
|
|
1215
|
+
*
|
|
1216
|
+
* @see {@link FilterPresetBase.setpts}
|
|
1217
|
+
*/
|
|
1218
|
+
setpts(expression) {
|
|
1219
|
+
return this.add(this.presets.setpts(expression));
|
|
1220
|
+
}
|
|
1221
|
+
/**
|
|
1222
|
+
* Adds an asetpts filter to the chain.
|
|
1223
|
+
*
|
|
1224
|
+
* @param expression - PTS expression
|
|
1225
|
+
*
|
|
1226
|
+
* @returns This instance for chaining
|
|
1227
|
+
*
|
|
1228
|
+
* @example
|
|
1229
|
+
* ```typescript
|
|
1230
|
+
* chain.asetpts('PTS-STARTPTS') // Reset audio timestamps
|
|
1231
|
+
* ```
|
|
1232
|
+
*
|
|
1233
|
+
* @see {@link FilterPresetBase.asetpts}
|
|
1234
|
+
*/
|
|
1235
|
+
asetpts(expression) {
|
|
1236
|
+
return this.add(this.presets.asetpts(expression));
|
|
1237
|
+
}
|
|
1238
|
+
/**
|
|
1239
|
+
* Adds a setsar filter to the chain.
|
|
1240
|
+
*
|
|
1241
|
+
* @param ratio - Sample aspect ratio
|
|
1242
|
+
*
|
|
1243
|
+
* @returns This instance for chaining
|
|
1244
|
+
*
|
|
1245
|
+
* @example
|
|
1246
|
+
* ```typescript
|
|
1247
|
+
* chain.setsar('1:1') // Square pixels
|
|
1248
|
+
* ```
|
|
1249
|
+
*
|
|
1250
|
+
* @see {@link FilterPresetBase.setsar}
|
|
1251
|
+
*/
|
|
1252
|
+
setsar(ratio) {
|
|
1253
|
+
return this.add(this.presets.setsar(ratio));
|
|
1254
|
+
}
|
|
1255
|
+
/**
|
|
1256
|
+
* Adds a setdar filter to the chain.
|
|
1257
|
+
*
|
|
1258
|
+
* @param ratio - Display aspect ratio
|
|
1259
|
+
*
|
|
1260
|
+
* @returns This instance for chaining
|
|
1261
|
+
*
|
|
1262
|
+
* @example
|
|
1263
|
+
* ```typescript
|
|
1264
|
+
* chain.setdar('16:9') // Set widescreen aspect
|
|
1265
|
+
* ```
|
|
1266
|
+
*
|
|
1267
|
+
* @see {@link FilterPresetBase.setdar}
|
|
1268
|
+
*/
|
|
1269
|
+
setdar(ratio) {
|
|
1270
|
+
return this.add(this.presets.setdar(ratio));
|
|
1271
|
+
}
|
|
1272
|
+
/**
|
|
1273
|
+
* Adds an apad filter to the chain.
|
|
1274
|
+
*
|
|
1275
|
+
* @param wholeDuration - Minimum total duration
|
|
1276
|
+
* @param padDuration - Padding duration to add
|
|
1277
|
+
*
|
|
1278
|
+
* @returns This instance for chaining
|
|
1279
|
+
*
|
|
1280
|
+
* @example
|
|
1281
|
+
* ```typescript
|
|
1282
|
+
* chain.apad(10) // Ensure at least 10 seconds of audio
|
|
1283
|
+
* ```
|
|
1284
|
+
*
|
|
1285
|
+
* @see {@link FilterPresetBase.apad}
|
|
1286
|
+
*/
|
|
1287
|
+
apad(wholeDuration, padDuration) {
|
|
1288
|
+
return this.add(this.presets.apad(wholeDuration, padDuration));
|
|
1289
|
+
}
|
|
1290
|
+
/**
|
|
1291
|
+
* Adds a select filter to the chain.
|
|
1292
|
+
*
|
|
1293
|
+
* @param expression - Selection expression
|
|
1294
|
+
*
|
|
1295
|
+
* @returns This instance for chaining
|
|
1296
|
+
*
|
|
1297
|
+
* @example
|
|
1298
|
+
* ```typescript
|
|
1299
|
+
* chain.select('eq(pict_type,I)') // Select only I-frames
|
|
1300
|
+
* ```
|
|
1301
|
+
*
|
|
1302
|
+
* @see {@link FilterPresetBase.select}
|
|
1303
|
+
*/
|
|
1304
|
+
select(expression) {
|
|
1305
|
+
return this.add(this.presets.select(expression));
|
|
1306
|
+
}
|
|
1307
|
+
/**
|
|
1308
|
+
* Adds an aselect filter to the chain.
|
|
1309
|
+
*
|
|
1310
|
+
* @param expression - Selection expression
|
|
1311
|
+
*
|
|
1312
|
+
* @returns This instance for chaining
|
|
1313
|
+
*
|
|
1314
|
+
* @example
|
|
1315
|
+
* ```typescript
|
|
1316
|
+
* chain.aselect('between(t,10,20)') // Select audio between 10-20s
|
|
1317
|
+
* ```
|
|
1318
|
+
*
|
|
1319
|
+
* @see {@link FilterPresetBase.aselect}
|
|
1320
|
+
*/
|
|
1321
|
+
aselect(expression) {
|
|
1322
|
+
return this.add(this.presets.aselect(expression));
|
|
1323
|
+
}
|
|
1324
|
+
/**
|
|
1325
|
+
* Adds a concat filter to the chain.
|
|
1326
|
+
*
|
|
1327
|
+
* @param n - Number of input segments
|
|
1328
|
+
* @param v - Number of video streams
|
|
1329
|
+
* @param a - Number of audio streams
|
|
1330
|
+
*
|
|
1331
|
+
* @returns This instance for chaining
|
|
1332
|
+
*
|
|
1333
|
+
* @example
|
|
1334
|
+
* ```typescript
|
|
1335
|
+
* chain.concat(3, 1, 1) // Concatenate 3 segments with video and audio
|
|
1336
|
+
* ```
|
|
1337
|
+
*
|
|
1338
|
+
* @see {@link FilterPresetBase.concat}
|
|
1339
|
+
*/
|
|
1340
|
+
concat(n, v = 1, a = 1) {
|
|
1341
|
+
return this.add(this.presets.concat(n, v, a));
|
|
1342
|
+
}
|
|
1343
|
+
/**
|
|
1344
|
+
* Adds an amerge filter to the chain.
|
|
1345
|
+
*
|
|
1346
|
+
* @param inputs - Number of input streams
|
|
1347
|
+
*
|
|
1348
|
+
* @returns This instance for chaining
|
|
1349
|
+
*
|
|
1350
|
+
* @example
|
|
1351
|
+
* ```typescript
|
|
1352
|
+
* chain.amerge(2) // Merge 2 audio streams
|
|
1353
|
+
* ```
|
|
1354
|
+
*
|
|
1355
|
+
* @see {@link FilterPresetBase.amerge}
|
|
1356
|
+
*/
|
|
1357
|
+
amerge(inputs = 2) {
|
|
1358
|
+
return this.add(this.presets.amerge(inputs));
|
|
1359
|
+
}
|
|
1360
|
+
/**
|
|
1361
|
+
* Adds a channelmap filter to the chain.
|
|
1362
|
+
*
|
|
1363
|
+
* @param map - Channel mapping string
|
|
1364
|
+
*
|
|
1365
|
+
* @returns This instance for chaining
|
|
1366
|
+
*
|
|
1367
|
+
* @example
|
|
1368
|
+
* ```typescript
|
|
1369
|
+
* chain.channelmap('FL-FR|FR-FL') // Swap stereo channels
|
|
1370
|
+
* ```
|
|
1371
|
+
*
|
|
1372
|
+
* @see {@link FilterPresetBase.channelmap}
|
|
1373
|
+
*/
|
|
1374
|
+
channelmap(map) {
|
|
1375
|
+
return this.add(this.presets.channelmap(map));
|
|
1376
|
+
}
|
|
1377
|
+
/**
|
|
1378
|
+
* Adds a channelsplit filter to the chain.
|
|
1379
|
+
*
|
|
1380
|
+
* @param channelLayout - Channel layout to split
|
|
1381
|
+
*
|
|
1382
|
+
* @returns This instance for chaining
|
|
1383
|
+
*
|
|
1384
|
+
* @example
|
|
1385
|
+
* ```typescript
|
|
1386
|
+
* chain.channelsplit('stereo') // Split stereo into two mono streams
|
|
1387
|
+
* ```
|
|
1388
|
+
*
|
|
1389
|
+
* @see {@link FilterPresetBase.channelsplit}
|
|
1390
|
+
*/
|
|
1391
|
+
channelsplit(channelLayout) {
|
|
1392
|
+
return this.add(this.presets.channelsplit(channelLayout));
|
|
1393
|
+
}
|
|
1394
|
+
/**
|
|
1395
|
+
* Adds a loudnorm filter to the chain.
|
|
1396
|
+
*
|
|
1397
|
+
* @param I - Integrated loudness target (LUFS)
|
|
1398
|
+
* @param TP - True peak (dBTP)
|
|
1399
|
+
* @param LRA - Loudness range (LU)
|
|
1400
|
+
*
|
|
1401
|
+
* @returns This instance for chaining
|
|
1402
|
+
*
|
|
1403
|
+
* @example
|
|
1404
|
+
* ```typescript
|
|
1405
|
+
* chain.loudnorm(-16, -1.5, 11) // Streaming loudness standard
|
|
1406
|
+
* ```
|
|
1407
|
+
*
|
|
1408
|
+
* @see {@link FilterPresetBase.loudnorm}
|
|
1409
|
+
*/
|
|
1410
|
+
loudnorm(I = -24, TP = -2, LRA = 7) {
|
|
1411
|
+
return this.add(this.presets.loudnorm(I, TP, LRA));
|
|
1412
|
+
}
|
|
1413
|
+
/**
|
|
1414
|
+
* Adds a compand filter to the chain.
|
|
1415
|
+
*
|
|
1416
|
+
* @param attacks - Attack times
|
|
1417
|
+
* @param decays - Decay times
|
|
1418
|
+
* @param points - Transfer function points
|
|
1419
|
+
* @param gain - Output gain
|
|
1420
|
+
*
|
|
1421
|
+
* @returns This instance for chaining
|
|
1422
|
+
*
|
|
1423
|
+
* @example
|
|
1424
|
+
* ```typescript
|
|
1425
|
+
* chain.compand('0.3|0.3', '1|1', '-90/-60|-60/-40|-40/-30|-20/-20', 6)
|
|
1426
|
+
* ```
|
|
1427
|
+
*
|
|
1428
|
+
* @see {@link FilterPresetBase.compand}
|
|
1429
|
+
*/
|
|
1430
|
+
compand(attacks, decays, points, gain) {
|
|
1431
|
+
return this.add(this.presets.compand(attacks, decays, points, gain));
|
|
1432
|
+
}
|
|
491
1433
|
/**
|
|
492
1434
|
* Adds a transpose filter to the chain (hardware-specific).
|
|
493
1435
|
* Only available for hardware presets that support transpose
|
|
494
1436
|
*
|
|
495
|
-
* @param
|
|
1437
|
+
* @param mode - Transpose mode (number or string)
|
|
1438
|
+
*
|
|
496
1439
|
* @returns This instance for chaining
|
|
497
1440
|
*
|
|
1441
|
+
* @example
|
|
1442
|
+
* ```typescript
|
|
1443
|
+
* const chain = FilterPresets.chain()
|
|
1444
|
+
* .transpose('clock')
|
|
1445
|
+
* .build();
|
|
1446
|
+
* ```
|
|
1447
|
+
*
|
|
1448
|
+
* @example
|
|
1449
|
+
* ```typescript
|
|
1450
|
+
* const chain = FilterPresets.chain()
|
|
1451
|
+
* .transpose('cclock_flip')
|
|
1452
|
+
* .build();
|
|
1453
|
+
* ```
|
|
498
1454
|
*/
|
|
499
|
-
transpose(
|
|
1455
|
+
transpose(mode = 0) {
|
|
500
1456
|
if ('transpose' in this.presets) {
|
|
501
|
-
return this.add(this.presets.transpose(
|
|
1457
|
+
return this.add(this.presets.transpose(mode));
|
|
502
1458
|
}
|
|
503
1459
|
return this.add(null);
|
|
504
1460
|
}
|
|
@@ -507,8 +1463,22 @@ export class ChainBuilderBase extends FilterChain {
|
|
|
507
1463
|
* Only available for hardware presets that support tonemapping
|
|
508
1464
|
*
|
|
509
1465
|
* @param options - Tonemapping options
|
|
1466
|
+
*
|
|
510
1467
|
* @returns This instance for chaining
|
|
511
1468
|
*
|
|
1469
|
+
* @example
|
|
1470
|
+
* ```typescript
|
|
1471
|
+
* const chain = FilterPresets.chain()
|
|
1472
|
+
* .tonemap()
|
|
1473
|
+
* .build();
|
|
1474
|
+
* ```
|
|
1475
|
+
*
|
|
1476
|
+
* @example
|
|
1477
|
+
* ```typescript
|
|
1478
|
+
* const chain = FilterPresets.chain()
|
|
1479
|
+
* .tonemap({ tonemap: 'hable', desat: '0' })
|
|
1480
|
+
* .build();
|
|
1481
|
+
* ```
|
|
512
1482
|
*/
|
|
513
1483
|
tonemap(options) {
|
|
514
1484
|
if ('tonemap' in this.presets) {
|
|
@@ -521,8 +1491,22 @@ export class ChainBuilderBase extends FilterChain {
|
|
|
521
1491
|
* Only available for hardware presets that support deinterlacing
|
|
522
1492
|
*
|
|
523
1493
|
* @param mode - Deinterlace mode (optional)
|
|
1494
|
+
*
|
|
524
1495
|
* @returns This instance for chaining
|
|
525
1496
|
*
|
|
1497
|
+
* @example
|
|
1498
|
+
* ```typescript
|
|
1499
|
+
* const chain = FilterPresets.chain()
|
|
1500
|
+
* .deinterlace()
|
|
1501
|
+
* .build();
|
|
1502
|
+
* ```
|
|
1503
|
+
*
|
|
1504
|
+
* @example
|
|
1505
|
+
* ```typescript
|
|
1506
|
+
* const chain = FilterPresets.chain()
|
|
1507
|
+
* .deinterlace('yadif')
|
|
1508
|
+
* .build();
|
|
1509
|
+
* ```
|
|
526
1510
|
*/
|
|
527
1511
|
deinterlace(mode) {
|
|
528
1512
|
if ('deinterlace' in this.presets) {
|
|
@@ -535,8 +1519,22 @@ export class ChainBuilderBase extends FilterChain {
|
|
|
535
1519
|
* Falls back to hflip/vflip if hardware flip not available
|
|
536
1520
|
*
|
|
537
1521
|
* @param direction - Flip direction ('h' or 'v')
|
|
1522
|
+
*
|
|
538
1523
|
* @returns This instance for chaining
|
|
539
1524
|
*
|
|
1525
|
+
* @example
|
|
1526
|
+
* ```typescript
|
|
1527
|
+
* const chain = FilterPresets.chain()
|
|
1528
|
+
* .flip('h')
|
|
1529
|
+
* .build();
|
|
1530
|
+
* ```
|
|
1531
|
+
*
|
|
1532
|
+
* @example
|
|
1533
|
+
* ```typescript
|
|
1534
|
+
* const chain = FilterPresets.chain()
|
|
1535
|
+
* .flip('v')
|
|
1536
|
+
* .build();
|
|
1537
|
+
* ```
|
|
540
1538
|
*/
|
|
541
1539
|
flip(direction) {
|
|
542
1540
|
if ('flip' in this.presets) {
|
|
@@ -551,8 +1549,22 @@ export class ChainBuilderBase extends FilterChain {
|
|
|
551
1549
|
*
|
|
552
1550
|
* @param type - Blur type (default: 'avg')
|
|
553
1551
|
* @param radius - Blur radius (optional)
|
|
1552
|
+
*
|
|
554
1553
|
* @returns This instance for chaining
|
|
555
1554
|
*
|
|
1555
|
+
* @example
|
|
1556
|
+
* ```typescript
|
|
1557
|
+
* const chain = FilterPresets.chain()
|
|
1558
|
+
* .blur('gaussian', 5)
|
|
1559
|
+
* .build();
|
|
1560
|
+
* ```
|
|
1561
|
+
*
|
|
1562
|
+
* @example
|
|
1563
|
+
* ```typescript
|
|
1564
|
+
* const chain = FilterPresets.chain()
|
|
1565
|
+
* .blur('box')
|
|
1566
|
+
* .build();
|
|
1567
|
+
* ```
|
|
556
1568
|
*/
|
|
557
1569
|
blur(type = 'avg', radius) {
|
|
558
1570
|
if ('blur' in this.presets) {
|
|
@@ -565,8 +1577,22 @@ export class ChainBuilderBase extends FilterChain {
|
|
|
565
1577
|
* Only available for hardware presets that support sharpening
|
|
566
1578
|
*
|
|
567
1579
|
* @param amount - Sharpen amount (optional)
|
|
1580
|
+
*
|
|
568
1581
|
* @returns This instance for chaining
|
|
569
1582
|
*
|
|
1583
|
+
* @example
|
|
1584
|
+
* ```typescript
|
|
1585
|
+
* const chain = FilterPresets.chain()
|
|
1586
|
+
* .sharpen(1.5)
|
|
1587
|
+
* .build();
|
|
1588
|
+
* ```
|
|
1589
|
+
*
|
|
1590
|
+
* @example
|
|
1591
|
+
* ```typescript
|
|
1592
|
+
* const chain = FilterPresets.chain()
|
|
1593
|
+
* .sharpen()
|
|
1594
|
+
* .build();
|
|
1595
|
+
* ```
|
|
570
1596
|
*/
|
|
571
1597
|
sharpen(amount) {
|
|
572
1598
|
if ('sharpen' in this.presets) {
|
|
@@ -580,8 +1606,22 @@ export class ChainBuilderBase extends FilterChain {
|
|
|
580
1606
|
*
|
|
581
1607
|
* @param type - Stack type ('h' for horizontal, 'v' for vertical, 'x' for grid)
|
|
582
1608
|
* @param inputs - Number of inputs (default: 2)
|
|
1609
|
+
*
|
|
583
1610
|
* @returns This instance for chaining
|
|
584
1611
|
*
|
|
1612
|
+
* @example
|
|
1613
|
+
* ```typescript
|
|
1614
|
+
* const chain = FilterPresets.chain()
|
|
1615
|
+
* .stack('h', 2)
|
|
1616
|
+
* .build();
|
|
1617
|
+
* ```
|
|
1618
|
+
*
|
|
1619
|
+
* @example
|
|
1620
|
+
* ```typescript
|
|
1621
|
+
* const chain = FilterPresets.chain()
|
|
1622
|
+
* .stack('x', 4)
|
|
1623
|
+
* .build();
|
|
1624
|
+
* ```
|
|
585
1625
|
*/
|
|
586
1626
|
stack(type, inputs = 2) {
|
|
587
1627
|
if ('stack' in this.presets) {
|
|
@@ -593,6 +1633,14 @@ export class ChainBuilderBase extends FilterChain {
|
|
|
593
1633
|
* Adds a hwupload filter to upload frames to hardware.
|
|
594
1634
|
*
|
|
595
1635
|
* @returns This instance for chaining
|
|
1636
|
+
*
|
|
1637
|
+
* @example
|
|
1638
|
+
* ```typescript
|
|
1639
|
+
* const chain = FilterPresets.chain()
|
|
1640
|
+
* .hwupload()
|
|
1641
|
+
* .scale(1920, 1080)
|
|
1642
|
+
* .build();
|
|
1643
|
+
* ```
|
|
596
1644
|
*/
|
|
597
1645
|
hwupload() {
|
|
598
1646
|
if ('hwupload' in this.presets) {
|
|
@@ -604,6 +1652,14 @@ export class ChainBuilderBase extends FilterChain {
|
|
|
604
1652
|
* Adds a hwdownload filter to download frames from hardware.
|
|
605
1653
|
*
|
|
606
1654
|
* @returns This instance for chaining
|
|
1655
|
+
*
|
|
1656
|
+
* @example
|
|
1657
|
+
* ```typescript
|
|
1658
|
+
* const chain = FilterPresets.chain()
|
|
1659
|
+
* .scale(1920, 1080)
|
|
1660
|
+
* .hwdownload()
|
|
1661
|
+
* .build();
|
|
1662
|
+
* ```
|
|
607
1663
|
*/
|
|
608
1664
|
hwdownload() {
|
|
609
1665
|
if ('hwdownload' in this.presets) {
|
|
@@ -615,7 +1671,22 @@ export class ChainBuilderBase extends FilterChain {
|
|
|
615
1671
|
* Adds a hwmap filter to map frames between hardware devices.
|
|
616
1672
|
*
|
|
617
1673
|
* @param derive - Device to derive from (optional)
|
|
1674
|
+
*
|
|
618
1675
|
* @returns This instance for chaining
|
|
1676
|
+
*
|
|
1677
|
+
* @example
|
|
1678
|
+
* ```typescript
|
|
1679
|
+
* const chain = FilterPresets.chain()
|
|
1680
|
+
* .hwmap('cuda')
|
|
1681
|
+
* .build();
|
|
1682
|
+
* ```
|
|
1683
|
+
*
|
|
1684
|
+
* @example
|
|
1685
|
+
* ```typescript
|
|
1686
|
+
* const chain = FilterPresets.chain()
|
|
1687
|
+
* .hwmap()
|
|
1688
|
+
* .build();
|
|
1689
|
+
* ```
|
|
619
1690
|
*/
|
|
620
1691
|
hwmap(derive) {
|
|
621
1692
|
if ('hwmap' in this.presets) {
|
|
@@ -683,7 +1754,18 @@ export class FilterPresets extends FilterPresetBase {
|
|
|
683
1754
|
* @param width - Target width
|
|
684
1755
|
* @param height - Target height
|
|
685
1756
|
* @param flags - Scaling algorithm flags (optional)
|
|
1757
|
+
*
|
|
686
1758
|
* @returns Scale filter string
|
|
1759
|
+
*
|
|
1760
|
+
* @example
|
|
1761
|
+
* ```typescript
|
|
1762
|
+
* const filter = FilterPresets.scale(1920, 1080);
|
|
1763
|
+
* ```
|
|
1764
|
+
*
|
|
1765
|
+
* @example
|
|
1766
|
+
* ```typescript
|
|
1767
|
+
* const filter = FilterPresets.scale(1280, 720, 'lanczos');
|
|
1768
|
+
* ```
|
|
687
1769
|
*/
|
|
688
1770
|
static scale(width, height, flags) {
|
|
689
1771
|
const result = FilterPresets.instance.scale(width, height, { flags });
|
|
@@ -696,7 +1778,18 @@ export class FilterPresets extends FilterPresetBase {
|
|
|
696
1778
|
* @param height - Crop height
|
|
697
1779
|
* @param x - X position (default: 0)
|
|
698
1780
|
* @param y - Y position (default: 0)
|
|
1781
|
+
*
|
|
699
1782
|
* @returns Crop filter string
|
|
1783
|
+
*
|
|
1784
|
+
* @example
|
|
1785
|
+
* ```typescript
|
|
1786
|
+
* const filter = FilterPresets.crop(640, 480);
|
|
1787
|
+
* ```
|
|
1788
|
+
*
|
|
1789
|
+
* @example
|
|
1790
|
+
* ```typescript
|
|
1791
|
+
* const filter = FilterPresets.crop(1920, 1080, 100, 50);
|
|
1792
|
+
* ```
|
|
700
1793
|
*/
|
|
701
1794
|
static crop(width, height, x = 0, y = 0) {
|
|
702
1795
|
const result = FilterPresets.instance.crop(width, height, x, y);
|
|
@@ -706,7 +1799,18 @@ export class FilterPresets extends FilterPresetBase {
|
|
|
706
1799
|
* Creates an FPS filter string.
|
|
707
1800
|
*
|
|
708
1801
|
* @param fps - Target frame rate
|
|
1802
|
+
*
|
|
709
1803
|
* @returns FPS filter string
|
|
1804
|
+
*
|
|
1805
|
+
* @example
|
|
1806
|
+
* ```typescript
|
|
1807
|
+
* const filter = FilterPresets.fps(30);
|
|
1808
|
+
* ```
|
|
1809
|
+
*
|
|
1810
|
+
* @example
|
|
1811
|
+
* ```typescript
|
|
1812
|
+
* const filter = FilterPresets.fps(23.976);
|
|
1813
|
+
* ```
|
|
710
1814
|
*/
|
|
711
1815
|
static fps(fps) {
|
|
712
1816
|
const result = FilterPresets.instance.fps(fps);
|
|
@@ -716,7 +1820,18 @@ export class FilterPresets extends FilterPresetBase {
|
|
|
716
1820
|
* Creates a format filter string.
|
|
717
1821
|
*
|
|
718
1822
|
* @param pixelFormat - Target pixel format(s)
|
|
1823
|
+
*
|
|
719
1824
|
* @returns Format filter string
|
|
1825
|
+
*
|
|
1826
|
+
* @example
|
|
1827
|
+
* ```typescript
|
|
1828
|
+
* const filter = FilterPresets.format('yuv420p');
|
|
1829
|
+
* ```
|
|
1830
|
+
*
|
|
1831
|
+
* @example
|
|
1832
|
+
* ```typescript
|
|
1833
|
+
* const filter = FilterPresets.format(AV_PIX_FMT_RGB24);
|
|
1834
|
+
* ```
|
|
720
1835
|
*/
|
|
721
1836
|
static format(pixelFormat) {
|
|
722
1837
|
const result = FilterPresets.instance.format(pixelFormat);
|
|
@@ -726,7 +1841,18 @@ export class FilterPresets extends FilterPresetBase {
|
|
|
726
1841
|
* Creates a rotate filter string.
|
|
727
1842
|
*
|
|
728
1843
|
* @param angle - Rotation angle in degrees
|
|
1844
|
+
*
|
|
729
1845
|
* @returns Rotate filter string
|
|
1846
|
+
*
|
|
1847
|
+
* @example
|
|
1848
|
+
* ```typescript
|
|
1849
|
+
* const filter = FilterPresets.rotate(45);
|
|
1850
|
+
* ```
|
|
1851
|
+
*
|
|
1852
|
+
* @example
|
|
1853
|
+
* ```typescript
|
|
1854
|
+
* const filter = FilterPresets.rotate(-90);
|
|
1855
|
+
* ```
|
|
730
1856
|
*/
|
|
731
1857
|
static rotate(angle) {
|
|
732
1858
|
const result = FilterPresets.instance.rotate(angle);
|
|
@@ -736,6 +1862,11 @@ export class FilterPresets extends FilterPresetBase {
|
|
|
736
1862
|
* Creates a horizontal flip filter string.
|
|
737
1863
|
*
|
|
738
1864
|
* @returns Horizontal flip filter string
|
|
1865
|
+
*
|
|
1866
|
+
* @example
|
|
1867
|
+
* ```typescript
|
|
1868
|
+
* const filter = FilterPresets.hflip();
|
|
1869
|
+
* ```
|
|
739
1870
|
*/
|
|
740
1871
|
static hflip() {
|
|
741
1872
|
const result = FilterPresets.instance.hflip();
|
|
@@ -745,6 +1876,11 @@ export class FilterPresets extends FilterPresetBase {
|
|
|
745
1876
|
* Creates a vertical flip filter string.
|
|
746
1877
|
*
|
|
747
1878
|
* @returns Vertical flip filter string
|
|
1879
|
+
*
|
|
1880
|
+
* @example
|
|
1881
|
+
* ```typescript
|
|
1882
|
+
* const filter = FilterPresets.vflip();
|
|
1883
|
+
* ```
|
|
748
1884
|
*/
|
|
749
1885
|
static vflip() {
|
|
750
1886
|
const result = FilterPresets.instance.vflip();
|
|
@@ -756,7 +1892,18 @@ export class FilterPresets extends FilterPresetBase {
|
|
|
756
1892
|
* @param type - Fade type ('in' or 'out')
|
|
757
1893
|
* @param start - Start time in seconds
|
|
758
1894
|
* @param duration - Fade duration in seconds
|
|
1895
|
+
*
|
|
759
1896
|
* @returns Fade filter string
|
|
1897
|
+
*
|
|
1898
|
+
* @example
|
|
1899
|
+
* ```typescript
|
|
1900
|
+
* const filter = FilterPresets.fade('in', 0, 2);
|
|
1901
|
+
* ```
|
|
1902
|
+
*
|
|
1903
|
+
* @example
|
|
1904
|
+
* ```typescript
|
|
1905
|
+
* const filter = FilterPresets.fade('out', 10, 1.5);
|
|
1906
|
+
* ```
|
|
760
1907
|
*/
|
|
761
1908
|
static fade(type, start, duration) {
|
|
762
1909
|
const result = FilterPresets.instance.fade(type, start, duration);
|
|
@@ -767,7 +1914,18 @@ export class FilterPresets extends FilterPresetBase {
|
|
|
767
1914
|
*
|
|
768
1915
|
* @param x - X position (default: 0)
|
|
769
1916
|
* @param y - Y position (default: 0)
|
|
1917
|
+
*
|
|
770
1918
|
* @returns Overlay filter string
|
|
1919
|
+
*
|
|
1920
|
+
* @example
|
|
1921
|
+
* ```typescript
|
|
1922
|
+
* const filter = FilterPresets.overlay(100, 50);
|
|
1923
|
+
* ```
|
|
1924
|
+
*
|
|
1925
|
+
* @example
|
|
1926
|
+
* ```typescript
|
|
1927
|
+
* const filter = FilterPresets.overlay();
|
|
1928
|
+
* ```
|
|
771
1929
|
*/
|
|
772
1930
|
static overlay(x = 0, y = 0) {
|
|
773
1931
|
const result = FilterPresets.instance.overlay(x, y);
|
|
@@ -777,7 +1935,18 @@ export class FilterPresets extends FilterPresetBase {
|
|
|
777
1935
|
* Creates a volume filter string.
|
|
778
1936
|
*
|
|
779
1937
|
* @param factor - Volume multiplication factor
|
|
1938
|
+
*
|
|
780
1939
|
* @returns Volume filter string
|
|
1940
|
+
*
|
|
1941
|
+
* @example
|
|
1942
|
+
* ```typescript
|
|
1943
|
+
* const filter = FilterPresets.volume(0.5);
|
|
1944
|
+
* ```
|
|
1945
|
+
*
|
|
1946
|
+
* @example
|
|
1947
|
+
* ```typescript
|
|
1948
|
+
* const filter = FilterPresets.volume(2.0);
|
|
1949
|
+
* ```
|
|
781
1950
|
*/
|
|
782
1951
|
static volume(factor) {
|
|
783
1952
|
const result = FilterPresets.instance.volume(factor);
|
|
@@ -789,17 +1958,61 @@ export class FilterPresets extends FilterPresetBase {
|
|
|
789
1958
|
* @param sampleFormat - Target sample format
|
|
790
1959
|
* @param sampleRate - Target sample rate (optional)
|
|
791
1960
|
* @param channelLayout - Target channel layout (optional)
|
|
1961
|
+
*
|
|
792
1962
|
* @returns Audio format filter string
|
|
1963
|
+
*
|
|
1964
|
+
* @example
|
|
1965
|
+
* ```typescript
|
|
1966
|
+
* const filter = FilterPresets.aformat(AV_SAMPLE_FMT_FLT, 48000, 'stereo');
|
|
1967
|
+
* ```
|
|
1968
|
+
*
|
|
1969
|
+
* @example
|
|
1970
|
+
* ```typescript
|
|
1971
|
+
* const filter = FilterPresets.aformat('s16', 44100);
|
|
1972
|
+
* ```
|
|
793
1973
|
*/
|
|
794
1974
|
static aformat(sampleFormat, sampleRate, channelLayout) {
|
|
795
1975
|
const result = FilterPresets.instance.aformat(sampleFormat, sampleRate, channelLayout);
|
|
796
1976
|
return result ?? '';
|
|
797
1977
|
}
|
|
1978
|
+
/**
|
|
1979
|
+
* Creates an asetnsamples filter string.
|
|
1980
|
+
*
|
|
1981
|
+
* @param samples - Number of samples per frame
|
|
1982
|
+
* @param padding - Whether to pad or drop samples (default: true)
|
|
1983
|
+
*
|
|
1984
|
+
* @returns Asetnsamples filter string
|
|
1985
|
+
*
|
|
1986
|
+
* @example
|
|
1987
|
+
* ```typescript
|
|
1988
|
+
* const filter = FilterPresets.asetnsamples(960);
|
|
1989
|
+
* ```
|
|
1990
|
+
*
|
|
1991
|
+
* @example
|
|
1992
|
+
* ```typescript
|
|
1993
|
+
* const filter = FilterPresets.asetnsamples(1024, false);
|
|
1994
|
+
* ```
|
|
1995
|
+
*/
|
|
1996
|
+
static asetnsamples(samples, padding = true) {
|
|
1997
|
+
const result = FilterPresets.instance.asetnsamples(samples, padding);
|
|
1998
|
+
return result ?? '';
|
|
1999
|
+
}
|
|
798
2000
|
/**
|
|
799
2001
|
* Creates an atempo filter string.
|
|
800
2002
|
*
|
|
801
2003
|
* @param factor - Tempo factor (0.5 to 2.0)
|
|
2004
|
+
*
|
|
802
2005
|
* @returns Atempo filter string
|
|
2006
|
+
*
|
|
2007
|
+
* @example
|
|
2008
|
+
* ```typescript
|
|
2009
|
+
* const filter = FilterPresets.atempo(1.5);
|
|
2010
|
+
* ```
|
|
2011
|
+
*
|
|
2012
|
+
* @example
|
|
2013
|
+
* ```typescript
|
|
2014
|
+
* const filter = FilterPresets.atempo(0.8);
|
|
2015
|
+
* ```
|
|
803
2016
|
*/
|
|
804
2017
|
static atempo(factor) {
|
|
805
2018
|
const result = FilterPresets.instance.atempo(factor);
|
|
@@ -811,7 +2024,18 @@ export class FilterPresets extends FilterPresetBase {
|
|
|
811
2024
|
* @param type - Fade type ('in' or 'out')
|
|
812
2025
|
* @param start - Start time in seconds
|
|
813
2026
|
* @param duration - Fade duration in seconds
|
|
2027
|
+
*
|
|
814
2028
|
* @returns Audio fade filter string
|
|
2029
|
+
*
|
|
2030
|
+
* @example
|
|
2031
|
+
* ```typescript
|
|
2032
|
+
* const filter = FilterPresets.afade('in', 0, 3);
|
|
2033
|
+
* ```
|
|
2034
|
+
*
|
|
2035
|
+
* @example
|
|
2036
|
+
* ```typescript
|
|
2037
|
+
* const filter = FilterPresets.afade('out', 25, 2);
|
|
2038
|
+
* ```
|
|
815
2039
|
*/
|
|
816
2040
|
static afade(type, start, duration) {
|
|
817
2041
|
const result = FilterPresets.instance.afade(type, start, duration);
|
|
@@ -822,7 +2046,18 @@ export class FilterPresets extends FilterPresetBase {
|
|
|
822
2046
|
*
|
|
823
2047
|
* @param inputs - Number of inputs (default: 2)
|
|
824
2048
|
* @param duration - Duration mode (default: 'longest')
|
|
2049
|
+
*
|
|
825
2050
|
* @returns Amix filter string
|
|
2051
|
+
*
|
|
2052
|
+
* @example
|
|
2053
|
+
* ```typescript
|
|
2054
|
+
* const filter = FilterPresets.amix(3, 'longest');
|
|
2055
|
+
* ```
|
|
2056
|
+
*
|
|
2057
|
+
* @example
|
|
2058
|
+
* ```typescript
|
|
2059
|
+
* const filter = FilterPresets.amix(2, 'first');
|
|
2060
|
+
* ```
|
|
826
2061
|
*/
|
|
827
2062
|
static amix(inputs = 2, duration = 'longest') {
|
|
828
2063
|
const result = FilterPresets.instance.amix(inputs, duration);
|
|
@@ -837,7 +2072,7 @@ export class FilterPresets extends FilterPresetBase {
|
|
|
837
2072
|
* @example
|
|
838
2073
|
* ```typescript
|
|
839
2074
|
* // Create hardware presets for CUDA
|
|
840
|
-
* const hw = new HardwareFilterPresets(AV_HWDEVICE_TYPE_CUDA
|
|
2075
|
+
* const hw = new HardwareFilterPresets(AV_HWDEVICE_TYPE_CUDA);
|
|
841
2076
|
*
|
|
842
2077
|
* // Check capabilities
|
|
843
2078
|
* if (hw.support.scale) {
|
|
@@ -859,12 +2094,12 @@ export class HardwareFilterPresets extends FilterPresetBase {
|
|
|
859
2094
|
support;
|
|
860
2095
|
/**
|
|
861
2096
|
* @param deviceType - Hardware device type enum
|
|
862
|
-
* @param deviceTypeName -
|
|
2097
|
+
* @param deviceTypeName - Optional hardware device type name (e.g., 'cuda', 'vaapi')
|
|
863
2098
|
*/
|
|
864
2099
|
constructor(deviceType, deviceTypeName) {
|
|
865
2100
|
super();
|
|
866
2101
|
this.deviceType = deviceType;
|
|
867
|
-
this.deviceTypeName = deviceTypeName;
|
|
2102
|
+
this.deviceTypeName = deviceTypeName ?? HardwareDeviceContext.getTypeName(deviceType);
|
|
868
2103
|
this.support = this.getSupport();
|
|
869
2104
|
}
|
|
870
2105
|
/**
|
|
@@ -918,8 +2153,18 @@ export class HardwareFilterPresets extends FilterPresetBase {
|
|
|
918
2153
|
* @param width - Target width
|
|
919
2154
|
* @param height - Target height
|
|
920
2155
|
* @param options - Hardware-specific scaling options
|
|
2156
|
+
*
|
|
921
2157
|
* @returns Hardware scale filter string or null if not supported
|
|
922
2158
|
*
|
|
2159
|
+
* @example
|
|
2160
|
+
* ```typescript
|
|
2161
|
+
* const filter = hwPresets.scale(1920, 1080);
|
|
2162
|
+
* ```
|
|
2163
|
+
*
|
|
2164
|
+
* @example
|
|
2165
|
+
* ```typescript
|
|
2166
|
+
* const filter = hwPresets.scale(1280, 720, { npp: true });
|
|
2167
|
+
* ```
|
|
923
2168
|
*
|
|
924
2169
|
* @see {@link https://ffmpeg.org/ffmpeg-filters.html#scale_005fcuda | FFmpeg scale_cuda filter}
|
|
925
2170
|
*/
|
|
@@ -958,8 +2203,19 @@ export class HardwareFilterPresets extends FilterPresetBase {
|
|
|
958
2203
|
* @param x - X position (default: 0)
|
|
959
2204
|
* @param y - Y position (default: 0)
|
|
960
2205
|
* @param options - Hardware-specific overlay options
|
|
2206
|
+
*
|
|
961
2207
|
* @returns Hardware overlay filter string or null if not supported
|
|
962
2208
|
*
|
|
2209
|
+
* @example
|
|
2210
|
+
* ```typescript
|
|
2211
|
+
* const filter = hwPresets.overlay(100, 50);
|
|
2212
|
+
* ```
|
|
2213
|
+
*
|
|
2214
|
+
* @example
|
|
2215
|
+
* ```typescript
|
|
2216
|
+
* const filter = hwPresets.overlay(0, 0, { eof_action: 'pass' });
|
|
2217
|
+
* ```
|
|
2218
|
+
*
|
|
963
2219
|
* @see {@link https://ffmpeg.org/ffmpeg-filters.html#overlay_005fcuda | FFmpeg overlay_cuda filter}
|
|
964
2220
|
*/
|
|
965
2221
|
overlay(x = 0, y = 0, options) {
|
|
@@ -981,18 +2237,51 @@ export class HardwareFilterPresets extends FilterPresetBase {
|
|
|
981
2237
|
*
|
|
982
2238
|
* Direction values:
|
|
983
2239
|
* - 0: 90 degrees counter-clockwise and vertical flip
|
|
984
|
-
* - 1: 90 degrees clockwise
|
|
985
|
-
* - 2: 90 degrees counter-clockwise
|
|
986
|
-
* - 3: 90 degrees clockwise and vertical flip
|
|
2240
|
+
* - 1 / 'clock': 90 degrees clockwise
|
|
2241
|
+
* - 2 / 'cclock': 90 degrees counter-clockwise
|
|
2242
|
+
* - 3 / 'clock_flip': 90 degrees clockwise and vertical flip
|
|
2243
|
+
*
|
|
2244
|
+
* @param mode - Transpose mode (number or string)
|
|
987
2245
|
*
|
|
988
|
-
* @param dir - Transpose direction (default: 0)
|
|
989
2246
|
* @returns Hardware transpose filter string or null if not supported
|
|
990
2247
|
*
|
|
2248
|
+
* @example
|
|
2249
|
+
* ```typescript
|
|
2250
|
+
* const filter = hwPresets.transpose('clock');
|
|
2251
|
+
* ```
|
|
2252
|
+
*
|
|
2253
|
+
* @example
|
|
2254
|
+
* ```typescript
|
|
2255
|
+
* const filter = hwPresets.transpose(2);
|
|
2256
|
+
* ```
|
|
991
2257
|
*/
|
|
992
|
-
transpose(
|
|
2258
|
+
transpose(mode) {
|
|
993
2259
|
if (!this.support.transpose) {
|
|
994
2260
|
return null;
|
|
995
2261
|
}
|
|
2262
|
+
// Convert string modes to numbers
|
|
2263
|
+
let dir;
|
|
2264
|
+
if (typeof mode === 'string') {
|
|
2265
|
+
switch (mode) {
|
|
2266
|
+
case 'clock':
|
|
2267
|
+
dir = 1;
|
|
2268
|
+
break;
|
|
2269
|
+
case 'cclock':
|
|
2270
|
+
dir = 2;
|
|
2271
|
+
break;
|
|
2272
|
+
case 'clock_flip':
|
|
2273
|
+
dir = 3;
|
|
2274
|
+
break;
|
|
2275
|
+
case 'cclock_flip':
|
|
2276
|
+
dir = 0;
|
|
2277
|
+
break;
|
|
2278
|
+
default:
|
|
2279
|
+
dir = 0;
|
|
2280
|
+
}
|
|
2281
|
+
}
|
|
2282
|
+
else {
|
|
2283
|
+
dir = mode;
|
|
2284
|
+
}
|
|
996
2285
|
// Special handling for different hardware transpose implementations
|
|
997
2286
|
let filterName;
|
|
998
2287
|
if (this.deviceType === AV_HWDEVICE_TYPE_CUDA) {
|
|
@@ -1011,8 +2300,18 @@ export class HardwareFilterPresets extends FilterPresetBase {
|
|
|
1011
2300
|
* Used for HDR to SDR conversion with hardware acceleration.
|
|
1012
2301
|
*
|
|
1013
2302
|
* @param options - Tonemapping options (algorithm, parameters)
|
|
2303
|
+
*
|
|
1014
2304
|
* @returns Hardware tonemap filter string or null if not supported
|
|
1015
2305
|
*
|
|
2306
|
+
* @example
|
|
2307
|
+
* ```typescript
|
|
2308
|
+
* const filter = hwPresets.tonemap();
|
|
2309
|
+
* ```
|
|
2310
|
+
*
|
|
2311
|
+
* @example
|
|
2312
|
+
* ```typescript
|
|
2313
|
+
* const filter = hwPresets.tonemap({ tonemap: 'hable', desat: '0' });
|
|
2314
|
+
* ```
|
|
1016
2315
|
*/
|
|
1017
2316
|
tonemap(options) {
|
|
1018
2317
|
if (!this.support.tonemap) {
|
|
@@ -1040,8 +2339,18 @@ export class HardwareFilterPresets extends FilterPresetBase {
|
|
|
1040
2339
|
* - VideoToolbox: yadif_videotoolbox
|
|
1041
2340
|
*
|
|
1042
2341
|
* @param mode - Deinterlacing mode (optional)
|
|
2342
|
+
*
|
|
1043
2343
|
* @returns Hardware deinterlace filter string or null if not supported
|
|
1044
2344
|
*
|
|
2345
|
+
* @example
|
|
2346
|
+
* ```typescript
|
|
2347
|
+
* const filter = hwPresets.deinterlace();
|
|
2348
|
+
* ```
|
|
2349
|
+
*
|
|
2350
|
+
* @example
|
|
2351
|
+
* ```typescript
|
|
2352
|
+
* const filter = hwPresets.deinterlace('send_field');
|
|
2353
|
+
* ```
|
|
1045
2354
|
*/
|
|
1046
2355
|
deinterlace(mode) {
|
|
1047
2356
|
if (!this.support.deinterlace) {
|
|
@@ -1067,8 +2376,18 @@ export class HardwareFilterPresets extends FilterPresetBase {
|
|
|
1067
2376
|
* Currently only Vulkan supports hardware flip filters.
|
|
1068
2377
|
*
|
|
1069
2378
|
* @param direction - Flip direction ('h' for horizontal, 'v' for vertical)
|
|
2379
|
+
*
|
|
1070
2380
|
* @returns Hardware flip filter string or null if not supported
|
|
1071
2381
|
*
|
|
2382
|
+
* @example
|
|
2383
|
+
* ```typescript
|
|
2384
|
+
* const filter = hwPresets.flip('h');
|
|
2385
|
+
* ```
|
|
2386
|
+
*
|
|
2387
|
+
* @example
|
|
2388
|
+
* ```typescript
|
|
2389
|
+
* const filter = hwPresets.flip('v');
|
|
2390
|
+
* ```
|
|
1072
2391
|
*/
|
|
1073
2392
|
flip(direction) {
|
|
1074
2393
|
if (!this.support.flip) {
|
|
@@ -1089,8 +2408,18 @@ export class HardwareFilterPresets extends FilterPresetBase {
|
|
|
1089
2408
|
*
|
|
1090
2409
|
* @param type - Blur type ('avg', 'gaussian', or 'box', default: 'avg')
|
|
1091
2410
|
* @param radius - Blur radius (optional)
|
|
2411
|
+
*
|
|
1092
2412
|
* @returns Hardware blur filter string or null if not supported
|
|
1093
2413
|
*
|
|
2414
|
+
* @example
|
|
2415
|
+
* ```typescript
|
|
2416
|
+
* const filter = hwPresets.blur('gaussian', 5);
|
|
2417
|
+
* ```
|
|
2418
|
+
*
|
|
2419
|
+
* @example
|
|
2420
|
+
* ```typescript
|
|
2421
|
+
* const filter = hwPresets.blur('avg');
|
|
2422
|
+
* ```
|
|
1094
2423
|
*/
|
|
1095
2424
|
blur(type = 'avg', radius) {
|
|
1096
2425
|
if (!this.support.blur) {
|
|
@@ -1116,8 +2445,18 @@ export class HardwareFilterPresets extends FilterPresetBase {
|
|
|
1116
2445
|
* - CUDA: sharpen_npp (NPP-based)
|
|
1117
2446
|
*
|
|
1118
2447
|
* @param amount - Sharpening amount (optional)
|
|
2448
|
+
*
|
|
1119
2449
|
* @returns Hardware sharpen filter string or null if not supported
|
|
1120
2450
|
*
|
|
2451
|
+
* @example
|
|
2452
|
+
* ```typescript
|
|
2453
|
+
* const filter = hwPresets.sharpen(1.5);
|
|
2454
|
+
* ```
|
|
2455
|
+
*
|
|
2456
|
+
* @example
|
|
2457
|
+
* ```typescript
|
|
2458
|
+
* const filter = hwPresets.sharpen();
|
|
2459
|
+
* ```
|
|
1121
2460
|
*/
|
|
1122
2461
|
sharpen(amount) {
|
|
1123
2462
|
if (!this.support.sharpen) {
|
|
@@ -1141,8 +2480,18 @@ export class HardwareFilterPresets extends FilterPresetBase {
|
|
|
1141
2480
|
*
|
|
1142
2481
|
* @param type - Stack type ('h' for horizontal, 'v' for vertical, 'x' for grid)
|
|
1143
2482
|
* @param inputs - Number of inputs to stack (default: 2)
|
|
2483
|
+
*
|
|
1144
2484
|
* @returns Hardware stack filter string or null if not supported
|
|
1145
2485
|
*
|
|
2486
|
+
* @example
|
|
2487
|
+
* ```typescript
|
|
2488
|
+
* const filter = hwPresets.stack('h', 2);
|
|
2489
|
+
* ```
|
|
2490
|
+
*
|
|
2491
|
+
* @example
|
|
2492
|
+
* ```typescript
|
|
2493
|
+
* const filter = hwPresets.stack('x', 4);
|
|
2494
|
+
* ```
|
|
1146
2495
|
*/
|
|
1147
2496
|
stack(type, inputs = 2) {
|
|
1148
2497
|
if (!this.support.stack) {
|
|
@@ -1159,6 +2508,11 @@ export class HardwareFilterPresets extends FilterPresetBase {
|
|
|
1159
2508
|
*
|
|
1160
2509
|
* @returns Hardware upload filter string
|
|
1161
2510
|
*
|
|
2511
|
+
* @example
|
|
2512
|
+
* ```typescript
|
|
2513
|
+
* const filter = hwPresets.hwupload();
|
|
2514
|
+
* ```
|
|
2515
|
+
*
|
|
1162
2516
|
* @see {@link https://ffmpeg.org/ffmpeg-filters.html#hwupload | FFmpeg hwupload filter}
|
|
1163
2517
|
*/
|
|
1164
2518
|
hwupload() {
|
|
@@ -1172,6 +2526,11 @@ export class HardwareFilterPresets extends FilterPresetBase {
|
|
|
1172
2526
|
*
|
|
1173
2527
|
* @returns Hardware download filter string
|
|
1174
2528
|
*
|
|
2529
|
+
* @example
|
|
2530
|
+
* ```typescript
|
|
2531
|
+
* const filter = hwPresets.hwdownload();
|
|
2532
|
+
* ```
|
|
2533
|
+
*
|
|
1175
2534
|
* @see {@link https://ffmpeg.org/ffmpeg-filters.html#hwdownload | FFmpeg hwdownload filter}
|
|
1176
2535
|
*/
|
|
1177
2536
|
hwdownload() {
|
|
@@ -1181,8 +2540,19 @@ export class HardwareFilterPresets extends FilterPresetBase {
|
|
|
1181
2540
|
* Creates a hwmap filter to map frames between hardware devices.
|
|
1182
2541
|
*
|
|
1183
2542
|
* @param derive - Device to derive from (optional)
|
|
2543
|
+
*
|
|
1184
2544
|
* @returns Hardware map filter string
|
|
1185
2545
|
*
|
|
2546
|
+
* @example
|
|
2547
|
+
* ```typescript
|
|
2548
|
+
* const filter = hwPresets.hwmap('cuda');
|
|
2549
|
+
* ```
|
|
2550
|
+
*
|
|
2551
|
+
* @example
|
|
2552
|
+
* ```typescript
|
|
2553
|
+
* const filter = hwPresets.hwmap();
|
|
2554
|
+
* ```
|
|
2555
|
+
*
|
|
1186
2556
|
* @see {@link https://ffmpeg.org/ffmpeg-filters.html#hwmap | FFmpeg hwmap filter}
|
|
1187
2557
|
*/
|
|
1188
2558
|
hwmap(derive) {
|