--- name: media-conversion title: Converting media description: Use when asked to convert, re-encode, remux or extract audio from a video or audio file, to make a web-friendly version of something, or to pull a still out of a video — "make this mp4", "get the audio off this", "these need to be smaller for the site". Carries the one endpoint, the copy-or-encode decision, and the rule that decides where the output goes. version: 1 --- You convert media through **av-club**, a plugin on this machine. One endpoint does the work and you already have the key. ```bash AV=(-H "Authorization: Bearer $OFFICER_AGENT_KEY" -H "Host: $OFFICER_API_HOST" -H 'content-type: application/json') curl -s "${AV[@]}" "$OFFICER_API_URL/api/av-club/health" ``` ## Never shell out to ffmpeg yourself Not because you cannot, but because everything that makes this safe lives on the other side of that endpoint: no shell, protocols disabled, filters allowlisted, work bounded, paths confined. A hand-built `ffmpeg` command has none of it, and the first one somebody writes with a filename from a web page is the incident. If av-club cannot express what is being asked, say so — that is a gap to report, not a reason to go around it. ## Files stay where they are ```bash curl -s "${AV[@]}" -X POST "$OFFICER_API_URL/api/av-club/v1/ffmpeg" \ -d '{"inputPath":"/home/you/Movies/film.mkv","outputPath":"/home/you/Movies/film.mp4", "format":"mp4","outputOptions":{"c:v":"copy","c:a":"copy","movflags":"+faststart"}}' # {"path":"/home/you/Movies/film.mp4","bytes":734003200} ``` Both paths must be **absolute** and inside the owner's home. A relative path, a `..`, a symlink pointing out, or a write outside the root are each a 400 — do not try to work around one, it is telling you the answer is no. There is also an asset mode (`{"input":"as_…"}`) for files that are not on disk. Prefer paths: a conversion of something already on the filesystem should not copy it twice. ## Look before you convert ```bash curl -s "${AV[@]}" "$OFFICER_API_URL/api/av-club/v1/probe?path=/home/you/Movies/film.mkv" ``` **This decides the most important thing you will decide.** If the codecs already fit the target container, ask for `"c:v":"copy","c:a":"copy"` — that is a *remux*: lossless, and about a hundred times faster. Re-encoding a two-hour film that only needed rewrapping costs an hour of CPU and quality, for nothing. - **mp4** carries h264, hevc, mpeg4 · aac, mp3 - **mov** carries h264, hevc, prores · aac, pcm - **mkv** carries almost anything, so converting *into* mkv is nearly always a remux - **webm** carries only vp8, vp9, av1 · opus, vorbis — so mp4 → webm is always a re-encode Guessing from the extension is how a "fast remux" silently re-encodes: plenty of `.avi` holds h264. ## Extracting audio `vn: true` drops the video. It is a boolean — `"1"` is refused. ```bash curl -s "${AV[@]}" -X POST "$OFFICER_API_URL/api/av-club/v1/ffmpeg" \ -d '{"inputPath":"/home/you/ep.mkv","outputPath":"/home/you/ep.mp3","format":"mp3", "outputOptions":{"vn":true,"c:a":"libmp3lame","b:a":"320k","map_metadata":"0"}}' ``` **A video with no audio track fails**, and that is not a broken video — screen recordings usually have none. Report it as "no audio track", not as an error. ## Quality settings worth reusing | Want | Say | | --- | --- | | mp3 | `c:a libmp3lame`, `b:a 320k`, `id3v2_version 3` | | m4a | `c:a aac`, `b:a 256k` | | opus | `c:a libopus`, `b:a 192k` | | ogg | `c:a libvorbis`, `q:a 6` | | flac / wav | `c:a flac` / `c:a pcm_s16le` | | h264 re-encode | `c:v libx264`, `crf 21`, `preset medium`, `pix_fmt yuv420p` | | for the web | add `movflags +faststart`, or playback waits for the whole file | **`map_metadata: "0"` or the tags are gone.** A converted album with no artist and no track numbers is the kind of loss nobody notices until the library has been rebuilt. CRF, not a bitrate: constant quality means a difficult scene gets the bits it needs and a static one does not waste them. ## Three tasks already exist — offer them first **Convert Audio**, **Extract Audio** and **Convert Video** are on the right-click menu of any media file or folder in the file browser. They do everything above, with the skip rules and a delete-source checkbox. If the owner is at a screen, pointing at the menu is better than running curl for them. Reach for the API when it is not a right-click: a folder being watched, a batch inside a larger job, or something the tasks do not offer. ## Rules that are not negotiable - **The input is never modified.** av-club writes to a temp file and moves it into place, so a job that dies leaves the original intact. Preserve that: never convert a file onto itself. - **Never overwrite an existing output** without saying so first. The file that is there may be one somebody made deliberately. - **Deleting a source is the owner's decision**, and only ever after the output exists and is non-empty. If you were not asked to delete, do not. - **Say what you did in their words** — "made film.mp4 beside the original, 700 MB, copied both streams so nothing was re-encoded" — not the JSON.