drum-sample-extractor / docs /HIT_REVIEW_AND_STREAMING.md
ChatGPT
feat: add hit review and streaming progress
3703c4e
|
Raw
History Blame Contribute Delete
3.29 kB
# Hit review and progress streaming
Last updated: 2026-05-12
## Purpose
This pass moves the app closer to a review workstation by making detected hits individually inspectable and by replacing frontend-only polling with a server-sent-events progress channel.
## Implemented behavior
| Area | Implementation | Files |
|---|---|---|
| Review hit artifacts | Every accepted detected hit is written as an individual WAV under `review/hits/`. | `pipeline_runner.py` |
| Manifest hit rows | `manifest.json` now includes a top-level `hits` array with onset, duration, label, cluster, representative flag, and relative file path. | `pipeline_runner.py` |
| Hit URLs | API serialization adds direct download/playback URLs to every hit row. | `app.py` |
| Waveform selection | Clicking the waveform selects the nearest detected onset marker. | `web/app.js` |
| Hit audition | Clicking a hit row or waveform marker loads that hit into the selected-hit audio player. | `web/index.html`, `web/app.js` |
| Sample audition | Representative sample rows now have explicit Audition buttons and a dedicated selected-sample player. | `web/index.html`, `web/app.js` |
| SSE progress | `GET /api/jobs/{job_id}/events` streams job snapshots whenever state changes. | `app.py`, `web/app.js` |
| Poll fallback | The frontend falls back to polling if `EventSource` is unavailable or errors. | `web/app.js` |
| Artifact serving hardening | File downloads now use `Path.relative_to()` against the resolved run output directory. | `app.py` |
## Manifest shape additions
Completed results now include:
```json
{
"hits": [
{
"index": 0,
"label": "kick",
"cluster_id": 3,
"cluster_label": "kick_0",
"is_representative": true,
"onset_sec": 0.002993,
"duration_ms": 255.0,
"rms_energy": 0.141768,
"spectral_centroid_hz": 773.4,
"file": "review/hits/hit_00000_kick.wav"
}
]
}
```
API responses add `url` to each hit row, for example:
```json
{
"file": "review/hits/hit_00000_kick.wav",
"url": "/api/jobs/<job-id>/files/review/hits/hit_00000_kick.wav"
}
```
The `overview.onsets` entries now also carry `index` and `duration_sec`, allowing the waveform to map markers back to review hit rows.
## Streaming endpoint
`GET /api/jobs/{job_id}/events` returns `text/event-stream`.
Each emitted event has type `job` and contains the same serialized shape as `GET /api/jobs/{job_id}`:
```text
event: job
data: {"id":"...","status":"running",...}
```
The stream ends after `complete` or `error`. Completed historical jobs stream one final event and then close.
## Current limitations
- Hit review is read-only. It does not yet support delete/shift/relabel actions.
- Every accepted hit is exported as a WAV. This is correct for review UX, but large files with thousands of hits may produce many small artifacts.
- SSE streams job snapshots, not fine-grained internal Demucs progress.
- The waveform is an overview canvas, not an editable detailed waveform yet.
## Next editor step
Add an edit state layer on top of the hit manifest:
1. Mark hit deleted/restored.
2. Shift onset and duration bounds.
3. Reassign cluster label.
4. Merge/split clusters.
5. Re-render/repack from edited manifest without rerunning Demucs or onset detection.