feat: dual input (start_frame/end_frame + start_time/end_time) + all outputs include frames, time, fps
This commit is contained in:
@@ -36,10 +36,10 @@ struct TracesRequest {
|
||||
struct TraceInfo {
|
||||
trace_id: i32,
|
||||
face_count: i64,
|
||||
first_frame: i32,
|
||||
last_frame: i32,
|
||||
first_sec: f64,
|
||||
last_sec: f64,
|
||||
start_frame: i32,
|
||||
end_frame: i32,
|
||||
start_time: f64,
|
||||
end_time: f64,
|
||||
duration_sec: f64,
|
||||
avg_confidence: f64,
|
||||
sample_face_id: Option<String>,
|
||||
@@ -49,6 +49,7 @@ struct TraceInfo {
|
||||
struct TracesResponse {
|
||||
success: bool,
|
||||
file_uuid: String,
|
||||
fps: f64,
|
||||
total_traces: i64,
|
||||
total_faces: i64,
|
||||
page: i64,
|
||||
@@ -73,8 +74,8 @@ async fn list_traces_sorted(
|
||||
|
||||
let order_clause = match sort {
|
||||
"face_count" => "face_count DESC",
|
||||
"duration" => "(MAX(frame_number) - MIN(frame_number)) DESC",
|
||||
_ => "first_frame ASC",
|
||||
"duration" => "duration_sec DESC",
|
||||
_ => "start_frame ASC",
|
||||
};
|
||||
|
||||
let fps: f64 =
|
||||
@@ -87,12 +88,13 @@ async fn list_traces_sorted(
|
||||
.unwrap_or(24.0);
|
||||
|
||||
let query = format!(
|
||||
"SELECT tt.*, fd.id AS sample_face_id, {} AS video_fps FROM (
|
||||
"SELECT tt.*, fd.id AS sample_face_id FROM (
|
||||
SELECT trace_id,
|
||||
COUNT(*) AS face_count,
|
||||
MIN(frame_number) AS first_frame,
|
||||
MAX(frame_number) AS last_frame,
|
||||
AVG(confidence) AS avg_confidence
|
||||
MIN(frame_number) AS start_frame,
|
||||
MAX(frame_number) AS end_frame,
|
||||
(MAX(frame_number) - MIN(frame_number))::float8 AS duration_sec,
|
||||
AVG(confidence)::float8 AS avg_confidence
|
||||
FROM {}
|
||||
WHERE file_uuid = $1 AND trace_id IS NOT NULL
|
||||
AND confidence >= $5 AND confidence <= $6
|
||||
@@ -106,13 +108,12 @@ async fn list_traces_sorted(
|
||||
WHERE trace_id = tt.trace_id AND file_uuid = $1
|
||||
ORDER BY confidence DESC LIMIT 1
|
||||
) fd ON true",
|
||||
crate::core::db::schema::table_name("videos"),
|
||||
crate::core::db::schema::table_name("face_detections"),
|
||||
order_clause,
|
||||
crate::core::db::schema::table_name("face_detections"),
|
||||
);
|
||||
|
||||
let rows: Vec<(i32, i64, i32, i32, f64, f64, f64, f64, Option<String>)> =
|
||||
let rows: Vec<(i32, i64, i32, i32, f64, f64, Option<i32>)> =
|
||||
sqlx::query_as(&query)
|
||||
.bind(&file_uuid)
|
||||
.bind(min_faces)
|
||||
@@ -126,16 +127,16 @@ async fn list_traces_sorted(
|
||||
|
||||
let traces: Vec<TraceInfo> = rows
|
||||
.into_iter()
|
||||
.map(|(tid, fc, ff, lf, fs, ls, dur, conf, fid)| TraceInfo {
|
||||
.map(|(tid, fc, sf, ef, dur, conf, fid)| TraceInfo {
|
||||
trace_id: tid,
|
||||
face_count: fc,
|
||||
first_frame: ff,
|
||||
last_frame: lf,
|
||||
first_sec: fs,
|
||||
last_sec: ls,
|
||||
duration_sec: dur,
|
||||
start_frame: sf,
|
||||
end_frame: ef,
|
||||
start_time: sf as f64 / fps,
|
||||
end_time: ef as f64 / fps,
|
||||
duration_sec: dur / fps,
|
||||
avg_confidence: conf,
|
||||
sample_face_id: fid,
|
||||
sample_face_id: fid.map(|v| v.to_string()),
|
||||
})
|
||||
.collect();
|
||||
|
||||
@@ -151,6 +152,7 @@ async fn list_traces_sorted(
|
||||
Ok(Json(TracesResponse {
|
||||
success: true,
|
||||
file_uuid,
|
||||
fps,
|
||||
total_traces,
|
||||
total_faces,
|
||||
page,
|
||||
@@ -174,7 +176,9 @@ struct TraceFacesQuery {
|
||||
struct TraceFaceItem {
|
||||
id: i32,
|
||||
start_frame: i32,
|
||||
end_frame: i32,
|
||||
start_time: f64,
|
||||
end_time: f64,
|
||||
x: Option<i32>,
|
||||
y: Option<i32>,
|
||||
width: Option<i32>,
|
||||
@@ -188,6 +192,7 @@ struct TraceFacesResponse {
|
||||
success: bool,
|
||||
file_uuid: String,
|
||||
trace_id: i32,
|
||||
fps: f64,
|
||||
total: i64,
|
||||
faces: Vec<TraceFaceItem>,
|
||||
}
|
||||
@@ -274,10 +279,13 @@ async fn list_trace_faces(
|
||||
let mid_w = lerp_i32(prev.4, *w, t);
|
||||
let mid_h = lerp_i32(prev.5, *h, t);
|
||||
let mid_frame = prev_frame + mid;
|
||||
let mt = (mid_frame as f64 / fps * 10.0).round() / 10.0;
|
||||
faces.push(TraceFaceItem {
|
||||
id: 0,
|
||||
start_frame: mid_frame,
|
||||
start_time: (mid_frame as f64 / fps * 10.0).round() / 10.0,
|
||||
end_frame: mid_frame,
|
||||
start_time: mt,
|
||||
end_time: mt,
|
||||
x: mid_x,
|
||||
y: mid_y,
|
||||
width: mid_w,
|
||||
@@ -291,10 +299,13 @@ async fn list_trace_faces(
|
||||
|
||||
// Add the real detection
|
||||
let frame_val = *frame;
|
||||
let ft = (frame_val as f64 / fps * 10.0).round() / 10.0;
|
||||
faces.push(TraceFaceItem {
|
||||
id: *id,
|
||||
start_frame: frame_val,
|
||||
start_time: (frame_val as f64 / fps * 10.0).round() / 10.0,
|
||||
end_frame: frame_val,
|
||||
start_time: ft,
|
||||
end_time: ft,
|
||||
x: *x,
|
||||
y: *y,
|
||||
width: *w,
|
||||
@@ -314,6 +325,7 @@ async fn list_trace_faces(
|
||||
success: true,
|
||||
file_uuid,
|
||||
trace_id,
|
||||
fps,
|
||||
total,
|
||||
faces,
|
||||
}))
|
||||
|
||||
Reference in New Issue
Block a user