Initial commit: sanitize repository for remote push
This commit is contained in:
126
monitor.py
Normal file
126
monitor.py
Normal 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("视频监控模块已停止")
|
||||
Reference in New Issue
Block a user