Files
2026-03-03 23:49:13 +01:00

148 lines
5.0 KiB
TypeScript

/**
* FFmpeg utilities for video concatenation and section-based speed manipulation.
*
* Both functions use a single ffmpeg filter_complex pass: trim segments from
* the input, apply setpts for speed, normalize fps/scale, then concat.
* No intermediate files, no multi-pass.
*/
/** Seconds of normal-speed buffer kept before and after each execution */
export declare const INTERACTION_BUFFER_SECONDS = 1;
interface EncoderInfo {
/** Encoder name for `-c:v`, e.g. "h264_videotoolbox" or "libx264" */
codec: string;
/** true when using a hardware encoder */
isHardware: boolean;
}
/**
* Detect the best available H.264 encoder.
* Tries platform-specific hardware encoders first, falls back to libx264.
* Result is cached for the lifetime of the process.
*/
export declare function detectEncoder(): Promise<EncoderInfo>;
export interface InputFile {
path: string;
start?: number;
end?: number;
}
export interface ConcatenateOptions {
inputFiles: InputFile[];
outputFile: string;
outputDimensions: {
width: number;
height: number;
};
frameRate: number;
signal?: AbortSignal;
}
export interface SpeedSection {
/** Start time in seconds */
start: number;
/** End time in seconds */
end: number;
/** Speed multiplier, e.g. 2 = 2x faster, 0.5 = 2x slower */
speed: number;
}
export interface SpeedUpSectionsOptions {
inputFile: string;
/** Defaults to inputFile with `-fast` suffix before extension */
outputFile?: string;
sections: SpeedSection[];
/** Defaults to input video dimensions (probed via ffprobe) */
outputDimensions?: {
width: number;
height: number;
};
/** Defaults to input video frame rate (probed via ffprobe) */
frameRate?: number;
signal?: AbortSignal;
}
export interface VideoInfo {
width: number;
height: number;
frameRate: number;
}
/** Probe input video for dimensions and frame rate via ffprobe. */
export declare function probeVideo(filePath: string): Promise<VideoInfo>;
export declare function concatenateVideos(options: ConcatenateOptions): Promise<void>;
/**
* Speed up (or slow down) sections of a video by timestamp ranges.
*
* Sections not covered by any SpeedSection play at normal speed.
* Uses a single ffmpeg filter_complex: trim each segment, apply setpts
* speed, normalize fps/scale, then concat — no intermediate files.
*
* @example
* ```ts
* await speedUpSections({
* inputFile: 'recording.mp4',
* sections: [
* { start: 10, end: 20, speed: 4 }, // 4x between 10s-20s
* { start: 30, end: 40, speed: 2 }, // 2x between 30s-40s
* ],
* })
* // → outputs recording-fast.mp4
* ```
*/
export declare function speedUpSections(options: SpeedUpSectionsOptions): Promise<string>;
export interface ExecutionTimestamp {
/** Start time in seconds relative to recording start */
start: number;
/** End time in seconds relative to recording start */
end: number;
}
/**
* Compute which parts of a recording are "idle" (no execute() calls)
* and return them as SpeedSections that can be passed to speedUpSections().
*
* A buffer of INTERACTION_BUFFER_SECONDS is kept around each execution
* at normal speed so the viewer sees context before/after each action.
*
* @example
* ```ts
* const { executionTimestamps, duration } = await stopRecording()
* const idleSections = computeIdleSections({
* executionTimestamps,
* totalDurationMs: duration,
* })
* await speedUpSections({
* inputFile: recordingPath,
* sections: idleSections,
* })
* ```
*/
export declare function computeIdleSections({ executionTimestamps, totalDurationMs, speed, bufferSeconds, }: {
executionTimestamps: ExecutionTimestamp[];
/** Total recording duration in milliseconds (from stopRecording result) */
totalDurationMs: number;
/** Speed multiplier for idle sections (default 5) */
speed?: number;
/** Override the default buffer around each execution (seconds) */
bufferSeconds?: number;
}): SpeedSection[];
export interface CreateDemoVideoOptions {
/** Path to the raw recording file */
recordingPath: string;
/** Total recording duration in milliseconds (from stopRecording result) */
durationMs: number;
/** Execution timestamps (from stopRecording result) */
executionTimestamps: ExecutionTimestamp[];
/** Speed multiplier for idle sections (default 5) */
speed?: number;
/** Output file path (defaults to recordingPath with `-demo` suffix) */
outputFile?: string;
signal?: AbortSignal;
}
/**
* Create a demo video from a recording by speeding up idle sections
* (gaps between execute() calls) while keeping interactions at normal speed.
*
* A 1-second buffer (INTERACTION_BUFFER_SECONDS) is preserved around each
* interaction so viewers see context before and after each action.
*
* Requires `ffmpeg` and `ffprobe` installed on the system.
*
* @returns The output file path
*/
export declare function createDemoVideo(options: CreateDemoVideoOptions): Promise<string>;
export {};
//# sourceMappingURL=ffmpeg.d.ts.map