from typing import Dict, Literal, Optional from pydantic import BaseModel, Field, SecretStr from pydantic_settings import BaseSettings class RouteConfig(BaseModel): """Configuration for a specific route""" proxy: bool = True proxy_url: Optional[str] = None verify_ssl: bool = True class TransportConfig(BaseSettings): """Main proxy configuration""" proxy_url: Optional[str] = Field( None, description="Primary proxy URL. Example: socks5://user:pass@proxy:1080 or http://proxy:8080" ) disable_ssl_verification_globally: bool = Field( False, description="Disable SSL verification for all requests globally." ) all_proxy: bool = Field(False, description="Enable proxy for all routes by default") transport_routes: Dict[str, RouteConfig] = Field( default_factory=dict, description="Pattern-based route configuration" ) timeout: int = Field(60, description="Timeout for HTTP requests in seconds") class Config: env_file = ".env" extra = "ignore" class Settings(BaseSettings): api_password: str | None = None # The password for protecting the API endpoints. log_level: str = "INFO" # The logging level to use. transport_config: TransportConfig = Field(default_factory=TransportConfig) # Configuration for HTTP transport. enable_streaming_progress: bool = False # Whether to enable streaming progress tracking. disable_home_page: bool = False # Whether to disable the home page UI. disable_docs: bool = False # Whether to disable the API documentation (Swagger UI). disable_speedtest: bool = False # Whether to disable the speedtest UI. clear_cache_on_startup: bool = ( False # Whether to clear all caches (extractor, MPD, etc.) on startup. Useful for development. ) stremio_proxy_url: str | None = None # The Stremio server URL for alternative content proxying. m3u8_content_routing: Literal["mediaflow", "stremio", "direct"] = ( "mediaflow" # Routing strategy for M3U8 content URLs: "mediaflow", "stremio", or "direct" ) enable_hls_prebuffer: bool = True # Whether to enable HLS pre-buffering for improved streaming performance. livestream_start_offset: ( float | None ) = -18 # Default start offset for live streams (e.g., -18 to start 18 seconds behind live edge). Applies to HLS and MPD live playlists. Set to None to disable. hls_prebuffer_segments: int = 5 # Number of segments to pre-buffer ahead. hls_prebuffer_cache_size: int = 50 # Maximum number of segments to cache in memory. hls_prebuffer_max_memory_percent: int = 80 # Maximum percentage of system memory to use for HLS pre-buffer cache. hls_prebuffer_emergency_threshold: int = 90 # Emergency threshold percentage to trigger aggressive cache cleanup. hls_prebuffer_inactivity_timeout: int = 60 # Seconds of inactivity before stopping playlist refresh loop. hls_segment_cache_ttl: int = 300 # TTL (seconds) for cached HLS segments; 300s (5min) for VOD, lower for live. enable_dash_prebuffer: bool = True # Whether to enable DASH pre-buffering for improved streaming performance. dash_prebuffer_segments: int = 5 # Number of segments to pre-buffer ahead. dash_prebuffer_cache_size: int = 50 # Maximum number of segments to cache in memory. dash_prebuffer_max_memory_percent: int = 80 # Maximum percentage of system memory to use for DASH pre-buffer cache. dash_prebuffer_emergency_threshold: int = 90 # Emergency threshold percentage to trigger aggressive cache cleanup. dash_prebuffer_inactivity_timeout: int = 60 # Seconds of inactivity before cleaning up stream state. dash_segment_cache_ttl: int = 60 # TTL (seconds) for cached media segments; longer = better for slow playback. mpd_live_init_cache_ttl: int = 60 # TTL (seconds) for live init segment cache; 0 disables caching. mpd_live_playlist_depth: int = 8 # Number of recent segments to expose per live playlist variant. remux_to_ts: bool = False # Remux fMP4 segments to MPEG-TS for ExoPlayer/VLC compatibility. processed_segment_cache_ttl: int = 60 # TTL (seconds) for caching processed (decrypted/remuxed) segments. # FlareSolverr settings (for Cloudflare bypass) flaresolverr_url: str | None = None # FlareSolverr service URL. Example: http://localhost:8191 flaresolverr_timeout: int = 60 # Timeout (seconds) for FlareSolverr requests. # Acestream settings enable_acestream: bool = False # Whether to enable Acestream proxy support. acestream_host: str = "localhost" # Acestream engine host. acestream_port: int = 6878 # Acestream engine port. acestream_buffer_size: int = 4 * 1024 * 1024 # Buffer size for MPEG-TS streaming (4MB default, like acexy). acestream_empty_timeout: int = 30 # Timeout (seconds) when no data is received from upstream. acestream_session_timeout: int = 60 # Session timeout (seconds) for cleanup of inactive sessions. acestream_keepalive_interval: int = 15 # Interval (seconds) for session keepalive polling. # Telegram MTProto settings enable_telegram: bool = False # Whether to enable Telegram MTProto proxy support. telegram_api_id: int | None = None # Telegram API ID from https://my.telegram.org/apps telegram_api_hash: SecretStr | None = None # Telegram API hash from https://my.telegram.org/apps telegram_session_string: SecretStr | None = None # Persistent session string (avoids re-authentication). telegram_max_connections: int = 8 # Max parallel DC connections for downloads (max 20, careful of floods). telegram_request_timeout: int = 30 # Request timeout in seconds. # Transcode settings enable_transcode: bool = True # Whether to enable on-the-fly transcoding endpoints (MKV→fMP4, HLS VOD). transcode_prefer_gpu: bool = True # Prefer GPU acceleration (NVENC/VideoToolbox/VAAPI) when available. transcode_video_bitrate: str = "4M" # Target video bitrate for re-encoding (e.g. "4M", "2000k"). transcode_audio_bitrate: int = 192000 # AAC audio bitrate in bits/s for the Python transcode pipeline. transcode_video_preset: str = "medium" # Encoding speed/quality tradeoff (libx264: ultrafast..veryslow). user_agent: str = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36" # The user agent to use for HTTP requests. # Upstream error resilience settings upstream_retry_on_disconnect: bool = True # Enable/disable retry when upstream disconnects mid-stream. upstream_retry_attempts: int = 2 # Number of retry attempts when upstream disconnects during streaming. upstream_retry_delay: float = 1.0 # Delay (seconds) between retry attempts. graceful_stream_end: bool = True # Return valid empty playlist instead of error when upstream fails. # Redis settings redis_url: str | None = None # Redis URL for distributed locking and caching. None = disabled. cache_namespace: str | None = ( None # Optional namespace for instance-specific caches (e.g. pod name or hostname). When set, extractor results and other IP-bound data are stored under this namespace so multiple pods sharing one Redis don't serve each other's IP-specific URLs. ) class Config: env_file = ".env" extra = "ignore" settings = Settings()