Transcode uploaded sound effects to Opus

FeatureConversionService
Shipped
August 15, 2026 at 12:34 AM UTC
Author
Kamo
Commit
ce48de0

Extends the ffmpeg wrapper the VoIP recording pipeline already had — this image installs ffmpeg with libopus for it, so putting a second ffmpeg in another image to avoid one hop would have been the wrong trade. The VoIP methods make a phone call small: mono, 32 kbit, `-application voip`, which is tuned for speech and audibly wrong for a chime. Sound effects get their own path: stereo preserved where it exists, 48 kHz (Opus's native rate, so no resampling), `-application audio`, and Ogg rather than WebM — `.opus` IS the Ogg-contained form, it is what every tool that says "Opus file" produces, and it is what the browser's decodeAudioData is handed. probeAudio answers two questions in one ffprobe: what codec arrived, and is there any audio at all. A renamed PDF reaches the endpoint, and "convert it anyway" spends twenty seconds of ffmpeg to produce an empty file. A file that is ALREADY Opus is stored byte-for-byte. Re-encoding Opus to Opus is generation loss for nothing — unless the uploader asked for loudness normalisation, which by definition requires a re-encode. That is off by default: it changes audio somebody chose, and doing that silently is not ours to decide. Over-long uploads are trimmed, not refused: twenty seconds is generous for a custom jingle, and the member gets the front of what they picked, which is the part they meant. Scan first, always. A decoder is exactly the kind of thing a malformed media file is written to attack, so UploadScanGuard runs ahead of ffmpeg, not after it. Note: ImageResizeServiceTest fails at HEAD (PNG expected, WebP produced) and is unrelated to this change — the Docker build runs -DskipTests, so it does not block the image.

All changes

Like what you see shipping?

Every one of these updates lands in your workspace automatically. Start free and watch it grow week after week.

Start Free ForeverView Pricing