KamoCRM

Audio — a waveform thumbnail at upload, and peaks and transcripts on demand

FeatureConversionService
Shipped
September 23, 2026 at 8:21 AM UTC
Author
Kamo
Commit
d2e504a

An uploaded audio file fell through to the Docs PDF path, which cannot open one, so every audio upload ended "Conversion failed" with a blank library tile. Audio now takes its own branch, like video: streamed to scratch (never into heap), decoded ONCE into peaks, and its page-0 thumbnail drawn from those peaks in Java. Not ffmpeg's showwavespic, which holds every decoded frame until the end of the file: measured at 298 MB for a 30-minute MP3 and 546 MB for an hour, on an unbounded thread per upload in a pod sized for documents; the streamed decode peaks at 54 MB. FLAC, which the MIME table stores as a generic binary, is recognised by its extension. **************** - GET /peaks — the duration and a 1,600-bucket waveform (base64 of 0–255 peaks). ffmpeg's PCM is read as it streams and only one short per 50 ms window is kept, so an hour costs 72,000 shorts; the browser's decodeAudioData would hold over a gigabyte for the same hour. Stored beside the file as <datId>_peaks_v1.json, so it is computed once per content. - POST|GET /transcript — a timed WebVTT transcript from whisper-asr (vad_filter on), run as a job on a virtual thread with its state in <datId>_transcript_v1.json, which either replica can read (an in-memory job table would be invisible to the other pod). One job per pod at a time: whisper-asr is one CPU-bound replica shared with voicemail and meeting transcription. A running job rewrites its marker every minute from its own thread (joined before the result is written), so a job whose pod died reads as failed after three missed beats instead of locking the author out for a Whisper timeout; ?restart=true replaces a finished transcript. Measured against the live service: a 2 min 7 s recording took 25 s. Both require VIEW_DOCUMENTS and the imaging access level, and serve HR Resources only: voicemails, call recordings and chat voice notes each carry a per-record rule in DocsService that this service cannot see, so they stay a 404 until something that needs them brings that rule along. The build also picks up kamo-shared-library's audio MIME aliases: M4A, WAV, OGG and AAC uploads were being refused as a MIME mismatch.

All changes

Like what you see shipping?

All of it arrives in your workspace on its own. Start on the free plan and read this page again in a month.

Start Free ForeverView Pricing