diff --git a/fam-edge/src/fam_edge/video_processor.py b/fam-edge/src/fam_edge/video_processor.py index c326ef5..ef3b4f3 100644 --- a/fam-edge/src/fam_edge/video_processor.py +++ b/fam-edge/src/fam_edge/video_processor.py @@ -24,7 +24,21 @@ logger = setup_logger('fam-edge.video_processor') def _parse_event_start_from_filename(filename: str) -> str: - """从监控文件名解析开始时间(北京时间)。示例: 2026-08-21_081500.mp4""" + """从监控文件名解析开始时间(北京时间)。 + + 支持格式: + - 2026-08-21_081500.mp4 / 20260821_081500.mp4(带/不带分隔符日期) + - Generic_ONVIF-001-20260820-140416-xxx.mp4(纯数字 YYYYMMDD-HHMMSS) + """ + # 纯数字: YYYYMMDD-HHMMSS 或 YYYYMMDDHHMMSS(监控录像文件名格式) + m0 = re.search(r'(\d{4})(\d{2})(\d{2})[-_]?(\d{2})(\d{2})(\d{2})', filename) + if m0: + y, mo, d, hh, mm, ss = m0.groups() + try: + dt = datetime(int(y), int(mo), int(d), int(hh), int(mm), int(ss)) + return dt.strftime('%Y-%m-%d %H:%M:%S') + except ValueError: + pass m = re.search(r'(\d{4})[-_](\d{2})[-_](\d{2})[_-]?(\d{2})(\d{2})(\d{2})', filename) if m: y, mo, d, hh, mm, ss = m.groups() @@ -50,10 +64,19 @@ def _parse_event_ts(ts: str, start_dt): m = re.match(r'^(\d{1,2}):(\d{2}):(\d{2})$', ts) if m: off = int(m.group(1)) * 3600 + int(m.group(2)) * 60 + int(m.group(3)) + # 启发式:监控单段通常 ≤1h,相对时间超过 6h 视为模型误输出绝对时间(无日期),不强行定位 + if off <= 6 * 3600: + if start_dt is not None: + abs_ts = (start_dt + timedelta(seconds=off)).strftime('%Y-%m-%d %H:%M:%S') + return abs_ts, float(off) + return ts, float(off) if start_dt is not None: - abs_ts = (start_dt + timedelta(seconds=off)).strftime('%Y-%m-%d %H:%M:%S') - return abs_ts, float(off) - return ts, float(off) + try: + ev_dt = datetime.strptime(ts[:19], '%Y-%m-%d %H:%M:%S') + return ts, (ev_dt - start_dt).total_seconds() + except ValueError: + pass + return ts, 0.0 if start_dt is not None: try: ev_dt = datetime.strptime(ts[:19], '%Y-%m-%d %H:%M:%S')