import { Demuxer } from './demuxer.js';
import type { AVPixelFormat } from '../constants/constants.js';
import type { FFVideoDecoder } from '../constants/decoders.js';
import type { AudioDeviceMode, DeviceInfo, DeviceMode } from '../lib/device.js';
/**
 * Options for opening a camera device.
 */
export interface CameraOptions {
    videoDevice?: string | number;
    frameRate?: number;
    width?: number;
    height?: number;
    pixelFormat?: AVPixelFormat;
    avfoundation?: {
        captureRawData?: boolean;
    };
    v4l2?: {
        inputFormat?: FFVideoDecoder;
    };
    dshow?: {
        videoDeviceNumber?: number;
        videoPinName?: string;
    };
    formatOptions?: Record<string, string | number | boolean | undefined | null>;
}
/**
 * Options for opening a microphone device.
 */
export interface MicrophoneOptions {
    audioDevice?: string | number;
    sampleRate?: number;
    channels?: number;
    alsa?: {
        configPath?: string;
    };
    dshow?: {
        sampleSize?: number;
        audioDeviceNumber?: number;
        audioPinName?: string;
        audioBufferSize?: number;
    };
    formatOptions?: Record<string, string | number | boolean | undefined | null>;
}
/**
 * Options for screen capture.
 */
export interface ScreenCaptureOptions {
    screenIndex?: number;
    windowId?: number;
    x?: number;
    y?: number;
    width?: number;
    height?: number;
    frameRate?: number;
    drawMouse?: boolean;
    pixelFormat?: AVPixelFormat;
    avfoundation?: {
        captureMouseClicks?: boolean;
        captureSystemAudio?: boolean;
        excludeProcessAudio?: boolean;
        audioSampleRate?: 8000 | 16000 | 24000 | 48000;
        audioChannels?: 1 | 2;
    };
    x11grab?: {
        display?: string;
        followMouse?: 'centered' | number;
        showRegion?: boolean;
    };
    gdigrab?: {
        windowTitle?: string;
        showRegion?: boolean;
    };
    formatOptions?: Record<string, string | number | boolean | undefined | null>;
}
/**
 * Options for combined video + audio device capture.
 */
export interface DeviceOptions {
    videoDevice?: string | number;
    audioDevice?: string | number;
    frameRate?: number;
    width?: number;
    height?: number;
    pixelFormat?: AVPixelFormat;
    sampleRate?: number;
    channels?: number;
    avfoundation?: {
        captureRawData?: boolean;
    };
    dshow?: {
        videoDeviceNumber?: number;
        audioDeviceNumber?: number;
        videoPinName?: string;
        audioPinName?: string;
        audioBufferSize?: number;
    };
    formatOptions?: Record<string, string | number | boolean | undefined | null>;
}
export declare class DeviceAPI {
    /**
     * List all available capture devices.
     *
     * Enumerates video (cameras) and audio (microphones) capture devices
     * on the system using platform-specific APIs.
     *
     * @returns Array of device information
     *
     * @example
     * ```typescript
     * const devices = await DeviceAPI.list();
     *
     * // Filter by type
     * const cameras = devices.filter(d => d.type === 'video');
     * const microphones = devices.filter(d => d.type === 'audio');
     *
     * // Find default devices
     * const defaultCamera = devices.find(d => d.type === 'video' && d.isDefault);
     * ```
     */
    static list(): Promise<DeviceInfo[]>;
    /**
     * List all available capture devices synchronously.
     *
     * @returns Array of device information
     *
     * @example
     * ```typescript
     * const devices = DeviceAPI.listSync();
     * console.log('Found', devices.length, 'devices');
     * ```
     *
     * @see {@link list} For async version
     */
    static listSync(): DeviceInfo[];
    /**
     * Query supported capture modes for a video device.
     *
     * Returns supported resolutions and frame rate ranges, sorted descending
     * by resolution (area), then by max frame rate.
     *
     * @param deviceName - Device name as returned by `list()` (e.g. uniqueID on macOS)
     *
     * @returns Array of supported device modes
     *
     * @example
     * ```typescript
     * const devices = await DeviceAPI.list();
     * const camera = devices.find(d => d.type === 'video');
     * if (camera) {
     *   const modes = await DeviceAPI.modes(camera.name);
     *   for (const mode of modes) {
     *     console.log(`${mode.width}x${mode.height} @ ${mode.minFrameRate}-${mode.maxFrameRate} fps`);
     *   }
     * }
     * ```
     *
     * @see {@link modesSync} For sync version
     */
    static modes(deviceName: string): Promise<DeviceMode[]>;
    /**
     * Query supported capture modes for a video device synchronously.
     *
     * @param deviceName - Device name as returned by `listSync()`
     *
     * @returns Array of supported device modes
     *
     * @example
     * ```typescript
     * const devices = DeviceAPI.listSync();
     * const camera = devices.find(d => d.type === 'video');
     * if (camera) {
     *   const modes = DeviceAPI.modesSync(camera.name);
     *   for (const mode of modes) {
     *     console.log(`${mode.width}x${mode.height} @ ${mode.minFrameRate}-${mode.maxFrameRate} fps`);
     *   }
     * }
     * ```
     *
     * @see {@link modes} For async version
     */
    static modesSync(deviceName: string): DeviceMode[];
    /**
     * Query supported audio capture modes for an audio device.
     *
     * Returns supported sample rates, channel counts and sample formats,
     * sorted descending by sample rate, then by channel count.
     *
     * @param deviceName - Device name as returned by `list()` (e.g. uniqueID on macOS)
     *
     * @returns Array of supported audio device modes
     *
     * @example
     * ```typescript
     * const devices = await DeviceAPI.list();
     * const mic = devices.find(d => d.type === 'audio');
     * if (mic) {
     *   const modes = await DeviceAPI.audioModes(mic.name);
     *   for (const mode of modes) {
     *     console.log(`${mode.sampleRate}Hz ${mode.channels}ch`);
     *   }
     * }
     * ```
     *
     * @see {@link audioModesSync} For sync version
     */
    static audioModes(deviceName: string): Promise<AudioDeviceMode[]>;
    /**
     * Query supported audio capture modes for an audio device synchronously.
     *
     * @param deviceName - Device name as returned by `listSync()`
     *
     * @returns Array of supported audio device modes
     *
     * @example
     * ```typescript
     * const devices = DeviceAPI.listSync();
     * const mic = devices.find(d => d.type === 'audio');
     * if (mic) {
     *   const modes = DeviceAPI.audioModesSync(mic.name);
     *   for (const mode of modes) {
     *     console.log(`${mode.sampleRate}Hz ${mode.channels}ch`);
     *   }
     * }
     * ```
     *
     * @see {@link audioModes} For async version
     */
    static audioModesSync(deviceName: string): AudioDeviceMode[];
    /**
     * Open a camera device for capture.
     *
     * Creates a Demuxer for the specified video capture device.
     * Uses platform-specific format and device naming conventions.
     *
     * @param options - Camera capture options
     *
     * @returns Demuxer for the camera stream
     *
     * @throws {Error} If device cannot be opened
     *
     * @example
     * ```typescript
     * // Open first camera with default settings
     * await using input = await DeviceAPI.openCamera({ videoDevice: 0 });
     *
     * // Open with specific resolution and frame rate
     * await using input = await DeviceAPI.openCamera({
     *   videoDevice: 0,
     *   width: 1280,
     *   height: 720,
     *   frameRate: 30,
     * });
     *
     * // Open by device name
     * await using input = await DeviceAPI.openCamera({
     *   videoDevice: 'FaceTime HD Camera',
     * });
     * ```
     */
    static openCamera(options?: CameraOptions): Promise<Demuxer>;
    /**
     * Open a camera device for capture synchronously.
     *
     * @param options - Camera capture options
     *
     * @returns Demuxer for the camera stream
     *
     * @example
     * ```typescript
     * using input = DeviceAPI.openCameraSync({ videoDevice: 0 });
     * ```
     *
     * @see {@link openCamera} For async version
     */
    static openCameraSync(options?: CameraOptions): Demuxer;
    /**
     * Open a microphone device for capture.
     *
     * Creates a Demuxer for the specified audio capture device.
     * Uses platform-specific format and device naming conventions.
     *
     * @param options - Microphone capture options
     *
     * @returns Demuxer for the audio stream
     *
     * @throws {Error} If device cannot be opened
     *
     * @example
     * ```typescript
     * // Open first microphone
     * await using input = await DeviceAPI.openMicrophone({ audioDevice: 0 });
     *
     * // Open with specific sample rate
     * await using input = await DeviceAPI.openMicrophone({
     *   audioDevice: 'default',
     *   sampleRate: 48000,
     *   channels: 2,
     * });
     * ```
     */
    static openMicrophone(options?: MicrophoneOptions): Promise<Demuxer>;
    /**
     * Open a microphone device for capture synchronously.
     *
     * @param options - Microphone capture options
     *
     * @returns Demuxer for the audio stream
     *
     * @example
     * ```typescript
     * using input = DeviceAPI.openMicrophoneSync({ audioDevice: 0 });
     * ```
     *
     * @see {@link openMicrophone} For async version
     */
    static openMicrophoneSync(options?: MicrophoneOptions): Demuxer;
    /**
     * Open screen capture.
     *
     * Creates a Demuxer for screen/display capture.
     * Uses platform-specific format and capture conventions.
     *
     * @param options - Screen capture options
     *
     * @returns Demuxer for the screen capture stream
     *
     * @throws {Error} If screen capture cannot be opened
     *
     * @example
     * ```typescript
     * // Capture entire screen
     * await using input = await DeviceAPI.openScreen({
     *   frameRate: 30,
     * });
     *
     * // Capture specific region
     * await using input = await DeviceAPI.openScreen({
     *   x: 100,
     *   y: 100,
     *   width: 800,
     *   height: 600,
     *   frameRate: 30,
     * });
     *
     * // Capture specific screen (works cross-platform)
     * await using input = await DeviceAPI.openScreen({
     *   screenIndex: 1,
     *   frameRate: 30,
     * });
     * ```
     */
    static openScreen(options?: ScreenCaptureOptions): Promise<Demuxer>;
    /**
     * Open screen capture synchronously.
     *
     * @param options - Screen capture options
     *
     * @returns Demuxer for the screen capture stream
     *
     * @example
     * ```typescript
     * using input = DeviceAPI.openScreenSync({ frameRate: 30 });
     * ```
     *
     * @see {@link openScreen} For async version
     */
    static openScreenSync(options?: ScreenCaptureOptions): Demuxer;
    /**
     * Open a combined video + audio device for capture.
     *
     * Creates a single Demuxer that captures both video and audio simultaneously.
     * Supported on macOS (AVFoundation) and Windows (DirectShow).
     * Not supported on Linux — use separate `openCamera()` and `openMicrophone()` calls instead.
     *
     * @param options - Combined device capture options
     *
     * @returns Demuxer for the combined video + audio stream
     *
     * @throws {Error} If devices cannot be opened or platform does not support combined capture
     *
     * @example
     * ```typescript
     * await using input = await DeviceAPI.openDevice({
     *   videoDevice: 0,
     *   audioDevice: 0,
     *   width: 1280,
     *   height: 720,
     *   frameRate: 30,
     *   sampleRate: 48000,
     *   channels: 2,
     * });
     * ```
     */
    static openDevice(options: DeviceOptions): Promise<Demuxer>;
    /**
     * Open a combined video + audio device for capture synchronously.
     *
     * @param options - Combined device capture options
     *
     * @returns Demuxer for the combined video + audio stream
     *
     * @example
     * ```typescript
     * using input = DeviceAPI.openDeviceSync({
     *   videoDevice: 0,
     *   audioDevice: 0,
     * });
     * ```
     *
     * @see {@link openDevice} For async version
     */
    static openDeviceSync(options: DeviceOptions): Demuxer;
    /**
     * Get the platform-specific input format for video devices.
     *
     * @returns Format name (avfoundation/v4l2/dshow)
     *
     * @example
     * ```typescript
     * const format = DeviceAPI.getVideoFormat();
     * // Returns 'avfoundation' on macOS, 'v4l2' on Linux, 'dshow' on Windows
     * ```
     */
    static getVideoFormat(): string;
    /**
     * Get the platform-specific input format for audio devices.
     *
     * @returns Format name (avfoundation/alsa/dshow)
     *
     * @example
     * ```typescript
     * const format = DeviceAPI.getAudioFormat();
     * // Returns 'avfoundation' on macOS, 'alsa' on Linux, 'dshow' on Windows
     * ```
     */
    static getAudioFormat(): string;
    /**
     * Get the platform-specific input format for screen capture.
     *
     * @returns Format name (avfoundation/x11grab/gdigrab)
     *
     * @example
     * ```typescript
     * const format = DeviceAPI.getScreenFormat();
     * // Returns 'avfoundation' on macOS, 'x11grab' on Linux, 'gdigrab' on Windows
     * ```
     */
    static getScreenFormat(): string;
    /**
     * Check if the application has screen capture permission.
     *
     * On macOS 11+, uses `CGPreflightScreenCaptureAccess()` to check
     * whether the app has been granted screen recording permission.
     * Always returns `true` on Linux, Windows, and macOS < 11.
     *
     * @returns `true` if screen capture is permitted
     *
     * @example
     * ```typescript
     * if (!DeviceAPI.hasScreenCapturePermission()) {
     *   console.log('Screen capture permission not granted');
     *   DeviceAPI.requestScreenCaptureAccess(); // triggers system dialog
     * }
     * ```
     *
     * @see {@link requestScreenCaptureAccess} To trigger the permission dialog
     */
    static hasScreenCapturePermission(): boolean;
    /**
     * Request screen capture permission from the user.
     *
     * On macOS 11+, uses `CGRequestScreenCaptureAccess()` to trigger
     * the system permission dialog if not already granted.
     * Always returns `true` on Linux, Windows, and macOS < 11.
     *
     * Note: This function returns immediately. If permission was not previously
     * granted, the system dialog is shown asynchronously. The return value
     * indicates whether permission was already granted at the time of the call,
     * not the result of the dialog.
     *
     * @returns `true` if permission was already granted
     *
     * @example
     * ```typescript
     * const alreadyGranted = DeviceAPI.requestScreenCaptureAccess();
     * if (!alreadyGranted) {
     *   console.log('Permission dialog shown — restart the app after granting access');
     * }
     * ```
     *
     * @see {@link hasScreenCapturePermission} To check current permission status
     */
    static requestScreenCaptureAccess(): boolean;
    /**
     * Build platform-specific video device name.
     *
     * @param options - Camera options containing videoDevice
     *
     * @returns Platform-specific device name string
     *
     * @internal
     */
    private static buildVideoDeviceName;
    /**
     * Build platform-specific audio device name.
     *
     * @param options - Microphone options containing audioDevice
     *
     * @returns Platform-specific device name string
     *
     * @internal
     */
    private static buildAudioDeviceName;
    /**
     * Build platform-specific combined video + audio device name.
     *
     * @param options - Device options containing videoDevice and audioDevice
     *
     * @returns Platform-specific combined device name string
     *
     * @internal
     */
    private static buildCombinedDeviceName;
    /**
     * Build video format options.
     *
     * @param options - Camera options containing video parameters
     *
     * @returns FFmpeg format options dictionary
     *
     * @internal
     */
    private static buildVideoFormatOptions;
    /**
     * Build audio format options.
     *
     * @param options - Microphone options containing audio parameters
     *
     * @returns FFmpeg format options dictionary
     *
     * @internal
     */
    private static buildAudioFormatOptions;
    /**
     * Build combined video + audio format options.
     *
     * @param options - Device options containing both video and audio parameters
     *
     * @returns FFmpeg format options dictionary
     *
     * @internal
     */
    private static buildDeviceFormatOptions;
    /**
     * Build screen capture parameters.
     *
     * @param options - Screen capture options
     *
     * @returns Device name and format options for screen capture
     *
     * @internal
     */
    private static buildScreenCaptureParams;
    /**
     * Resolve screen bounds for a given screen index.
     *
     * @param screenIndex - 0-based screen index
     *
     * @returns Screen bounds or undefined if not found
     *
     * @internal
     */
    private static resolveScreenBounds;
    /**
     * Ensure ALSA configuration is available on Linux.
     *
     * Auto-detects the ALSA configuration file from standard paths and sets
     * `ALSA_CONFIG_PATH` if not already defined. This ensures ALSA can find
     * its configuration even if it is installed at a non-standard location.
     *
     * @param configPath - Optional explicit path to alsa.conf
     *
     * @internal
     */
    private static ensureAlsaConfig;
}
