import os from dataclasses import dataclass from typing import Dict, List, Optional, Union import logging from dotenv import load_dotenv load_dotenv() @dataclass class FFmpegConfig: """FFmpeg相关配置""" encoder_args: List[str] video_args: List[str] audio_args: List[str] default_args: List[str] old_ffmpeg: bool = False re_encode_video_args: Optional[List[str]] = None re_encode_encoder_args: Optional[List[str]] = None @classmethod def from_env(cls) -> 'FFmpegConfig': encoder_args = os.getenv("ENCODER_ARGS", "-c:v h264").split(" ") video_args = os.getenv("VIDEO_ARGS", "-profile:v high -level:v 4").split(" ") audio_args = ["-c:a", "aac", "-b:a", "128k", "-ar", "48000", "-ac", "2"] default_args = ["-shortest"] re_encode_video_args = None if os.getenv("RE_ENCODE_VIDEO_ARGS"): re_encode_video_args = os.getenv("RE_ENCODE_VIDEO_ARGS").split(" ") re_encode_encoder_args = None if os.getenv("RE_ENCODE_ENCODER_ARGS"): re_encode_encoder_args = os.getenv("RE_ENCODE_ENCODER_ARGS").split(" ") return cls( encoder_args=encoder_args, video_args=video_args, audio_args=audio_args, default_args=default_args, old_ffmpeg=bool(os.getenv("OLD_FFMPEG", False)), re_encode_video_args=re_encode_video_args, re_encode_encoder_args=re_encode_encoder_args ) @dataclass class APIConfig: """API相关配置""" endpoint: str access_key: str timeout: int = 10 redirect_to_url: Optional[str] = None @classmethod def from_env(cls) -> 'APIConfig': endpoint = os.getenv('API_ENDPOINT', '') if not endpoint: raise ValueError("API_ENDPOINT environment variable is required") access_key = os.getenv('ACCESS_KEY', '') if not access_key: raise ValueError("ACCESS_KEY environment variable is required") return cls( endpoint=endpoint, access_key=access_key, timeout=int(os.getenv('API_TIMEOUT', '10')), redirect_to_url=os.getenv("REDIRECT_TO_URL") or None ) @dataclass class StorageConfig: """存储相关配置""" template_dir: str @classmethod def from_env(cls) -> 'StorageConfig': template_dir = os.getenv('TEMPLATE_DIR', './template') return cls(template_dir=template_dir) @dataclass class ServerConfig: """服务器相关配置""" host: str = "0.0.0.0" port: int = 9998 debug: bool = False @classmethod def from_env(cls) -> 'ServerConfig': return cls( host=os.getenv('HOST', '0.0.0.0'), port=int(os.getenv('PORT', '9998')), debug=bool(os.getenv('DEBUG', False)) ) @dataclass class AppConfig: """应用总配置""" ffmpeg: FFmpegConfig api: APIConfig storage: StorageConfig server: ServerConfig @classmethod def from_env(cls) -> 'AppConfig': return cls( ffmpeg=FFmpegConfig.from_env(), api=APIConfig.from_env(), storage=StorageConfig.from_env(), server=ServerConfig.from_env() ) # 全局配置实例 _config: Optional[AppConfig] = None def get_config() -> AppConfig: """获取全局配置实例""" global _config if _config is None: _config = AppConfig.from_env() return _config def reload_config() -> AppConfig: """重新加载配置""" global _config _config = AppConfig.from_env() return _config # 向后兼容的配置获取函数 def get_ffmpeg_config() -> FFmpegConfig: return get_config().ffmpeg def get_api_config() -> APIConfig: return get_config().api def get_storage_config() -> StorageConfig: return get_config().storage def get_server_config() -> ServerConfig: return get_config().server