Initial commit: sanitize repository for remote push

This commit is contained in:
theshy
2026-03-21 01:36:28 +08:00
commit 3925cb508f
21 changed files with 3357 additions and 0 deletions

126
monitor.py Normal file
View File

@ -0,0 +1,126 @@
import os
import shutil
import subprocess
import time
import sys
from pathlib import Path
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
from logger import get_system_logger, log_exception
# ==========================================
# 接口配置
# ==========================================
STAGE_DIR = r'./stage'
BACKUP_DIR = r'./backup'
SESSION_DIR = r'./session'
MIN_DURATION_SECONDS = 15 * 60
VIDEO_EXTS = {'.mp4', '.mkv', '.avi', '.mov', '.flv', '.wmv'}
# 初始化日志
logger = get_system_logger('monitor')
# ==========================================
def get_video_duration(file_path):
try:
cmd = ['ffprobe', '-v', 'error', '-show_entries', 'format=duration', '-of', 'default=noprint_wrappers=1:nokey=1', str(file_path)]
result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
duration = float(result.stdout)
logger.debug(f"获取视频时长: {file_path.name} = {duration}")
return duration
except Exception as e:
log_exception(logger, e, f"获取视频时长失败: {file_path}")
return 0
class VideoHandler(FileSystemEventHandler):
def on_created(self, event):
if not event.is_directory:
# 兼容处理 watchdog 路径编码问题
src_path = event.src_path
if isinstance(src_path, bytes):
src_path = src_path.decode('utf-8')
logger.debug(f"检测到文件创建事件: {src_path}")
self.handle_file(Path(src_path))
def handle_file(self, file_path):
if file_path.suffix.lower() not in VIDEO_EXTS:
logger.debug(f"跳过非视频文件: {file_path.name}")
return
logger.info(f"发现新视频文件: {file_path.name},正在检查写入状态...")
# 改进:通过检查文件大小变化来判断是否写入完成
last_size = -1
while True:
try:
if not file_path.exists():
logger.warning(f"文件在检查期间消失: {file_path}")
return
current_size = file_path.stat().st_size
if current_size == last_size and current_size > 0:
break
last_size = current_size
time.sleep(5) # 每5秒检查一次大小
except Exception as e:
logger.error(f"检查文件状态异常: {e}")
break
try:
duration = get_video_duration(file_path)
logger.info(f"视频时长: {file_path.name} = {duration/60:.1f} 分钟")
if duration < MIN_DURATION_SECONDS:
logger.info(f"时长不足 {MIN_DURATION_SECONDS/60:.0f} 分钟,移动到备份区")
dst = Path(BACKUP_DIR) / file_path.name
shutil.move(str(file_path), str(dst))
logger.info(f"已移动至备份: {dst}")
else:
# 核心联动:创建专属工作区
session_folder = Path(SESSION_DIR) / file_path.stem
session_folder.mkdir(parents=True, exist_ok=True)
logger.info(f"创建工作区: {session_folder}")
logger.info(f"派发转录任务: {file_path.name}")
# 改进:使用 sys.executable 保证环境一致性
process = subprocess.Popen([
sys.executable, 'video2srt.py',
str(file_path),
str(session_folder)
])
logger.info(f"转录进程已启动 (PID: {process.pid})")
except Exception as e:
log_exception(logger, e, "监控处理异常")
if __name__ == "__main__":
logger.info("="*50)
logger.info("视频监控模块启动")
logger.info("="*50)
for d in [STAGE_DIR, BACKUP_DIR, SESSION_DIR]:
Path(d).mkdir(parents=True, exist_ok=True)
logger.info(f"监控目录: {STAGE_DIR}")
logger.info(f"备份目录: {BACKUP_DIR}")
logger.info(f"工作目录: {SESSION_DIR}")
handler = VideoHandler()
# 启动时扫描已有文件
logger.info("正在扫描 stage 目录下的存量视频...")
for f in Path(STAGE_DIR).iterdir():
if f.is_file():
handler.handle_file(f)
observer = Observer()
observer.schedule(handler, STAGE_DIR, recursive=False)
observer.start()
logger.info("文件监控已启动")
try:
while True: time.sleep(1)
except KeyboardInterrupt:
logger.info("接收到停止信号,正在关闭...")
observer.stop()
observer.join()
logger.info("视频监控模块已停止")