docs: rebuild HTML + WASM doc after identity PATCH update

This commit is contained in:
M5Max128
2026-05-22 10:08:08 +08:00
parent 2b025a014e
commit 3e81f7c16b
4 changed files with 511 additions and 3 deletions

View File

@@ -81,6 +81,211 @@ a { color: #0066cc; }
<p><strong>Auth</strong>: Required
<strong>Scope</strong>: file-level</p>
<hr />
<h3><code>GET /api/v1/file/:file_uuid/trace/:trace_id/representative-face</code></h3>
<p>Find the best single face to represent this trace. Uses a two-stage selection: SQL (area × confidence → top 10) then FFmpeg <code>blurdetect</code> (sharpness → pick the least blurry).</p>
<p><strong>Auth</strong>: Required
<strong>Scope</strong>: file-level</p>
<h4>Example</h4>
<div class="codehilite"><pre><span></span><code>curl<span class="w"> </span>-s<span class="w"> </span><span class="s2">&quot;</span><span class="nv">$API</span><span class="s2">/api/v1/file/</span><span class="nv">$FILE_UUID</span><span class="s2">/trace/1939/representative-face&quot;</span><span class="w"> </span><span class="se">\</span>
<span class="w"> </span>-H<span class="w"> </span><span class="s2">&quot;X-API-Key: </span><span class="nv">$KEY</span><span class="s2">&quot;</span>
</code></pre></div>
<h4>Response (200)</h4>
<div class="codehilite"><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;success&quot;</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;file_uuid&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;aeed71342a899fe4b4c57b7d41bcb692&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;trace_id&quot;</span><span class="p">:</span><span class="w"> </span><span class="mi">1939</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;face_count&quot;</span><span class="p">:</span><span class="w"> </span><span class="mi">538</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;representative&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;frame_number&quot;</span><span class="p">:</span><span class="w"> </span><span class="mi">68193</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;timestamp_secs&quot;</span><span class="p">:</span><span class="w"> </span><span class="mf">2727.72</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;bbox&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nt">&quot;x&quot;</span><span class="p">:</span><span class="w"> </span><span class="mi">347</span><span class="p">,</span><span class="w"> </span><span class="nt">&quot;y&quot;</span><span class="p">:</span><span class="w"> </span><span class="mi">378</span><span class="p">,</span><span class="w"> </span><span class="nt">&quot;width&quot;</span><span class="p">:</span><span class="w"> </span><span class="mi">427</span><span class="p">,</span><span class="w"> </span><span class="nt">&quot;height&quot;</span><span class="p">:</span><span class="w"> </span><span class="mi">427</span><span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;confidence&quot;</span><span class="p">:</span><span class="w"> </span><span class="mf">0.760</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;quality_score&quot;</span><span class="p">:</span><span class="w"> </span><span class="mi">138516</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;blur_score&quot;</span><span class="p">:</span><span class="w"> </span><span class="mf">9.46</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</code></pre></div>
<h4>Response Fields</h4>
<table class="table">
<thead>
<tr>
<th>Field</th>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>trace_id</code></td>
<td>integer</td>
<td>Face trace ID</td>
</tr>
<tr>
<td><code>face_count</code></td>
<td>integer</td>
<td>Total face detections in this trace</td>
</tr>
<tr>
<td><code>representative.frame_number</code></td>
<td>integer</td>
<td>Frame number of the selected face (primary coordinate)</td>
</tr>
<tr>
<td><code>representative.timestamp_secs</code></td>
<td>float</td>
<td>Time in seconds (derived from <code>frame_number / fps</code>)</td>
</tr>
<tr>
<td><code>representative.bbox</code></td>
<td>object</td>
<td>Bounding box <code>{x, y, width, height}</code></td>
</tr>
<tr>
<td><code>representative.confidence</code></td>
<td>float</td>
<td>Detection confidence (0.01.0)</td>
</tr>
<tr>
<td><code>representative.quality_score</code></td>
<td>float</td>
<td>Pre-selection score (<code>area × confidence</code>)</td>
</tr>
<tr>
<td><code>representative.blur_score</code></td>
<td>float</td>
<td>FFmpeg blurdetect result (lower = sharper)</td>
</tr>
</tbody>
</table>
<h4>Error Responses</h4>
<hr />
<h3><code>GET /api/v1/file/:file_uuid/trace/:trace_id/thumbnail</code></h3>
<p>Extract the best face image for a trace as JPEG (320×320). Internally selects the face using the same two-stage algorithm as <code>representative-face</code>, then crops via FFmpeg. The result is cacheable for 24 hours.</p>
<p><strong>Auth</strong>: Required
<strong>Scope</strong>: file-level</p>
<h4>Example</h4>
<div class="codehilite"><pre><span></span><code>curl<span class="w"> </span>-s<span class="w"> </span><span class="s2">&quot;</span><span class="nv">$API</span><span class="s2">/api/v1/file/</span><span class="nv">$FILE_UUID</span><span class="s2">/trace/1939/thumbnail&quot;</span><span class="w"> </span><span class="se">\</span>
<span class="w"> </span>-H<span class="w"> </span><span class="s2">&quot;X-API-Key: </span><span class="nv">$KEY</span><span class="s2">&quot;</span><span class="w"> </span>-o<span class="w"> </span>trace_1939_face.jpg
</code></pre></div>
<h4>Response</h4>
<ul>
<li><strong>200</strong>: <code>image/jpeg</code> binary data (320×320 cropped face)</li>
<li><strong>404</strong>: File, trace not found, or no suitable face</li>
<li><strong>500</strong>: FFmpeg or database error</li>
</ul>
<hr />
<h3><code>GET /api/v1/file/:file_uuid/identities/:identity_uuid_a/co-occur-with/:identity_uuid_b</code></h3>
<p>Find the first frame where two identities appear together, with representative face thumbnails for both.</p>
<p><strong>Auth</strong>: Required
<strong>Scope</strong>: file-level</p>
<h4>Example</h4>
<div class="codehilite"><pre><span></span><code><span class="c1"># Audrey Hepburn &amp; Cary Grant 第一次同框</span>
curl<span class="w"> </span>-s<span class="w"> </span><span class="s2">&quot;</span><span class="nv">$API</span><span class="s2">/api/v1/file/</span><span class="nv">$FILE_UUID</span><span class="s2">/identities/</span><span class="nv">$AUDREY_UUID</span><span class="s2">/co-occur-with/</span><span class="nv">$CARY_UUID</span><span class="s2">&quot;</span><span class="w"> </span><span class="se">\</span>
<span class="w"> </span>-H<span class="w"> </span><span class="s2">&quot;X-API-Key: </span><span class="nv">$KEY</span><span class="s2">&quot;</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>jq<span class="w"> </span><span class="s1">&#39;{identity_a: .identity_a.name, identity_b: .identity_b.name, first_frame: .first_cooccurrence.frame_number}&#39;</span>
</code></pre></div>
<h4>Response (200)</h4>
<div class="codehilite"><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;success&quot;</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;file_uuid&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;aeed71342a899fe4b4c57b7d41bcb692&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;identity_a&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;identity_uuid&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;c3545906-c82d-4b66-aa1d-150bc02decce&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;name&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Audrey Hepburn&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;trace_id&quot;</span><span class="p">:</span><span class="w"> </span><span class="mi">920</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;identity_b&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;identity_uuid&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;2b0ddefe-e2a9-4533-9308-b375594604d5&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;name&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Cary Grant&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;trace_id&quot;</span><span class="p">:</span><span class="w"> </span><span class="mi">919</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;first_cooccurrence&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;frame_number&quot;</span><span class="p">:</span><span class="w"> </span><span class="mi">38165</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;timestamp_secs&quot;</span><span class="p">:</span><span class="w"> </span><span class="mf">1526.60</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;total_cooccurrence_frames&quot;</span><span class="p">:</span><span class="w"> </span><span class="mi">3136</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;representative_face_a&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;frame_number&quot;</span><span class="p">:</span><span class="w"> </span><span class="mi">38199</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;bbox&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nt">&quot;x&quot;</span><span class="p">:</span><span class="w"> </span><span class="mi">122</span><span class="p">,</span><span class="w"> </span><span class="nt">&quot;y&quot;</span><span class="p">:</span><span class="w"> </span><span class="mi">339</span><span class="p">,</span><span class="w"> </span><span class="nt">&quot;width&quot;</span><span class="p">:</span><span class="w"> </span><span class="mi">176</span><span class="p">,</span><span class="w"> </span><span class="nt">&quot;height&quot;</span><span class="p">:</span><span class="w"> </span><span class="mi">176</span><span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;confidence&quot;</span><span class="p">:</span><span class="w"> </span><span class="mf">0.832</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;thumbnail_url&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;/api/v1/file/aeed71342.../trace/920/thumbnail&quot;</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;representative_face_b&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;frame_number&quot;</span><span class="p">:</span><span class="w"> </span><span class="mi">38291</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;bbox&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nt">&quot;x&quot;</span><span class="p">:</span><span class="w"> </span><span class="mi">511</span><span class="p">,</span><span class="w"> </span><span class="nt">&quot;y&quot;</span><span class="p">:</span><span class="w"> </span><span class="mi">315</span><span class="p">,</span><span class="w"> </span><span class="nt">&quot;width&quot;</span><span class="p">:</span><span class="w"> </span><span class="mi">192</span><span class="p">,</span><span class="w"> </span><span class="nt">&quot;height&quot;</span><span class="p">:</span><span class="w"> </span><span class="mi">192</span><span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;confidence&quot;</span><span class="p">:</span><span class="w"> </span><span class="mf">0.791</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;thumbnail_url&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;/api/v1/file/aeed71342.../trace/919/thumbnail&quot;</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</code></pre></div>
<h4>Response Fields</h4>
<table class="table">
<thead>
<tr>
<th>Field</th>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>identity_a.name</code></td>
<td>string</td>
<td>First identity name</td>
</tr>
<tr>
<td><code>identity_b.name</code></td>
<td>string</td>
<td>Second identity name</td>
</tr>
<tr>
<td><code>first_cooccurrence.frame_number</code></td>
<td>int</td>
<td>First frame where both appear</td>
</tr>
<tr>
<td><code>first_cooccurrence.timestamp_secs</code></td>
<td>float</td>
<td>Time in seconds</td>
</tr>
<tr>
<td><code>first_cooccurrence.total_cooccurrence_frames</code></td>
<td>int</td>
<td>Total frames with both present</td>
</tr>
<tr>
<td><code>first_cooccurrence.representative_face_a/b</code></td>
<td>object</td>
<td>Best face thumbnail data for each identity</td>
</tr>
</tbody>
</table>
<h4>Error Responses</h4>
<table class="table">
<thead>
<tr>
<th>HTTP</th>
<th>When</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>404</code></td>
<td>File or identity not found</td>
</tr>
<tr>
<td><code>404</code></td>
<td>The two identities never co-occur in this file</td>
</tr>
<tr>
<td><code>500</code></td>
<td>Database or FFmpeg error</td>
</tr>
</tbody>
</table>
<h3><code>GET /api/v1/file/:file_uuid/video/bbox</code></h3>
<p>Stream video with bounding box overlay for all detected objects/faces.</p>
<p><strong>Auth</strong>: Required