@eleven-am/transcoder
Version:
High-performance HLS transcoding library with hardware acceleration, intelligent client management, and distributed processing support for Node.js
332 lines • 11.5 kB
TypeScript
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;
};
}
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 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 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;
/**
* Prefetch upcoming segments to improve performance
* @param currentIndex - The current segment index being processed
* @param priority - The priority of the current segment
*/
private prefetchSegments;
/**
* 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;
/**
* Optimize batch of segments for efficient FFmpeg processing
* Groups consecutive segments to minimize FFmpeg invocations
*/
private optimizeBatchForProcessing;
/**
* Generate FFMPEG transcoding arguments for processing segments
*/
private getTranscodeArgs;
/**
* 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