fix: handle no_faces case - TKG proceeds without waiting for face_traced.json

- Check face.json status before waiting for face_traced.json
- If status='no_faces', spawn TKG immediately (no face_track nodes)
- If status='has_faces', wait for face_traced.json
- Prevents infinite wait when video has no faces
This commit is contained in:
Accusys
2026-07-20 22:34:09 +08:00
parent 5ec18ed520
commit bc914ce3df
+86 -16
View File
@@ -2102,29 +2102,53 @@ impl JobWorker {
if tkg_done { if tkg_done {
info!("✅ TKG already built for {}, skipping spawn", uuid); info!("✅ TKG already built for {}, skipping spawn", uuid);
} else { } else {
// Check if face_traced.json exists (store_traced_faces.py completed) // Check face.json status first
let traced_path = format!( let face_json_path = format!(
"{}{}.face_traced.json", "{}{}.face.json",
crate::core::config::OUTPUT_DIR.as_str().trim_end_matches('/'), crate::core::config::OUTPUT_DIR.as_str().trim_end_matches('/'),
uuid uuid
); );
if !std::path::Path::new(&traced_path).exists() { let has_faces = if std::path::Path::new(&face_json_path).exists() {
info!( if let Ok(content) = std::fs::read_to_string(&face_json_path) {
"⏳ TKG build waiting for face_traced.json: {} (file_uuid={})", if let Ok(face_data) = serde_json::from_str::<serde_json::Value>(&content) {
traced_path, uuid face_data.get("status")
); .and_then(|s| s.as_str())
// Don't spawn TKG yet, wait for next poll .map(|s| s == "has_faces")
.unwrap_or(false)
} else {
false
}
} else {
false
}
} else { } else {
info!( false
"📝 Prerequisites met for TKG Build (face_traced.json exists): {}", };
if has_faces {
// Has faces - wait for face_traced.json
let traced_path = format!(
"{}{}.face_traced.json",
crate::core::config::OUTPUT_DIR.as_str().trim_end_matches('/'),
uuid uuid
); );
let db_clone = self.db.clone();
let redis_clone = self.redis.clone(); if !std::path::Path::new(&traced_path).exists() {
let uuid_clone = uuid.to_string(); info!(
let output_dir_clone = crate::core::config::OUTPUT_DIR.clone(); "⏳ TKG build waiting for face_traced.json: {} (file_uuid={})",
tokio::spawn(async move { traced_path, uuid
);
} else {
info!(
"📝 Prerequisites met for TKG Build (face_traced.json exists): {}",
uuid
);
let db_clone = self.db.clone();
let redis_clone = self.redis.clone();
let uuid_clone = uuid.to_string();
let output_dir_clone = crate::core::config::OUTPUT_DIR.clone();
tokio::spawn(async move {
match crate::core::processor::tkg::build_tkg( match crate::core::processor::tkg::build_tkg(
&db_clone, &db_clone,
&uuid_clone, &uuid_clone,
@@ -2209,6 +2233,52 @@ impl JobWorker {
} }
}); });
} }
} else {
// No faces detected - spawn TKG without waiting for face_traced.json
info!(
"📝 TKG Build proceeding without face_traced.json (no faces detected): {}",
uuid
);
let db_clone = self.db.clone();
let redis_clone = self.redis.clone();
let uuid_clone = uuid.to_string();
let output_dir_clone = crate::core::config::OUTPUT_DIR.clone();
tokio::spawn(async move {
match crate::core::processor::tkg::build_tkg(
&db_clone,
&uuid_clone,
&output_dir_clone,
Some(redis_clone.clone()),
)
.await
{
Ok(r) => {
let total_nodes = r.face_track_nodes
+ r.gaze_track_nodes
+ r.lip_track_nodes
+ r.text_region_nodes
+ r.appearance_trace_nodes
+ r.accessory_nodes
+ r.object_nodes
+ r.hand_nodes
+ r.speaker_nodes;
let total_edges = r.co_occurrence_edges
+ r.speaker_face_edges
+ r.face_face_edges
+ r.mutual_gaze_edges
+ r.lip_sync_edges
+ r.has_appearance_edges
+ r.wears_edges
+ r.hand_object_edges;
info!(
"✅ TKG build completed (no faces) for {}: {} nodes, {} edges",
uuid_clone, total_nodes, total_edges
);
}
Err(e) => error!("❌ TKG build failed for {}: {}", uuid_clone, e),
}
});
}
} }
} }