Queue a draft Take (#51) #105
No reviewers
Labels
No labels
bug
duplicate
enhancement
help wanted
invalid
needs-info
needs-triage
question
ready-for-agent
ready-for-human
wayfinder:grilling
wayfinder:map
wayfinder:prototype
wayfinder:research
wayfinder:task
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
crowmaki/ai-studio!105
Loading…
Reference in a new issue
No description provided.
Delete branch "issue-51-queue-draft-take"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #51.
What changed
Queuing a Take (
studio-core/src/takes.rs):queue_take(shot, TakeRequest { profile, seed })builds the wholeh3.draftjob at queue time. The Take gets these at once:shot.next_take_number, never reused), named12A-3Provenance: queuing also records what the Take was built from.
take_inputrow per reference sent. Each row has its slot number, medium, the exact bytes sent (as a blob) and real foreign keys to what it came from: the Lock snapshot, Keyframe, Tile, Character, Look, Wardrobe item, Prop or Location.takerow: the prompt text and the filled graph as blobs, the overridden flag, the workflow id/version/hash, the ratio, the W×H, the requested ms and the frame count.take(id)returns all of this asTakeDetail.Job builder: it fills the bindings, then makes the two structural edits:
LoadImage/LoadAudioper filled slot, wired into theMiniMaxH3ReferenceToVideoAutogrow ports in slot orderLoraLoaderModelOnlychain (enabled LoRAs only) on the manifest's chain point, with the shipped DMAD LoRA rewired to the chain's endSizes take the short side from the profile and the long side from the effective ratio, both rounded to ×32. The speed mode's step and strength values are applied. Each reference is uploaded under a name taken from its content hash, so the stored graph already names the exact files.
Slot media:
Rendition: the
renditionrow exists from queue time.renditions/<id>.{mp4,flac}andlatents/<id>.{video,audio}.latent.… [output]) for Promotion.Worker:
job_upload) withoverwrite=truebefore it submits.ffmpeg (
studio-core/src/ffmpeg.rs): only Rust calls it. It makes posters and joins audio. It is found throughAI_STUDIO_FFMPEG, then next to the app executable (where Tauri puts sidecars), then onPATH.studio:scheme:rendition/<id>serves a ready Rendition's video from the media folder, withAccept-Rangesand Range/206. That covers open-ended (capped at 4 MB a response), suffix and 416 cases. The Project lock is released before the file is read.Schema V23:
take,take_input,renditionandjob_uploadshot.next_take_numberkeyframe.deleted_atjobtable rebuilt with arendition_idtargetADR-0004:
is_consumedis now real.UI: each Shot lists its Takes with a poster and a Queued / Rendering % / Ready / Failed badge. A ready Take plays its draft inline.
ProfileEditor.svelte, shared with Project settings.Dialoggained awidesize.Screenshots
The queue dialog. A LoRA added for this Take only, so the profile is marked Changed, and a typed seed:
The Shot's Takes after rendering: two ready drafts with posters and a failed one. Its tooltip says "ComfyUI failed in UNETLoader: CUDA out of memory".
1A-1plays inline fromstudio://…/rendition/<id>, and seeking works through Range requests. The seed typed in the dialog (42) is the one recorded:These were taken in the running app against a stand-in ComfyUI (the test fake, serving an ffmpeg test pattern as the H3 output).
Testing
cargo test --workspace --all-featuresbun test src scriptsbun run checkcrates/studio-core/tests/takes.rschecks naming and numbering, the recorded inputs with slots and foreign keys, and the filled graph: loader wiring by content name, the LoRA chain order, size, steps and seed. Against the fake ComfyUI it also checks that the graph sent equals the recorded one, the uploads, the Rendition files in the media folder, the poster, failed renders, and a profile LoRA ComfyUI lacks. It also covers consumed-Keyframe soft delete with undo, the Shot/Setup delete refusal, and refusals that use no number (a bad profile, a seed ≥ 2^53).crates/studio-core/src/ffmpeg.rsunit tests run real ffmpeg for the poster and the join.src-tauri/tests/takes.rsqueues through the adapter, renders against the fake, and checks 200/206/416 Range serving.src/lib/scenes/takes.test.tscovers the badges, the seed parsing and the profile override.Review notes
externalBintotauri.conf.jsonwould breaktauri devand builds for anyone without the binary insrc-tauri/binaries/. So this PR finds ffmpeg at runtime instead: the env var, then next to the exe, thenPATH. Bundling an LGPL build (and a fetch script) can follow once we pick a build. Tests needffmpegonPATHorAI_STUDIO_FFMPEG.board_imagesalready does. Flattening the annotation layer in Rust is still to do.