# -*- coding: utf-8 -*- """ 通用工具函数 提供跨模块使用的通用功能 """ import os import re import subprocess import logging logger = logging.getLogger(__name__) def ensure_dir(path): """确保目录存在""" os.makedirs(path, exist_ok=True) return path def get_clip_num(path): """从路径中提取clip编号""" match = re.search(r'clip(\d+)', path) return int(match.group(1)) if match else 0 def run_cmd(cmd, capture=True, timeout=300): """ 执行shell命令 Args: cmd: 命令字符串 capture: 是否捕获输出 timeout: 超时时间(秒) Returns: True if success, False otherwise """ try: if capture: result = subprocess.run( cmd, shell=True, capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=timeout ) return result.returncode == 0 else: result = subprocess.run(cmd, shell=True, timeout=timeout) return result.returncode == 0 except subprocess.TimeoutExpired: logger.error(f"Command timeout: {cmd[:100]}...") return False except Exception as e: logger.error(f"Command failed: {e}") return False def to_srt_time(t): """将秒数转换为SRT时间格式 (HH:MM:SS,mmm)""" hours = int(t // 3600) minutes = int((t % 3600) // 60) seconds = int(t % 60) millis = int((t % 1) * 1000) return f"{hours:02d}:{minutes:02d}:{seconds:02d},{millis:03d}" def to_ass_time(t): """将秒数转换为ASS时间格式 (HH:MM:SS.cc)""" hours = int(t // 3600) minutes = int((t % 3600) // 60) seconds = int(t % 60) centis = int((t % 1) * 100) return f"{hours:02d}:{minutes:02d}:{seconds:02d}.{centis:02d}" def format_duration(seconds): """格式化时长为可读字符串""" if seconds < 60: return f"{seconds:.1f}秒" elif seconds < 3600: return f"{seconds/60:.1f}分钟" else: return f"{seconds/3600:.1f}小时" def format_filesize(bytes_size): """格式化文件大小为可读字符串""" mb = bytes_size / (1024 * 1024) if mb < 1024: return f"{mb:.1f} MB" else: return f"{mb/1024:.1f} GB" class SubtitleError(Exception): """字幕处理异常""" pass class VideoError(Exception): """视频处理异常""" pass class LLMError(Exception): """LLM调用异常""" pass