import { type MixTrack } from "../domain/audio-tools.js";
import type { Composition, ExportPreset } from "../shared/composition.js";
/**
 * Composition.yaml stores `clip.src` as workspace-relative paths
 * (e.g. "assets/videos/test.mp4") so the file is portable. Remotion's
 * compositor on the other hand 404s on relative URLs and refuses
 * file:// URLs (`@remotion/renderer` only accepts http/https). Rewrite
 * relative paths to the local server's `/api/works/:id/assets/...`
 * route, which is already wired for browser preview. URLs with an
 * existing scheme (http://, https://, data:, blob:) pass through.
 */
export declare function rewriteClipSrcsToAbsolute(comp: Composition): Composition;
export type RenderStage = "render" | "duck" | "loudnorm" | "burn" | "encode";
export interface RenderJobOptions {
    comp: Composition;
    outDir: string;
    /** When true, burn TextTrack clips into the video (animations frozen).
     *  Default false — soft-sub via Remotion <Text> remains. */
    burnSubtitles?: boolean;
    /** Override the loudness target. Default -14 (YouTube/抖音/TikTok). */
    loudnessTargetLufs?: number;
    /** Override the title used in the output filename. Defaults to
     *  "autoviral-export" via buildSafeOutputFilename when undefined. */
    outputTitle?: string;
    /** Hook for the render queue / API client to surface progress. */
    onProgress?: (stage: RenderStage, pct: number) => void;
    /** Phase 7.A — abort the in-flight pipeline. Wired into spawn() processes. */
    signal?: AbortSignal;
    /** Phase 7.C — half-res / 24fps / half-bitrate proxy render. */
    proxy?: boolean;
    /** Phase H (issue #35) — per-track caption strategy following the DaVinci
     *  Resolve subtitle model. When supplied, takes precedence over the legacy
     *  `burnSubtitles` boolean.
     *
     *  - `burnTrackId`: id of the single text track to bake into the video
     *    (rendered by Remotion <Text>). When undefined/null, NO text track is
     *    burned — every text track is dropped from Stage 1 render input.
     *  - `sidecarTrackIds`: ids of text tracks emitted as `<output>.<lang>.srt`
     *    next to the final mp4. These are excluded from Stage 1 render so they
     *    don't double-render on top of the burned track.
     *
     *  Tracks that appear in neither list are dropped (skipped entirely — the
     *  "both unchecked" path documented in #35).
     *
     *  When omitted, render behaviour is unchanged: every text track in the
     *  composition renders via Remotion (legacy single-track default). */
    captionTracks?: {
        burnTrackId?: string | null;
        sidecarTrackIds?: string[];
    };
}
/** Phase H — convert a text track into an SRT document body. Cues are
 *  emitted in trackOffset order with a 1-based sequence number per spec.
 *  Pure; no I/O. Exposed for the multi-caption render test. */
export declare function textTrackToSrt(track: {
    clips: Array<{
        kind: string;
        text?: string;
        trackOffset: number;
        duration?: number;
    }>;
}): string;
declare function compositionToMixTracks(comp: Composition): MixTrack[];
export { compositionToMixTracks as __compositionToMixTracksForTest };
/**
 * Phase 6.E — re-encode `input` to `output` using `preset` for codec /
 * bitrate / audio settings. Loudnorm runs upstream (stage 4); this stage
 * only honours codec + bitrate flags, plus a faststart container hint
 * for web seek.
 *
 * R46: hardware encoder auto-detection. Was hard-coded to libx264 (CPU
 * software encoder); now probes ffmpeg -encoders once and prefers
 * h264_nvenc / h264_videotoolbox / h264_vaapi / h264_qsv. macOS Apple
 * Silicon now uses VideoToolbox = ~2-4× faster on the same h264 baseline.
 */
export declare function runEncodeStage(input: string, output: string, preset: ExportPreset, signal?: AbortSignal): Promise<void>;
export declare function runRenderPipeline(opts: RenderJobOptions): Promise<string>;
//# sourceMappingURL=render-pipeline.d.ts.map