import { Result, TaskEither } from '@eleven-am/fp';
import { HardwareAccelerationDetector } from './hardwareAccelerationDetector';
import { JobProcessor } from './jobProcessor';
import { MediaSource } from './mediaSource';
import { MetadataService } from './metadataService';
import { QualityService } from './qualityService';
import { AudioQuality, AudioQualityEnum, HardwareAccelerationConfig, MediaMetadata, SegmentStream, StreamConfig, StreamMetricsEvent, StreamType, SubtitleInfo, TranscodeJob, VideoQuality, VideoQualityEnum } from './types';
import { ExtendedEventEmitter } from './utils';
interface StreamEventMap {
    'transcode:complete': TranscodeJob;
    'transcode:queued': TranscodeJob;
    'transcode:error': {
        job: TranscodeJob;
        error: Error;
    };
    'transcode:start': TranscodeJob;
    'transcode:fallback': {
        job: TranscodeJob;
        from: string;
        to: string;
    };
    'stream:metrics': StreamMetricsEvent;
    'dispose': {
        id: string;
    };
    'segment:processed': {
        segmentNumber: number;
        processingTime: number;
    };
    'pipeline:metrics': any;
}
interface DetailedVideoQuality extends VideoQuality {
    width: number;
    height: number;
}
export declare class Stream extends ExtendedEventEmitter<StreamEventMap> {
    private readonly quality;
    private readonly type;
    private readonly source;
    private readonly streamIndex;
    private readonly metadata;
    private readonly maxSegmentBatchSize;
    private readonly qualityService;
    private readonly hwDetector;
    private readonly optimisedAccel;
    private readonly jobProcessor;
    private static readonly DEFAULT_CONFIG;
    private readonly videoQuality;
    private readonly audioQuality;
    private readonly segments;
    private readonly jobRange;
    private readonly config;
    private readonly metrics;
    private readonly cachedHwOptions;
    private readonly segmentRetries;
    private readonly pipelineProcessor;
    private timer;
    private hasFallenBackToSoftware;
    private readonly streamCreatedAt;
    private lastActivityAt;
    private metricsTimer;
    private constructor();
    /**
     * Create a new stream
     * @param quality - The quality of the stream
     * @param type - The type of the stream (audio or video)
     * @param streamIndex - The index of the stream
     * @param source - The media source
     * @param maxSegmentBatchSize - The maximum number of segments to process at once
     * @param qualityService - The quality service
     * @param metadataService - The metadata service
     * @param hwDetector - The hardware acceleration detector
     * @param hwAccel - The hardware acceleration configuration
     * @param config - The stream configuration
     * @param jobProcessor - The job processor
     */
    static create(quality: string, type: StreamType, streamIndex: number, source: MediaSource, maxSegmentBatchSize: number, qualityService: QualityService, metadataService: MetadataService, hwDetector: HardwareAccelerationDetector, hwAccel: HardwareAccelerationConfig | null, config: Partial<StreamConfig>, jobProcessor: JobProcessor): TaskEither<Stream>;
    /**
    * Get the stream ID
    * @param fileId - The file ID
    * @param type - The type of the stream (audio or video)
    * @param quality - The quality of the stream
    * @param streamIndex - The index of the stream
    */
    static getStreamId(fileId: string, type: StreamType, quality: string, streamIndex: number): string;
    /**
    * Extract subtitle from a media source and convert to WebVTT
    * @param mediaSource - The media source
    * @param streamIndex - The index of the subtitle stream
    */
    static getVTTSubtitle(mediaSource: MediaSource, streamIndex: number): Promise<NodeJS.ReadableStream>;
    /**
     * Get all convertible subtitle streams from media metadata
     * @param metadata - The media metadata
     */
    static getConvertibleSubtitles(metadata: MediaMetadata): SubtitleInfo[];
    /**
     * Check if a subtitle stream can be converted to VTT
     * @param subtitleStream - The subtitle stream
     */
    private static canConvertToVtt;
    /**
     * Run FFMPEG command
     * @param outputOptions - The output options to feed to the Ffmpeg
     * @param inputPath - The input path to the file to perform the command on
     */
    private static runFFMPEGCommand;
    /**
     * Create a screenshot from a media source at a specific timestamp
     * @param timestamp - The timestamp of the screenshot to be created
     */
    generateScreenshot(timestamp: number): Promise<NodeJS.ReadableStream>;
    /**
     * Get the file ID
     */
    getFileId(): string;
    /**
     * Builds the transcode command for the stream
     * @param segmentIndex - The index of the segment
     * @param priority - The priority of the segment
     */
    buildTranscodeCommand(segmentIndex: number, priority: number): TaskEither<void>;
    /**
     * Get the segment stream for a specific segment
     * @param segmentIndex - The index of the segment
     * @param priority - The priority of the segment
     */
    getSegmentStream(segmentIndex: number, priority: number): TaskEither<SegmentStream>;
    /**
     * Get the stream ID
     */
    getStreamId(): string;
    /**
     * Creates a new playlist for the stream
     */
    getPlaylist(): string;
    /**
     * Builds the video quality for the stream
     * @param quality - The video quality to build
     * @param index - The index of the video stream
     */
    buildVideoQuality(quality: VideoQualityEnum, index?: number): DetailedVideoQuality;
    /**
     * Builds the audio quality for the stream
     * @param quality - The audio quality to build
     * @param index - The index of the audio stream
     */
    buildAudioQuality(quality: AudioQualityEnum, index?: number): AudioQuality;
    /**
     * Dispose of the stream
     */
    dispose(): Promise<Result<void>>;
    /**
     * Generate and emit comprehensive stream metrics
     */
    private emitMetrics;
    /**
     * Calculate current segment states
     */
    private calculateSegmentStates;
    /**
     * Initialize the stream
     */
    private initialise;
    /**
     * Start a timer to periodically emit metrics
     */
    private startPeriodicMetrics;
    /**
     * Get dynamic batch size based on hardware acceleration
     */
    private getDynamicBatchSize;
    /**
     * Get dynamic pipeline depth based on hardware acceleration and system resources
     */
    private getDynamicPipelineDepth;
    /**
     * Get cached hardware acceleration options
     * Uses optimisedAccel unless we've fallen back to software
     * @param width - Video width
     * @param height - Video height
     * @param codec - Codec type
     */
    private getCachedHardwareOptions;
    /**
     * Check if an error is related to hardware acceleration
     * @param err - The error to check
     */
    private isHardwareAccelerationError;
    /**
     * Fallback to software encoding while preserving the original optimized config
     */
    private fallbackToSoftwareEncoding;
    /**
     * Get the segment for this stream (Audio)
     * @param segment - The segment to process
     * @param priority - The priority of the segment
     */
    private buildAudioTranscodeOptions;
    /**
     * Build the FFMPEG command for video transcoding
     * @param segment - The segment to process
     * @param priority - The priority of the segment
     */
    private buildVideoTranscodeOptions;
    /**
     * Build the segments for this stream
     */
    private buildSegments;
    /**
     * Check the status of the segments
     */
    private checkSegmentsStatus;
    /**
     * Check if the segment file exists
     * @param segment - The segment to check
     */
    private checkSegmentFileStatus;
    /**
     * Intelligently filter and prepare segments for processing
     * Only processes segments that actually need work, respects ongoing jobs
     * @param initialSegment - The segment to start processing from
     */
    private filterAndPrepareSegments;
    /**
     * Generate FFMPEG transcoding arguments for processing segments
     */
    private getTranscodeArgs;
    private calculateSegmentTimings;
    private calculateNonFirstSegmentTimings;
    private calculateStartTime;
    private extractTimestamps;
    private formatTimestamps;
    private formatRelativeTimestamps;
    private createBaseFFMPEGOptions;
    private mergeFFMPEGOptions;
    /**
     * Build the FFMPEG command for transcoding
     */
    private buildFFMPEGCommand;
    /**
     * Execute the actual Ffmpeg transcoding command
     */
    private executeTranscodeCommand;
    /**
     * Setup and run the Ffmpeg command with proper event handling
     */
    private setupAndRunCommand;
    /**
     * Create the Ffmpeg command with options
     */
    private createFfmpegCommand;
    /**
     * Create a transcode job
     */
    private createTranscodeJob;
    /**
     * Create a job range
     */
    private createJobRange;
    /**
     * Set up comprehensive event handlers for the Ffmpeg command
     * @param command - The Ffmpeg command
     * @param job - The transcode job
     * @param jobRange - The job range
     * @param segments - The segments being processed
     * @param resolve - Resolve function
     * @param reject - Reject function
     */
    private setupCommandEventHandlers;
    /**
     * Handle segment progress updates
     * @param segmentIndex - The index of the segment
     */
    private handleSegmentProgress;
    /**
     * Handle transcoding errors with potential hardware acceleration fallback
     * @param err - The error that occurred
     * @param job - The job that was processing
     * @param jobRange - The job range that was processing
     * @param segments - The segments that were being processed
     * @param lastIndex - The last index processed
     * @param disposeHandler - The disposed handler to call
     */
    private handleTranscodeError;
    /**
     * Check if we should retry with fallback
     * @param err - The error to check
     * @param segmentIndex - The index of the segment
     */
    private shouldRetryWithFallback;
    /**
     * Retry transcoding with software fallback
     * @param segment - The segment to retry
     * @param originalJob - The original job
     * @param lock - The distributed lock (if any)
     * @param resolve - Resolve function
     * @param reject - Reject function
     */
    private retryWithFallback;
    /**
     * Update metrics on successful completion
     * @param segmentCount - Number of segments processed
     * @param processingTime - Time taken to process segments
     */
    private updateMetricsOnSuccess;
    /**
     * Calculate the closest multiple of x to n
     */
    private closestMultiple;
    /**
     * Load the quality of the stream
     */
    private loadQuality;
    /**
     * Debounce the dispose method
     */
    private debounceDispose;
    /**
     * Calculate distance from current encoders to a segment
     * @param segmentIndex - The index of the segment
     */
    private getMinEncoderDistance;
    /**
     * Check if a segment is already scheduled for processing
     * @param segmentIndex - The index of the segment
     */
    private isSegmentScheduled;
    /**
     * Check if hardware acceleration is being used
     */
    private isUsingHardwareAcceleration;
    /**
     * Get the current acceleration method
     */
    private getCurrentAccelerationMethod;
}
export {};
//# sourceMappingURL=stream.d.ts.map