import type { Channel, Nullable, ResolvedSiteProfile, UrlValidation } from "../types/index.js"; import type { Frame, Page } from "puppeteer-core"; import type { RecoveryMetrics, TabReplacementResult } from "./recovery.js"; import type { FFmpegProcess } from "../utils/index.js"; import type { Readable } from "node:stream"; /** * Factory function type for creating tab replacement handlers. Called by setupStream after generating stream IDs and resolving the profile, allowing the caller to * create a handler with access to all necessary context. */ export type TabReplacementHandlerFactory = (numericStreamId: number, streamId: string, profile: ResolvedSiteProfile, metadataComment: string | undefined) => () => Promise>; /** * Options for setting up a stream. */ export interface StreamSetupOptions { channel?: Channel; channelName?: string; channelSelector?: string; clickSelector?: string; clickToPlay?: boolean; noVideo?: boolean; onTabReplacementFactory?: TabReplacementHandlerFactory; profileOverride?: string; url: string; } /** * Result from setting up a stream. */ export interface StreamSetupResult { captureStream: Readable; channelName: Nullable; directTune: boolean; cleanup: () => Promise; ffmpegProcess: Nullable; numericStreamId: number; page: Page; profile: ResolvedSiteProfile; profileName: string; providerName: string; rawCaptureStream: Readable; startTime: Date; stopMonitor: () => RecoveryMetrics; streamId: string; url: string; } /** * Error thrown when stream setup fails. Includes HTTP status code and user-friendly message for the response. */ export declare class StreamSetupError extends Error { readonly statusCode: number; readonly userMessage: string; constructor(message: string, statusCode: number, userMessage: string); } /** * Options for creating a page with capture. */ export interface CreatePageWithCaptureOptions { comment?: string; onFFmpegError?: (error: Error) => void; profile: ResolvedSiteProfile; streamId: string; url: string; _pageClosedRetries?: number; } /** * Result from creating a page with capture. Contains everything needed to create a segmenter and continue with stream setup. */ export interface CreatePageWithCaptureResult { captureStream: Readable; context: Frame | Page; directTune: boolean; ffmpegProcess: Nullable; page: Page; rawCaptureStream: Readable; } /** * Generates a concise stream identifier for logging purposes. The identifier combines the channel name or hostname with a unique request ID, making it easy to * trace related log messages. We prefer the channel name when available because it's more meaningful than a hostname. * @param channelName - The channel name if streaming a named channel. * @param url - The URL being streamed. * @returns A concise stream identifier. */ export declare function generateStreamId(channelName: string | undefined, url: string | undefined): string; /** * Validates a URL before attempting to navigate to it. This function checks for supported protocols, prevents local file access, and ensures the URL is properly * formatted. Validating URLs before navigation prevents security issues and provides clear error messages. * @param url - The URL to validate. * @returns Validation result with optional reason for failure. */ export declare function validateStreamUrl(url: string | undefined): UrlValidation; /** * Creates a browser page with media capture and navigates to the URL. This is the reusable core function used by both initial stream setup and tab replacement * recovery. It handles: * - Creating a new browser page with CSP bypass * - Initializing media capture (native fMP4 or WebM+FFmpeg) * - Navigating to the URL with retry * - Setting up video playback via navigateToPage() + initializePlayback() * * The caller is responsible for: * - Creating the segmenter and piping captureStream to it * - Registering/updating the stream in the registry * - Starting/updating the health monitor * - Handling cleanup on failure * * @param options - Options for page and capture creation. * @returns The page, context, capture stream, and FFmpeg process (if any). * @throws Error if page creation, capture initialization, or navigation fails. */ export declare function createPageWithCapture(options: CreatePageWithCaptureOptions): Promise; /** * Sets up a stream: validates input, creates browser page, initializes capture, navigates to URL, and starts health monitoring. * * This function handles all common stream setup logic. The caller is responsible for: * - Connecting the returned captureStream to the appropriate output (HTTP response, FFmpeg, etc.) * - Registering the stream in the registry * - Triggering cleanup when the stream ends * * @param options - Stream configuration options. * @param onCircuitBreak - Callback invoked when the circuit breaker trips (stream unrecoverable). * @returns Setup result with capture stream, cleanup function, and metadata. * @throws StreamSetupError if setup fails with appropriate status code and message. */ export declare function setupStream(options: StreamSetupOptions, onCircuitBreak: () => void): Promise; /** * Verifies that Chrome's capture system is functional before the server starts accepting requests. This detects stale tabCapture state left over from a previous * Chrome process — common during quick service restarts where the old process hasn't fully exited before the new one launches. Without this probe, the first stream * request would trigger the runtime stale capture handler, which exits the process because the puppeteer-stream mutex is permanently leaked. * * The probe creates a temporary page, attempts a short capture, and tears down both cleanly. A 500ms delay after destroying the capture stream allows * puppeteer-stream's fire-and-forget STOP_RECORDING chain to complete before closing the page, preventing the stale capture cascade on the first real request. * * After a system reboot, Chrome's display stack or capture extension may not be ready when the service manager starts PrismCast. The probe retries up to * PROBE_MAX_ATTEMPTS times with a delay between attempts, giving the system time to settle before giving up. This prevents a rapid restart storm where the service * manager relaunches PrismCast repeatedly, each attempt orphaning a Chrome process and degrading the environment further. * * If stale capture state is detected, the process exits immediately — Chrome restart cannot fix the leaked mutex, only a fresh process can. */ export declare function verifyCaptureSystem(): Promise;