""" 本地配音历史:扫描 outputs/ 下已生成的 wav,供 Gradio 下拉试听与下载。 文件不会被自动删除,重启服务后仍可访问。 """ from __future__ import annotations import logging from datetime import datetime from pathlib import Path from typing import List, Tuple from config import OUTPUT_DIR logger = logging.getLogger(__name__) HISTORY_MAX_ITEMS = 50 VOICEOVER_GLOB = "voiceover_*.wav" def list_voice_history(limit: int = HISTORY_MAX_ITEMS) -> List[Tuple[str, str]]: """ 返回 Gradio Dropdown 选项:(显示名, 文件绝对路径),按时间倒序。 """ if not OUTPUT_DIR.is_dir(): return [] files = sorted( OUTPUT_DIR.glob(VOICEOVER_GLOB), key=lambda p: p.stat().st_mtime, reverse=True, )[:limit] choices: List[Tuple[str, str]] = [] for path in files: try: st = path.stat() except OSError: logger.debug("跳过不可读历史文件: %s", path) continue ts = datetime.fromtimestamp(st.st_mtime).strftime("%Y-%m-%d %H:%M") size_mb = st.st_size / (1024 * 1024) label = f"{ts} · {path.name} ({size_mb:.1f} MB)" choices.append((label, str(path.resolve()))) return choices def latest_voice_path() -> str | None: """最新一条配音路径,无历史时返回 None。""" items = list_voice_history(limit=1) return items[0][1] if items else None