Files
vfxreview/prisma/migrations/20260922000000_version_handles/migration.sql
T
twotalesanimation 2e9fa45580
Deploy / deploy (push) Successful in 3m31s
feat(review): flag handles in the review player (metadata only)
Renders run 8 frames past the cut at each end. Directors were flagging
glitches in unfixed handles as shot problems, so the player now marks
them — without trimming or burning anything into the EXRs/MOV/MP4.

- Version.handleHead/handleTail/pictureStartFrame, Export.handleHead/
  handleTail; migration backfills pipeline exports and their preview
  versions from the manifest's handleFrames (else 8)
- AE panel: "Includes handles [8] frames each end" -> manifest.review;
  older manifests fall back to source.handleFrames
- finalize copies handles onto the Version; worker 1.6.4 reports the
  head slate length (pictureStartSeconds), else the player infers it
  as MP4 frames - EXR frameCount
- Player: hatched HANDLE / SLATE regions and cut marks on the timeline,
  "HEAD/TAIL HANDLE · NOT IN EDIT" overlay on handle frames, HANDLE badge
  on notes, "Edit range only" toggle (default on in the client portal)
- Staff Handles editor on the review page for manual uploads/corrections

Also fixes two player bugs found while testing: timeToFrame floored
float error (every seek landed a frame early), and J/reverse never ran
(the keyboard effect's cleanup stopped it on the next render).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-22 15:07:29 +02:00

38 lines
1.5 KiB
SQL

-- Handles: frames rendered past the cut at each end of a shot. They ship with
-- the EXRs but are not in the edit, so the review player flags them. Purely
-- metadata — nothing renders differently.
ALTER TABLE "versions" ADD COLUMN "handleHead" INTEGER;
ALTER TABLE "versions" ADD COLUMN "handleTail" INTEGER;
ALTER TABLE "versions" ADD COLUMN "pictureStartFrame" INTEGER;
ALTER TABLE "exports" ADD COLUMN "handleHead" INTEGER;
ALTER TABLE "exports" ADD COLUMN "handleTail" INTEGER;
-- Backfill pipeline exports. Every render so far was queued by the panel with
-- its Handle Frames setting (8 unless changed); the value is in the render
-- manifest when the panel found a timing plate, otherwise use the house 8.
UPDATE "exports" e
SET "handleHead" = h.frames, "handleTail" = h.frames
FROM (
SELECT e2."id",
COALESCE(
(SELECT (rj."manifest"->'source'->>'handleFrames')::int
FROM "render_jobs" rj
WHERE rj."exportId" = e2."id"
AND rj."type" = 'AE_RENDER'
AND jsonb_typeof(rj."manifest"->'source'->'handleFrames') = 'number'
ORDER BY rj."createdAt" DESC
LIMIT 1),
8
) AS frames
FROM "exports" e2
) h
WHERE h."id" = e."id";
-- ...and the preview Versions they produced. pictureStartFrame stays null:
-- the player infers the head slate from the MP4 length vs the EXR frameCount.
UPDATE "versions" v
SET "handleHead" = e."handleHead", "handleTail" = e."handleTail"
FROM "exports" e
WHERE e."versionId" = v."id";