simple-ffmpegjs 0.5.0 → 0.5.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 +31 -1711
- package/package.json +1 -1
- package/types/index.d.mts +207 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "simple-ffmpegjs",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.2",
|
|
4
4
|
"description": "Declarative video composition for Node.js — define clips, transitions, text, and audio as simple objects, and let FFmpeg handle the rest.",
|
|
5
5
|
"author": "Brayden Blackwell <braydenblackwell21@gmail.com> (https://github.com/Fats403)",
|
|
6
6
|
"license": "MIT",
|
package/types/index.d.mts
CHANGED
|
@@ -167,9 +167,9 @@ declare namespace SIMPLEFFMPEG {
|
|
|
167
167
|
|
|
168
168
|
// Font
|
|
169
169
|
fontFile?: string;
|
|
170
|
-
fontFamily?: string;
|
|
171
|
-
fontSize?: number;
|
|
172
|
-
fontColor?: string;
|
|
170
|
+
fontFamily?: string; // defaults to 'Sans' via fontconfig
|
|
171
|
+
fontSize?: number; // default 48
|
|
172
|
+
fontColor?: string; // default '#FFFFFF'
|
|
173
173
|
|
|
174
174
|
// Position (xPercent/yPercent are percentages 0-1, x/y are pixels)
|
|
175
175
|
/** Horizontal position as percentage (0 = left, 0.5 = center, 1 = right) */
|
|
@@ -270,19 +270,24 @@ declare namespace SIMPLEFFMPEG {
|
|
|
270
270
|
| "letterbox";
|
|
271
271
|
|
|
272
272
|
interface EffectParamsBase {
|
|
273
|
+
/** Base blend amount from 0 to 1 (default: 1) */
|
|
273
274
|
amount?: number;
|
|
274
275
|
}
|
|
275
276
|
|
|
276
277
|
interface VignetteEffectParams extends EffectParamsBase {
|
|
278
|
+
/** Vignette angle in radians (default: PI/5) */
|
|
277
279
|
angle?: number;
|
|
278
280
|
}
|
|
279
281
|
|
|
280
282
|
interface FilmGrainEffectParams extends EffectParamsBase {
|
|
283
|
+
/** Noise intensity 0-1 (default: 0.35). Independent from blend amount. */
|
|
281
284
|
strength?: number;
|
|
285
|
+
/** Temporal grain changes every frame (default: true) */
|
|
282
286
|
temporal?: boolean;
|
|
283
287
|
}
|
|
284
288
|
|
|
285
289
|
interface GaussianBlurEffectParams extends EffectParamsBase {
|
|
290
|
+
/** Gaussian blur sigma (default derived from amount) */
|
|
286
291
|
sigma?: number;
|
|
287
292
|
}
|
|
288
293
|
|
|
@@ -296,19 +301,24 @@ declare namespace SIMPLEFFMPEG {
|
|
|
296
301
|
interface SepiaEffectParams extends EffectParamsBase {}
|
|
297
302
|
|
|
298
303
|
interface BlackAndWhiteEffectParams extends EffectParamsBase {
|
|
304
|
+
/** Optional contrast boost (default: 1, range 0-3) */
|
|
299
305
|
contrast?: number;
|
|
300
306
|
}
|
|
301
307
|
|
|
302
308
|
interface SharpenEffectParams extends EffectParamsBase {
|
|
309
|
+
/** Unsharp amount (default: 1.0, range 0-3) */
|
|
303
310
|
strength?: number;
|
|
304
311
|
}
|
|
305
312
|
|
|
306
313
|
interface ChromaticAberrationEffectParams extends EffectParamsBase {
|
|
314
|
+
/** Horizontal pixel offset for R/B channels (default: 4, range 0-20) */
|
|
307
315
|
shift?: number;
|
|
308
316
|
}
|
|
309
317
|
|
|
310
318
|
interface LetterboxEffectParams extends EffectParamsBase {
|
|
319
|
+
/** Bar height as fraction of frame height (default: 0.12, range 0-0.5) */
|
|
311
320
|
size?: number;
|
|
321
|
+
/** Bar color (default: "black") */
|
|
312
322
|
color?: string;
|
|
313
323
|
}
|
|
314
324
|
|
|
@@ -327,11 +337,17 @@ declare namespace SIMPLEFFMPEG {
|
|
|
327
337
|
interface EffectClip {
|
|
328
338
|
type: "effect";
|
|
329
339
|
effect: EffectName;
|
|
340
|
+
/** Start time on timeline in seconds. Required for effect clips. */
|
|
330
341
|
position: number;
|
|
342
|
+
/** End time on timeline in seconds. Mutually exclusive with duration. */
|
|
331
343
|
end?: number;
|
|
344
|
+
/** Duration in seconds (alternative to end). end = position + duration. */
|
|
332
345
|
duration?: number;
|
|
346
|
+
/** Ramp-in duration in seconds */
|
|
333
347
|
fadeIn?: number;
|
|
348
|
+
/** Ramp-out duration in seconds */
|
|
334
349
|
fadeOut?: number;
|
|
350
|
+
/** Effect-specific params */
|
|
335
351
|
params: EffectParams;
|
|
336
352
|
}
|
|
337
353
|
|
|
@@ -435,6 +451,10 @@ declare namespace SIMPLEFFMPEG {
|
|
|
435
451
|
validationMode?: "warn" | "strict";
|
|
436
452
|
/** Default font file path (.ttf, .otf) applied to all text clips. Individual clips can override this with their own fontFile. */
|
|
437
453
|
fontFile?: string;
|
|
454
|
+
/** Path to a .ttf/.otf emoji font for rendering emoji in text overlays (opt-in). Without this, emoji are silently stripped from text. Recommended: Noto Emoji (B&W outline). */
|
|
455
|
+
emojiFont?: string;
|
|
456
|
+
/** Custom directory for temporary files — gradient images, unrotated videos, intermediate renders, text/ASS temp files. Defaults to os.tmpdir() or the output directory depending on the operation. Useful for fast SSDs, ramdisks, or environments with constrained /tmp. */
|
|
457
|
+
tempDir?: string;
|
|
438
458
|
}
|
|
439
459
|
|
|
440
460
|
/** Log entry passed to onLog callback */
|
|
@@ -471,17 +491,66 @@ declare namespace SIMPLEFFMPEG {
|
|
|
471
491
|
comment?: string;
|
|
472
492
|
date?: string;
|
|
473
493
|
genre?: string;
|
|
494
|
+
/** Custom metadata key-value pairs */
|
|
474
495
|
custom?: Record<string, string>;
|
|
475
496
|
}
|
|
476
497
|
|
|
477
498
|
/** Thumbnail generation options */
|
|
478
499
|
interface ThumbnailOptions {
|
|
500
|
+
/** Output path for thumbnail image */
|
|
479
501
|
outputPath: string;
|
|
502
|
+
/** Time in seconds to capture (default: 0) */
|
|
480
503
|
time?: number;
|
|
504
|
+
/** Thumbnail width (maintains aspect if height omitted) */
|
|
505
|
+
width?: number;
|
|
506
|
+
/** Thumbnail height (maintains aspect if width omitted) */
|
|
507
|
+
height?: number;
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
/** Keyframe extraction mode */
|
|
511
|
+
type KeyframeMode = "scene-change" | "interval";
|
|
512
|
+
|
|
513
|
+
/** Output format for extracted keyframes */
|
|
514
|
+
type KeyframeFormat = "jpeg" | "png";
|
|
515
|
+
|
|
516
|
+
/** Base options for SIMPLEFFMPEG.extractKeyframes() */
|
|
517
|
+
interface ExtractKeyframesBaseOptions {
|
|
518
|
+
/** Extraction mode: 'scene-change' detects visual transitions, 'interval' samples at fixed spacing (default: 'scene-change') */
|
|
519
|
+
mode?: KeyframeMode;
|
|
520
|
+
/** Scene detection sensitivity 0-1, lower = more frames (default: 0.3). Only for scene-change mode. */
|
|
521
|
+
sceneThreshold?: number;
|
|
522
|
+
/** Seconds between frames (default: 5). Only for interval mode. */
|
|
523
|
+
intervalSeconds?: number;
|
|
524
|
+
/** Maximum number of frames to extract */
|
|
525
|
+
maxFrames?: number;
|
|
526
|
+
/** Output image format (default: 'jpeg') */
|
|
527
|
+
format?: KeyframeFormat;
|
|
528
|
+
/** JPEG quality 1-31, lower is better (default: 2). Only applies to JPEG. */
|
|
529
|
+
quality?: number;
|
|
530
|
+
/** Output width in pixels (maintains aspect ratio if height omitted) */
|
|
481
531
|
width?: number;
|
|
532
|
+
/** Output height in pixels (maintains aspect ratio if width omitted) */
|
|
482
533
|
height?: number;
|
|
534
|
+
/** Custom directory for temporary files (default: os.tmpdir()). Only used when outputDir is not set. Useful for fast SSDs, ramdisks, or environments with constrained /tmp. */
|
|
535
|
+
tempDir?: string;
|
|
483
536
|
}
|
|
484
537
|
|
|
538
|
+
/** Options with outputDir — writes to disk, returns string[] */
|
|
539
|
+
interface ExtractKeyframesToDiskOptions extends ExtractKeyframesBaseOptions {
|
|
540
|
+
/** Directory to write frame files to */
|
|
541
|
+
outputDir: string;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
/** Options without outputDir — returns Buffer[] */
|
|
545
|
+
interface ExtractKeyframesToBufferOptions extends ExtractKeyframesBaseOptions {
|
|
546
|
+
outputDir?: undefined;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
/** Combined options type for extractKeyframes */
|
|
550
|
+
type ExtractKeyframesOptions =
|
|
551
|
+
| ExtractKeyframesToDiskOptions
|
|
552
|
+
| ExtractKeyframesToBufferOptions;
|
|
553
|
+
|
|
485
554
|
/** Options for SIMPLEFFMPEG.snapshot() — capture a single frame from a video */
|
|
486
555
|
interface SnapshotOptions {
|
|
487
556
|
/** Output image path (extension determines format: .jpg, .png, .webp, .bmp, .tiff) */
|
|
@@ -496,6 +565,7 @@ declare namespace SIMPLEFFMPEG {
|
|
|
496
565
|
quality?: number;
|
|
497
566
|
}
|
|
498
567
|
|
|
568
|
+
/** Hardware acceleration options */
|
|
499
569
|
type HardwareAcceleration =
|
|
500
570
|
| "auto"
|
|
501
571
|
| "videotoolbox"
|
|
@@ -504,6 +574,7 @@ declare namespace SIMPLEFFMPEG {
|
|
|
504
574
|
| "qsv"
|
|
505
575
|
| "none";
|
|
506
576
|
|
|
577
|
+
/** Video codec options */
|
|
507
578
|
type VideoCodec =
|
|
508
579
|
| "libx264"
|
|
509
580
|
| "libx265"
|
|
@@ -520,6 +591,7 @@ declare namespace SIMPLEFFMPEG {
|
|
|
520
591
|
| "hevc_qsv"
|
|
521
592
|
| string;
|
|
522
593
|
|
|
594
|
+
/** Audio codec options */
|
|
523
595
|
type AudioCodec =
|
|
524
596
|
| "aac"
|
|
525
597
|
| "libmp3lame"
|
|
@@ -529,6 +601,7 @@ declare namespace SIMPLEFFMPEG {
|
|
|
529
601
|
| "copy"
|
|
530
602
|
| string;
|
|
531
603
|
|
|
604
|
+
/** Encoding preset options */
|
|
532
605
|
type EncodingPreset =
|
|
533
606
|
| "ultrafast"
|
|
534
607
|
| "superfast"
|
|
@@ -540,6 +613,7 @@ declare namespace SIMPLEFFMPEG {
|
|
|
540
613
|
| "slower"
|
|
541
614
|
| "veryslow";
|
|
542
615
|
|
|
616
|
+
/** Resolution presets */
|
|
543
617
|
type ResolutionPreset = "480p" | "720p" | "1080p" | "1440p" | "4k";
|
|
544
618
|
|
|
545
619
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
@@ -556,82 +630,147 @@ declare namespace SIMPLEFFMPEG {
|
|
|
556
630
|
|
|
557
631
|
/** Custom position using percentages (0-1) */
|
|
558
632
|
interface WatermarkPositionPercent {
|
|
633
|
+
/** Horizontal position as percentage (0 = left, 0.5 = center, 1 = right) */
|
|
559
634
|
xPercent: number;
|
|
635
|
+
/** Vertical position as percentage (0 = top, 0.5 = center, 1 = bottom) */
|
|
560
636
|
yPercent: number;
|
|
561
637
|
}
|
|
562
638
|
|
|
563
639
|
/** Custom position using pixels */
|
|
564
640
|
interface WatermarkPositionPixel {
|
|
641
|
+
/** X position in pixels from left */
|
|
565
642
|
x: number;
|
|
643
|
+
/** Y position in pixels from top */
|
|
566
644
|
y: number;
|
|
567
645
|
}
|
|
568
646
|
|
|
647
|
+
/** Watermark position options */
|
|
569
648
|
type WatermarkPosition =
|
|
570
649
|
| WatermarkPositionPreset
|
|
571
650
|
| WatermarkPositionPercent
|
|
572
651
|
| WatermarkPositionPixel;
|
|
573
652
|
|
|
653
|
+
/** Base watermark options shared by image and text watermarks */
|
|
574
654
|
interface BaseWatermarkOptions {
|
|
655
|
+
/** Position preset or custom coordinates (default: 'bottom-right') */
|
|
575
656
|
position?: WatermarkPosition;
|
|
657
|
+
/** Margin from edge in pixels when using preset positions (default: 20) */
|
|
576
658
|
margin?: number;
|
|
659
|
+
/** Opacity from 0 (transparent) to 1 (opaque) (default: 1) */
|
|
577
660
|
opacity?: number;
|
|
661
|
+
/** Start time in seconds (default: 0, start of video) */
|
|
578
662
|
startTime?: number;
|
|
663
|
+
/** End time in seconds (default: end of video) */
|
|
579
664
|
endTime?: number;
|
|
580
665
|
}
|
|
581
666
|
|
|
667
|
+
/** Image watermark options */
|
|
582
668
|
interface ImageWatermarkOptions extends BaseWatermarkOptions {
|
|
583
669
|
type: "image";
|
|
670
|
+
/** Path to the watermark image file */
|
|
584
671
|
url: string;
|
|
672
|
+
/** Scale relative to video width, 0-1 (default: 0.15, i.e., 15% of width) */
|
|
585
673
|
scale?: number;
|
|
586
674
|
}
|
|
587
675
|
|
|
676
|
+
/** Text watermark options */
|
|
588
677
|
interface TextWatermarkOptions extends BaseWatermarkOptions {
|
|
589
678
|
type: "text";
|
|
679
|
+
/** Text to display as watermark */
|
|
590
680
|
text: string;
|
|
681
|
+
/** Font size in pixels (default: 24) */
|
|
591
682
|
fontSize?: number;
|
|
683
|
+
/** Font color in hex format (default: '#FFFFFF') */
|
|
592
684
|
fontColor?: string;
|
|
685
|
+
/** Font family name (default: 'Sans') */
|
|
593
686
|
fontFamily?: string;
|
|
687
|
+
/** Path to custom font file */
|
|
594
688
|
fontFile?: string;
|
|
689
|
+
/** Border/outline color */
|
|
595
690
|
borderColor?: string;
|
|
691
|
+
/** Border/outline width in pixels */
|
|
596
692
|
borderWidth?: number;
|
|
693
|
+
/** Shadow color */
|
|
597
694
|
shadowColor?: string;
|
|
695
|
+
/** Shadow X offset */
|
|
598
696
|
shadowX?: number;
|
|
697
|
+
/** Shadow Y offset */
|
|
599
698
|
shadowY?: number;
|
|
600
699
|
}
|
|
601
700
|
|
|
701
|
+
/** Watermark configuration - either image or text */
|
|
602
702
|
type WatermarkOptions = ImageWatermarkOptions | TextWatermarkOptions;
|
|
603
703
|
|
|
604
704
|
interface ExportOptions {
|
|
705
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
605
706
|
// Output
|
|
707
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
708
|
+
|
|
709
|
+
/** Output file path (default: './output.mp4') */
|
|
606
710
|
outputPath?: string;
|
|
607
711
|
|
|
712
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
608
713
|
// Video Encoding
|
|
714
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
715
|
+
|
|
716
|
+
/** Video codec (default: 'libx264') */
|
|
609
717
|
videoCodec?: VideoCodec;
|
|
718
|
+
/** Quality level 0-51, lower is better (default: 23) */
|
|
610
719
|
crf?: number;
|
|
720
|
+
/** Encoding speed/quality tradeoff (default: 'medium') */
|
|
611
721
|
preset?: EncodingPreset;
|
|
722
|
+
/** Target video bitrate (e.g., '5M', '2500k'). Overrides CRF when set. */
|
|
612
723
|
videoBitrate?: string;
|
|
613
724
|
|
|
725
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
614
726
|
// Audio Encoding
|
|
727
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
728
|
+
|
|
729
|
+
/** Audio codec (default: 'aac') */
|
|
615
730
|
audioCodec?: AudioCodec;
|
|
731
|
+
/** Audio bitrate (default: '192k') */
|
|
616
732
|
audioBitrate?: string;
|
|
733
|
+
/** Audio sample rate in Hz (default: 48000) */
|
|
617
734
|
audioSampleRate?: number;
|
|
618
735
|
|
|
736
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
619
737
|
// Hardware Acceleration
|
|
738
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
739
|
+
|
|
740
|
+
/** Hardware acceleration mode (default: 'none') */
|
|
620
741
|
hwaccel?: HardwareAcceleration;
|
|
621
742
|
|
|
743
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
622
744
|
// Output Resolution
|
|
745
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
746
|
+
|
|
747
|
+
/** Output width in pixels (scales the output) */
|
|
623
748
|
outputWidth?: number;
|
|
749
|
+
/** Output height in pixels (scales the output) */
|
|
624
750
|
outputHeight?: number;
|
|
751
|
+
/** Resolution preset ('720p', '1080p', '4k', etc.) */
|
|
625
752
|
outputResolution?: ResolutionPreset;
|
|
626
753
|
|
|
754
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
627
755
|
// Advanced Options
|
|
756
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
757
|
+
|
|
758
|
+
/** Export audio only (no video) */
|
|
628
759
|
audioOnly?: boolean;
|
|
760
|
+
/** Enable two-pass encoding for better quality at target bitrate */
|
|
629
761
|
twoPass?: boolean;
|
|
762
|
+
/** Metadata to embed in output file */
|
|
630
763
|
metadata?: MetadataOptions;
|
|
764
|
+
/** Generate a thumbnail from the output */
|
|
631
765
|
thumbnail?: ThumbnailOptions;
|
|
632
766
|
|
|
767
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
633
768
|
// Debug & Logging
|
|
769
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
770
|
+
|
|
771
|
+
/** Enable verbose logging */
|
|
634
772
|
verbose?: boolean;
|
|
773
|
+
/** FFmpeg log level (default: 'warning') */
|
|
635
774
|
logLevel?:
|
|
636
775
|
| "quiet"
|
|
637
776
|
| "panic"
|
|
@@ -641,27 +780,49 @@ declare namespace SIMPLEFFMPEG {
|
|
|
641
780
|
| "info"
|
|
642
781
|
| "verbose"
|
|
643
782
|
| "debug";
|
|
783
|
+
/** Save FFmpeg command to file for debugging */
|
|
644
784
|
saveCommand?: string;
|
|
645
785
|
|
|
786
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
646
787
|
// Callbacks & Control
|
|
788
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
789
|
+
|
|
790
|
+
/** Progress callback for monitoring export progress */
|
|
647
791
|
onProgress?: (progress: ProgressInfo) => void;
|
|
648
792
|
/** FFmpeg log callback for real-time stderr/stdout output */
|
|
649
793
|
onLog?: (entry: LogEntry) => void;
|
|
794
|
+
/** AbortSignal for cancelling the export */
|
|
650
795
|
signal?: AbortSignal;
|
|
651
796
|
|
|
652
|
-
//
|
|
797
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
798
|
+
// Text Batching (Advanced)
|
|
799
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
800
|
+
|
|
801
|
+
/** Maximum text overlay nodes per FFmpeg pass (default: 75) */
|
|
653
802
|
textMaxNodesPerPass?: number;
|
|
803
|
+
/** Video codec for intermediate text passes (default: 'libx264') */
|
|
654
804
|
intermediateVideoCodec?: string;
|
|
805
|
+
/** CRF for intermediate text passes (default: 18) */
|
|
655
806
|
intermediateCrf?: number;
|
|
807
|
+
/** Preset for intermediate text passes (default: 'veryfast') */
|
|
656
808
|
intermediatePreset?: string;
|
|
657
809
|
|
|
810
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
658
811
|
// Watermark
|
|
812
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
813
|
+
|
|
814
|
+
/** Add a watermark overlay (image or text) to the video */
|
|
659
815
|
watermark?: WatermarkOptions;
|
|
660
816
|
|
|
817
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
661
818
|
// Timeline
|
|
819
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
820
|
+
|
|
662
821
|
/**
|
|
663
822
|
* Automatically adjust text/subtitle timings to compensate for timeline
|
|
664
823
|
* compression caused by xfade transitions (default: true).
|
|
824
|
+
* When enabled, text positioned at "15s" will appear at the visual 15s mark
|
|
825
|
+
* even if transitions have compressed the actual timeline.
|
|
665
826
|
*/
|
|
666
827
|
compensateTransitions?: boolean;
|
|
667
828
|
}
|
|
@@ -765,6 +926,7 @@ declare class SIMPLEFFMPEG {
|
|
|
765
926
|
|
|
766
927
|
/**
|
|
767
928
|
* Get available platform presets
|
|
929
|
+
* @returns Map of preset names to their configurations
|
|
768
930
|
*/
|
|
769
931
|
static getPresets(): Record<
|
|
770
932
|
SIMPLEFFMPEG.PlatformPreset,
|
|
@@ -773,6 +935,7 @@ declare class SIMPLEFFMPEG {
|
|
|
773
935
|
|
|
774
936
|
/**
|
|
775
937
|
* Get list of available preset names
|
|
938
|
+
* @returns Array of preset names
|
|
776
939
|
*/
|
|
777
940
|
static getPresetNames(): SIMPLEFFMPEG.PlatformPreset[];
|
|
778
941
|
|
|
@@ -858,6 +1021,46 @@ declare class SIMPLEFFMPEG {
|
|
|
858
1021
|
options: SIMPLEFFMPEG.SnapshotOptions
|
|
859
1022
|
): Promise<string>;
|
|
860
1023
|
|
|
1024
|
+
/**
|
|
1025
|
+
* Extract keyframes from a video using scene-change detection or fixed time intervals.
|
|
1026
|
+
*
|
|
1027
|
+
* Scene-change mode uses FFmpeg's select=gt(scene,N) filter to detect visual transitions.
|
|
1028
|
+
* Interval mode extracts frames at fixed time intervals.
|
|
1029
|
+
*
|
|
1030
|
+
* When outputDir is provided, frames are written to disk and the method returns file paths.
|
|
1031
|
+
* Without outputDir, frames are returned as in-memory Buffer objects.
|
|
1032
|
+
*
|
|
1033
|
+
* @param filePath - Path to the source video file
|
|
1034
|
+
* @param options - Extraction options (with outputDir → string[], without → Buffer[])
|
|
1035
|
+
* @throws {SIMPLEFFMPEG.SimpleffmpegError} If arguments are invalid
|
|
1036
|
+
* @throws {SIMPLEFFMPEG.FFmpegError} If FFmpeg fails during extraction
|
|
1037
|
+
*
|
|
1038
|
+
* @example
|
|
1039
|
+
* // Scene-change detection — returns Buffer[]
|
|
1040
|
+
* const frames = await SIMPLEFFMPEG.extractKeyframes("./video.mp4", {
|
|
1041
|
+
* mode: "scene-change",
|
|
1042
|
+
* sceneThreshold: 0.4,
|
|
1043
|
+
* maxFrames: 8,
|
|
1044
|
+
* });
|
|
1045
|
+
*
|
|
1046
|
+
* @example
|
|
1047
|
+
* // Fixed interval — writes to disk, returns string[]
|
|
1048
|
+
* const paths = await SIMPLEFFMPEG.extractKeyframes("./video.mp4", {
|
|
1049
|
+
* mode: "interval",
|
|
1050
|
+
* intervalSeconds: 5,
|
|
1051
|
+
* outputDir: "./frames/",
|
|
1052
|
+
* format: "png",
|
|
1053
|
+
* });
|
|
1054
|
+
*/
|
|
1055
|
+
static extractKeyframes(
|
|
1056
|
+
filePath: string,
|
|
1057
|
+
options: SIMPLEFFMPEG.ExtractKeyframesToDiskOptions
|
|
1058
|
+
): Promise<string[]>;
|
|
1059
|
+
static extractKeyframes(
|
|
1060
|
+
filePath: string,
|
|
1061
|
+
options?: SIMPLEFFMPEG.ExtractKeyframesToBufferOptions
|
|
1062
|
+
): Promise<Buffer[]>;
|
|
1063
|
+
|
|
861
1064
|
/**
|
|
862
1065
|
* Format validation result as human-readable string
|
|
863
1066
|
*/
|