color-grading
Color grading video in the AI Edit Video system - delog/tonemap HDR-HLG-log footage, apply the color preset the user approved in the UI, and the visual verification workflow. Read when the edit prompt
SKILL.md.claude/skills/color-grading/SKILL.md
GitHubColor Grading - grading video footage
Rule #1: the preview IS the final result
The user already APPROVED the color in the web UI based on a preview generated from the canonical filter chains in
apps/server/src/color.ts (GRADE_PRESETS). When applying it to the real video you MUST use that exact filter chain
- do not invent your own, do not "improve it further". A different chain = a color that no longer matches what the user picked.
Source of truth for presets + manual adjustments
Read apps/server/src/color.ts:
GRADE_PRESETS- 14 color templates (tu-nhien, tuoi-sang, vivid, cinematic, teal-orange, film-vintage, mau-phim, golden-hour, am, lanh, dem-xanh, moody, pastel, den-trang) with their -vf chains.GradeAdjust- the user's manual tweaks stacked ON TOP of the preset (brightness/contrast/ saturation/gamma viaeq,colortemperature,vibrance); thebuildFilterChain(preset, tonemap, adjust)function assembles them in the correct order: tonemap -> preset -> manual adjustments.- The edit prompt already prints the complete -vf chain for each asset - JUST USE IT VERBATIM.
Delog / HDR tonemap (insert BEFORE the preset)
Inspect the footage with ffprobe:
ffprobe -v error -select_streams v:0 -show_entries stream=color_transfer,color_primaries -of csv=p=0 input.mp4
If color_transfer is arib-std-b67 (HLG - iPhone/Android HDR capture) or smpte2084 (HDR10),
or color_primaries is bt2020 -> insert the tonemap BEFORE the preset:
zscale=t=linear:npl=100,tonemap=hable:desat=0,zscale=p=bt709:t=bt709:m=bt709:r=tv,format=yuv420p
Professional camera log (S-Log3, D-Log, V-Log...) whose metadata does not declare HDR needs the vendor's .cube LUT -
if that LUT is not in the system, tell the user instead of guessing.
Workflow for grading one video
- Probe the color (command above) -> decide whether a tonemap is needed.
- Produce the graded version (high quality encode, audio untouched):
ffmpeg -y -i assets/source.mp4 -vf "<tonemap-if-needed>,<preset-chain>" -c:v libx264 -crf 16 -preset medium -c:a copy assets/source.graded.mp4
- Visual verification (mandatory): extract 3 frames (start / middle / end) of the graded version and LOOK at each one: are skin tones natural and not blown out orange? are highlights not clipped? are blacks not crushed? If something is wrong -> report back, do NOT silently change the filter (the user locked in the preset).
- Use the
.graded.mp4version throughout the ENTIRE pipeline instead of the original (meta.json srcVideo; transcription can use either file since the audio is copied unchanged). - Record in the asset description (assets.json) which preset was used to grade it, so it does not get graded twice later.
Known issues
- Grading twice: the
.graded.mp4gets the preset applied again in a later session -> harsh color. ALWAYS check the filename and assets.json before grading. - Grading only the main video and forgetting b-roll/inserted images: inserted images usually do not need grading (they are graphics), but b-roll shot on the same camera needs the same preset - check the asset descriptions to know which files came from the camera.
- Missing
format=yuv420pat the end of the tonemap chain -> the output is 10-bit and HyperFrames/browsers may not play it.