[优化] 时间轴/统计过滤空会话 - 只展示运动片段(motion_)或有事件的视频, 整段素材分割0段的空会话不占时间轴; get_sync_videos/get_sync_stats 加内容过滤
This commit is contained in:
@@ -106,31 +106,35 @@ def get_sync_videos(limit=15, offset=0, date_filter=None) -> List[Dict]:
|
|||||||
排序/日期维度按视频实际录制时间(event_start_time,文件名解析),
|
排序/日期维度按视频实际录制时间(event_start_time,文件名解析),
|
||||||
为空回退 processed_at/updated_at/created_at。
|
为空回退 processed_at/updated_at/created_at。
|
||||||
date_filter 形如 '2026-08-21'。
|
date_filter 形如 '2026-08-21'。
|
||||||
|
只返回"有内容"的会话:运动片段(filename 前缀 motion_)或含事件的视频;
|
||||||
|
整段素材分割 0 段的空会话(历史素材无运动事件)不展示,避免淹没时间轴。
|
||||||
"""
|
"""
|
||||||
conn = get_conn()
|
conn = get_conn()
|
||||||
try:
|
try:
|
||||||
cur = conn.cursor(pymysql.cursors.DictCursor)
|
cur = conn.cursor(pymysql.cursors.DictCursor)
|
||||||
# 录制时间优先,回退分析时间
|
# 录制时间优先,回退分析时间
|
||||||
date_expr = "COALESCE(NULLIF(event_start_time,''), processed_at, updated_at, created_at)"
|
date_expr = "COALESCE(NULLIF(event_start_time,''), processed_at, updated_at, created_at)"
|
||||||
|
content_filter = ("v.filename LIKE 'motion_%' "
|
||||||
|
"OR EXISTS(SELECT 1 FROM sync_events se WHERE se.video_id = v.id)")
|
||||||
if date_filter:
|
if date_filter:
|
||||||
cur.execute(
|
cur.execute(
|
||||||
f"""SELECT id, filename, camera_name, event_start_time, status,
|
f"""SELECT v.id, v.filename, v.camera_name, v.event_start_time, v.status,
|
||||||
summary_json, events_json, people_json, compute_provider,
|
v.summary_json, v.events_json, v.people_json, v.compute_provider,
|
||||||
processed_at, updated_at,
|
v.processed_at, v.updated_at,
|
||||||
(SELECT COUNT(*) FROM sync_events se WHERE se.video_id = sync_videos.id) AS event_count
|
(SELECT COUNT(*) FROM sync_events se WHERE se.video_id = v.id) AS event_count
|
||||||
FROM sync_videos
|
FROM sync_videos v
|
||||||
WHERE status='done' AND {date_expr} LIKE %s
|
WHERE v.status='done' AND ({content_filter}) AND {date_expr} LIKE %s
|
||||||
ORDER BY {date_expr} DESC
|
ORDER BY {date_expr} DESC
|
||||||
LIMIT %s OFFSET %s""",
|
LIMIT %s OFFSET %s""",
|
||||||
(f'{date_filter}%', limit, offset))
|
(f'{date_filter}%', limit, offset))
|
||||||
else:
|
else:
|
||||||
cur.execute(
|
cur.execute(
|
||||||
f"""SELECT id, filename, camera_name, event_start_time, status,
|
f"""SELECT v.id, v.filename, v.camera_name, v.event_start_time, v.status,
|
||||||
summary_json, events_json, people_json, compute_provider,
|
v.summary_json, v.events_json, v.people_json, v.compute_provider,
|
||||||
processed_at, updated_at,
|
v.processed_at, v.updated_at,
|
||||||
(SELECT COUNT(*) FROM sync_events se WHERE se.video_id = sync_videos.id) AS event_count
|
(SELECT COUNT(*) FROM sync_events se WHERE se.video_id = v.id) AS event_count
|
||||||
FROM sync_videos
|
FROM sync_videos v
|
||||||
WHERE status='done'
|
WHERE v.status='done' AND ({content_filter})
|
||||||
ORDER BY {date_expr} DESC
|
ORDER BY {date_expr} DESC
|
||||||
LIMIT %s OFFSET %s""",
|
LIMIT %s OFFSET %s""",
|
||||||
(limit, offset))
|
(limit, offset))
|
||||||
@@ -524,19 +528,25 @@ def get_sync_stats(date_str: str = None) -> Dict:
|
|||||||
if date_str:
|
if date_str:
|
||||||
cur.execute(
|
cur.execute(
|
||||||
"""SELECT
|
"""SELECT
|
||||||
COUNT(*) AS videos,
|
(SELECT COUNT(*) FROM sync_videos sv
|
||||||
|
WHERE sv.status='done'
|
||||||
|
AND (sv.filename LIKE 'motion_%'
|
||||||
|
OR EXISTS(SELECT 1 FROM sync_events se WHERE se.video_id=sv.id))
|
||||||
|
AND {d} LIKE %s) AS videos,
|
||||||
(SELECT COUNT(*) FROM sync_events se
|
(SELECT COUNT(*) FROM sync_events se
|
||||||
JOIN sync_videos sv ON se.video_id=sv.id
|
JOIN sync_videos sv ON se.video_id=sv.id
|
||||||
WHERE {d} LIKE %s) AS events,
|
WHERE {d} LIKE %s) AS events,
|
||||||
(SELECT COALESCE(SUM(se.is_attention_event),0) FROM sync_events se
|
(SELECT COALESCE(SUM(se.is_attention_event),0) FROM sync_events se
|
||||||
JOIN sync_videos sv ON se.video_id=sv.id
|
JOIN sync_videos sv ON se.video_id=sv.id
|
||||||
WHERE {d} LIKE %s) AS attention
|
WHERE {d} LIKE %s) AS attention""".format(d=_D),
|
||||||
FROM sync_videos sv WHERE {d} LIKE %s""".format(d=_D),
|
|
||||||
(f'{date_str}%', f'{date_str}%', f'{date_str}%'))
|
(f'{date_str}%', f'{date_str}%', f'{date_str}%'))
|
||||||
else:
|
else:
|
||||||
cur.execute(
|
cur.execute(
|
||||||
"""SELECT
|
"""SELECT
|
||||||
(SELECT COUNT(*) FROM sync_videos WHERE status='done') AS videos,
|
(SELECT COUNT(*) FROM sync_videos
|
||||||
|
WHERE status='done'
|
||||||
|
AND (filename LIKE 'motion_%'
|
||||||
|
OR EXISTS(SELECT 1 FROM sync_events se WHERE se.video_id=sync_videos.id))) AS videos,
|
||||||
(SELECT COUNT(*) FROM sync_events) AS events,
|
(SELECT COUNT(*) FROM sync_events) AS events,
|
||||||
(SELECT COALESCE(SUM(is_attention_event),0) FROM sync_events) AS attention""")
|
(SELECT COALESCE(SUM(is_attention_event),0) FROM sync_events) AS attention""")
|
||||||
stat = cur.fetchone() or {}
|
stat = cur.fetchone() or {}
|
||||||
|
|||||||
Reference in New Issue
Block a user