# Media operations: agent guidance media-use resolves and remembers assets. For **operating** on them: cutting, reframing, stitching, transforming, it does not wrap every action as a bespoke command. Instead it points you at the right local tool (decision OP1). Run the tool, then register the output with `resolve --from --type ` so the result lands in the ledger and the global cache like any other asset. All tools below are local and free. ffmpeg is assumed present (it backs the engine already). ## Cut / trim: keep a slice ```bash ffmpeg -i in.mp4 -ss 00:00:12 -to 00:00:20 -c copy out.mp4 # 0:12–0:20, no re-encode ``` In-composition trimming usually needs **no new file**: a clip plays a sub-window via `data-media-start` + `data-duration` (see hyperframes-core). Only cut a physical file when exporting/assembling outside the composition. ## Reframe / crop: change aspect ratio ```bash # 16:9 -> 9:16, crop centered ffmpeg -i in.mp4 -vf "crop=ih*9/16:ih,scale=1080:1920" out.mp4 ``` For a non-destructive crop, set a `clip-path` on the element in the composition itself (render-time, source file untouched) instead of re-encoding with ffmpeg. ## Montage / stitch: join clips ```bash printf "file '%s'\n" a.mp4 b.mp4 c.mp4 > list.txt ffmpeg -f concat -safe 0 -i list.txt -c copy out.mp4 ``` ## Silence-cut / highlight: trim dead air, grab the best moment ```bash auto-editor in.mp4 --edit audio:threshold=4% -o tight.mp4 # pip install auto-editor scenedetect -i in.mp4 detect-adaptive list-scenes # pip install scenedetect ``` ## Transforms with a quality choice (process) These have a local option AND a higher-quality HeyGen-CLI option. Run the local one for free/offline; use the HeyGen CLI when quality matters. Showing the user a **side-by-side** (local vs HeyGen) is the honest way to let them choose. | Op | Local (free) | HeyGen CLI (quality) | | ------------------ | -------------------------------------------------- | --------------------------- | | Background removal | `hyperframes remove-background in.png` (u2net) | `heygen background-removal` | | Upscale | `realesrgan-ncnn-vulkan -i in.png -o out.png -s 4` | n/a | | Lipsync (dub) | n/a | `heygen lipsync` | | Translate | n/a | `heygen video-translate` | After any op: `resolve --from out.ext --type ` to register the derived asset (it records provenance and auto-promotes to the global cache). > ponytail: media-use doesn't re-wrap ffmpeg/heygen here, that's deliberate > (OP1). The value it adds is the ledger + global reuse on the _output_, via > `--from`. Add a thin `process` verb only if agents repeatedly fumble these > recipes. ## Exact error-diffusion dither Use the local processor when the requested look specifically calls for Floyd-Steinberg, Atkinson/Macintosh, Jarvis-Judice-Ninke, Stucki, Burkes, or a Sierra variant. These are sequential error-diffusion algorithms, not the realtime Bayer `effects.dither` shader. ```bash node /scripts/dither.mjs \ --input source.mp4 \ --out source.atkinson.mp4 \ --algorithm atkinson \ --palette '#0f380f,#306230,#8bac0f,#9bbc0f' \ --point-size 3 npx hyperframes media-use resolve \ --from source.atkinson.mp4 --type video --project . ``` Available algorithms: `floyd-steinberg`, `atkinson`, `jarvis-judice-ninke`, `stucki`, `burkes`, `sierra`, `sierra-lite`, and `two-row-sierra`. The default is balanced Floyd-Steinberg with a black/white palette. Palettes contain 2-6 `#rrggbb` colors in authored dark-to-light order; reversing the order intentionally inverts the mapping. `--point-size` controls 1-20px blocks; `--brightness` and `--contrast` accept 0.5-2; `--detail` accepts 0.1-1. The processor supports ordinary SDR images and MP4 video, preserves video audio, and emits BT.709 MP4. It rejects tagged PQ/HLG input rather than silently tone-mapping it. To animate the transformation, keep the original and processed files as two real media layers and use the seek-safe GSAP timeline to reveal or crossfade between them. Use the realtime Bayer shader instead when the dither amount itself must animate continuously. ## Transcription (default: Parakeet, better than whisper.cpp) `transcribe.mjs` is the default local transcription path. It runs **NVIDIA Parakeet-TDT via parakeet-mlx**, which beats whisper.cpp on the Open ASR Leaderboard (avg WER ~6.05% vs 7.44%; on NOISY audio 4.73% vs 5.96%, where whisper-large-v3 hallucinated to 308% WER on meetings) and is 5-10x faster. It emits `{ text, words:[{text,start,end}] }` with word timestamps (merged from Parakeet's sub-word tokens), feeding transcript-cut, captions, and the audio engine directly. ```bash # install once: uv venv ~/.venvs/parakeet && VIRTUAL_ENV=~/.venvs/parakeet uv pip install parakeet-mlx node /scripts/transcribe.mjs --input talk.mp4 --out talk.transcribe.json # equivalently, the hyperframes CLI has Parakeet built in (auto-detects it, whisper fallback): npx hyperframes transcribe talk.mp4 --engine parakeet # or --engine auto (default) ``` VERIFIED on 24GB: accurate, ~3s (cached) for 8s audio. Parakeet covers English + 25 European languages. For other languages, or when parakeet-mlx is not installed, transcribe.mjs auto-falls-back to whisper.cpp (99 languages) via `hyperframes transcribe`. `--engine parakeet|whisper` forces one. (Cohere Transcribe tops the leaderboard on paper but its mlx-audio quants produced garbage and ran 40-70x slower on a Mac in testing, so it is not wired in.) ## Text-based editing (transcript cut) `transcript-cut.mjs` is a compiler, not a wrapper: it turns word timestamps and agent cut decisions into exact kept segments. It is provided even though the rest of this file is guidance-only. ```bash node /scripts/transcript-cut.mjs \ --input talk.mp4 \ --transcript talk.transcribe.json \ --remove "12.41-15.02,88.3-91.7" \ --remove-fillers "um,uh,like" \ --cut-silence 0.8 \ --out talk.cut.mp4 resolve --from talk.cut.mp4 --type video ``` Use `--plan` first when you want to inspect the kept segment JSON before encoding. ## Ducking (declare in-composition / bake for export) B1, declare ducking in the composition. `audio-duck.mjs` emits a volume lane as a `data-automation` attribute. Add it to the background `