feat: representative frame - auto-detect thumbnail + JSON endpoint
This commit is contained in:
@@ -33,6 +33,10 @@ pub fn trace_agent_routes() -> Router<crate::api::types::AppState> {
|
||||
"/api/v1/file/:file_uuid/tkg/rebuild",
|
||||
post(rebuild_tkg),
|
||||
)
|
||||
.route(
|
||||
"/api/v1/file/:file_uuid/representative-frame",
|
||||
get(get_representative_frame),
|
||||
)
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
@@ -783,3 +787,59 @@ async fn rebuild_tkg(
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
// ── Representative Frame (JSON) ───────────────────────────────────
|
||||
|
||||
use crate::core::processor::tkg;
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct RepFrameResponse {
|
||||
success: bool,
|
||||
file_uuid: String,
|
||||
frame_number: i64,
|
||||
timestamp_secs: f64,
|
||||
face_quality: f64,
|
||||
main_identities: Vec<tkg::MainIdentityInfo>,
|
||||
traces: Vec<tkg::FrameTraceInfo>,
|
||||
}
|
||||
|
||||
async fn get_representative_frame(
|
||||
State(state): State<crate::api::types::AppState>,
|
||||
Path(file_uuid): Path<String>,
|
||||
) -> Result<Json<RepFrameResponse>, (StatusCode, Json<serde_json::Value>)> {
|
||||
let result = tkg::query_auto_representative_frame(
|
||||
state.db.pool(),
|
||||
&file_uuid,
|
||||
)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
(StatusCode::NOT_FOUND, Json(serde_json::json!({"error": e.to_string()})))
|
||||
})?;
|
||||
|
||||
let fps = query_fps(state.db.pool(), &file_uuid).await;
|
||||
|
||||
Ok(Json(RepFrameResponse {
|
||||
success: true,
|
||||
file_uuid,
|
||||
frame_number: result.frame_number,
|
||||
timestamp_secs: result.frame_number as f64 / fps,
|
||||
face_quality: result.face_quality,
|
||||
main_identities: result.main_identities,
|
||||
traces: result.traces,
|
||||
}))
|
||||
}
|
||||
|
||||
async fn query_fps(pool: &sqlx::PgPool, file_uuid: &str) -> f64 {
|
||||
use crate::core::db::schema;
|
||||
let video_table = schema::table_name("videos");
|
||||
sqlx::query_scalar(&format!(
|
||||
"SELECT COALESCE(fps, 25.0) FROM {} WHERE file_uuid = $1",
|
||||
video_table
|
||||
))
|
||||
.bind(file_uuid)
|
||||
.fetch_optional(pool)
|
||||
.await
|
||||
.ok()
|
||||
.flatten()
|
||||
.unwrap_or(25.0)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user