# -*- coding: utf-8 -*- """ 环境配置和常量定义 所有硬编码路径和配置集中管理,确保可维护性 """ import os import sys import shutil # ============== 项目根目录 ============== def _get_project_root(): """获取项目根目录""" # Assume this file is in src/core/, so project root is 2 levels up return os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) PROJECT_ROOT = _get_project_root() # ============== FFmpeg路径(动态检测)============== def _find_ffmpeg(): """动态查找FFmpeg路径""" # 1. Check local ffmpeg folder (for portable distribution) # Direct: ffmpeg/bin/ffmpeg.exe local_ffmpeg = os.path.join(PROJECT_ROOT, "ffmpeg", "bin") if os.path.exists(os.path.join(local_ffmpeg, "ffmpeg.exe")): return local_ffmpeg # Nested: ffmpeg/ffmpeg-8.1-full_build/bin/ffmpeg.exe ffmpeg_base = os.path.join(PROJECT_ROOT, "ffmpeg") if os.path.isdir(ffmpeg_base): for subdir in os.listdir(ffmpeg_base): nested_path = os.path.join(ffmpeg_base, subdir, "bin") if os.path.exists(os.path.join(nested_path, "ffmpeg.exe")): return nested_path # 2. Check system PATH system_ffmpeg = shutil.which("ffmpeg") if system_ffmpeg: return os.path.dirname(system_ffmpeg) # 3. Return empty - will fail later with clear error return "" FFMPEG_BIN = _find_ffmpeg() FFMPEG_CMD = os.path.join(FFMPEG_BIN, "ffmpeg.exe") if FFMPEG_BIN else "ffmpeg" FFPROBE_CMD = os.path.join(FFMPEG_BIN, "ffprobe.exe") if FFMPEG_BIN else "ffprobe" # ============== Whisper模型(动态检测)============== def _find_whisper_model(): """查找Whisper模型路径""" # 1. Check local whisper_models folder local_models = os.path.join(PROJECT_ROOT, "whisper_models") if os.path.exists(local_models): # Find any model folder for name in os.listdir(local_models): model_path = os.path.join(local_models, name) if os.path.isdir(model_path): return model_path.replace('\\', '/') # 2. Check environment variable env_path = os.environ.get("WHISPER_MODEL_PATH") if env_path and os.path.exists(env_path): return env_path.replace('\\', '/') # 3. Default path (for this user's environment) default_path = r"D:/AI/LM-Models/faster-whisper/large-v3" if os.path.exists(default_path): return default_path.replace('\\', '/') return "" WHISPER_MODEL_PATH = _find_whisper_model() # ============== 输出目录默认值 ============== DEFAULT_OUTPUT_DIR = os.path.join(PROJECT_ROOT, "output") # ============== 视频参数默认值 ============== DEFAULT_VIDEO_PARAMS = { "fade_duration": 1, "title_duration": 3, "title_fontsize": 60, "title_color": "FFFF00", "subtitle_fontsize": 24, "subtitle_color": "FFFFFF", "use_fast_whisper": True, "whisper_model": "large", } # ============== API配置 ============== DEFAULT_API_HOST = "https://ark.cn-beijing.volces.com/api/coding/v3" API_KEY_ENVS = ["VOLCENGINE_API_KEY", "MINIMAX_API_KEY"] # ============== LLM配置 ============== LLM_MODEL = "doubao-seed-2.0-lite" LLM_TIMEOUT = 60 LLM_MAX_RETRIES = 3 LLM_TITLE_TIMEOUT = 60 LLM_VALIDATE_TIMEOUT = 30 # ============== 字幕样式 ============== SUBTITLE_STYLE = "FontName=微软雅黑,FontSize=24,PrimaryColour=&H00FFFFFF" # ============== Windows控制台编码 ============== def setup_windows_encoding(): """Windows控制台UTF-8编码设置""" if sys.platform == 'win32': import io sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace') sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8', errors='replace') # ============== FFmpeg PATH设置 ============== def setup_ffmpeg_path(): """将FFmpeg添加到PATH(仅当使用本地FFmpeg时)""" if FFMPEG_BIN and FFMPEG_BIN not in os.environ.get('PATH', ''): os.environ['PATH'] = FFMPEG_BIN + os.pathsep + os.environ.get('PATH', '') # ============== 环境初始化 ============== def init_environment(): """初始化环境设置""" setup_windows_encoding() setup_ffmpeg_path() def get_api_key(): """获取API密钥""" for env_name in API_KEY_ENVS: key = os.environ.get(env_name) if key: return key return None