/**
 * @module _shared/scene-audio-scan
 *
 * Reads a scene project's root + sub-composition HTML and returns a flat list
 * of audio elements with **absolute** timeline positions. Used by `executeSceneRender`
 * to mux narration / background-audio tracks into the producer's silent video
 * output via ffmpeg.
 *
 * Why a post-render scanner: at time of writing, `@hyperframes/producer`
 * renders frames + assembles the MP4 but does not embed audio from
 * `<audio>` elements that live inside sub-compositions. We pick up the slack
 * here without touching the producer.
 *
 * Pure module — no I/O beyond the explicit `loadCompositionHtml` reader the
 * orchestrator passes in. Easy to unit-test with fixture strings.
 */
/**
 * One `<audio>` element resolved into an absolute-timeline entry.
 */
export interface SceneAudioElement {
    /** Project-relative `src` from the audio tag (e.g. `assets/narration-intro.wav`). */
    srcRel: string;
    /** Absolute path on disk — `resolve(projectDir, srcRel)`. */
    srcAbs: string;
    /** Seconds from the start of the root timeline at which playback begins. */
    absoluteStart: number;
    /**
     * Composition-supplied duration. `"auto"` means "use the file's natural
     * duration"; the mux pass probes the file. Numeric means a hard cap.
     */
    durationHint: "auto" | number;
    /** Cap from the parent scene clip — audio is trimmed to fit this many seconds. */
    clipDurationCap: number;
    /** `data-volume`. Defaults to `1`. */
    volume: number;
    /** `data-track-index` — used so callers can group narration vs music vs etc. */
    trackIndex: number;
    /** Composition that owns this audio element (debug aid). */
    compositionSrc: string;
}
/**
 * Parsed view of a single `<div class="clip" data-composition-src="...">`
 * reference inside the root composition.
 */
export interface SceneClipRef {
    compositionId: string;
    compositionSrc: string;
    start: number;
    duration: number;
    trackIndex: number;
}
/**
 * Walk the root HTML for clip references. Returns one entry per
 * `<div class="clip">` with the four attributes we care about. Pure: a
 * regex-based scan, not a full DOM parser. The root file is generated by
 * VibeFrame so the markup is predictable; if a user hand-edits it into
 * something unparseable, the scanner simply finds fewer clips.
 */
export declare function parseRootClips(rootHtml: string): SceneClipRef[];
/**
 * Walk a single composition's HTML for `<audio>` elements. Returns one entry
 * per element with attributes resolved into our shape. Composition-local —
 * caller adds the parent clip's start to compute absolute timing.
 */
export declare function parseSceneAudios(compositionHtml: string): Array<{
    srcRel: string;
    localStart: number;
    durationHint: "auto" | number;
    volume: number;
    trackIndex: number;
}>;
/** Reader hook so the scanner stays unit-testable without touching the FS. */
export type CompositionReader = (compositionSrcRel: string) => Promise<string | null>;
/**
 * Default reader: read the composition file from disk relative to the
 * project directory. Returns `null` for missing files so the scanner can
 * skip them and continue.
 */
export declare function makeFsCompositionReader(projectDir: string): CompositionReader;
/**
 * Top-level scan. Parses every clip in the root, loads each composition,
 * pulls every audio element, and resolves absolute timeline positions.
 *
 * Audio absolute start = clip.start + audio.localStart. The `clipDurationCap`
 * is filled in from the clip's own duration so the mux pass can trim audio
 * that runs past the visual end of its parent scene.
 */
export declare function scanSceneAudio(opts: {
    projectDir: string;
    rootHtml: string;
    /** Override the default FS reader (testing). */
    readComposition?: CompositionReader;
}): Promise<SceneAudioElement[]>;
