Skip to content

Commit e2a59c0

Browse files
committed
fix: transcode IVR audio uploads to OGG/Opus 48kHz mono
Apply the same ffmpeg transcoding to UploadIVRAudio that was added to UploadOrgAudio, so IVR greeting audio files are also guaranteed to be compatible with the WebRTC AudioPlayer.
1 parent 4a4dbcd commit e2a59c0

File tree

1 file changed

+19
-13
lines changed

1 file changed

+19
-13
lines changed

internal/handlers/ivr_flows.go

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -336,30 +336,36 @@ func (a *App) UploadIVRAudio(r *fastglue.Request) error {
336336
return r.SendErrorEnvelope(fasthttp.StatusBadRequest, "Unsupported audio type: "+mimeType, nil, "")
337337
}
338338

339-
// Determine extension
340-
ext := getExtensionFromMimeType(mimeType)
341-
if ext == "" {
342-
ext = ".bin"
343-
}
344-
345339
// Ensure audio directory exists
346340
audioDir := a.getAudioDir()
347341
if err := os.MkdirAll(audioDir, 0755); err != nil {
348342
a.Log.Error("Failed to create audio directory", "error", err)
349343
return r.SendErrorEnvelope(fasthttp.StatusInternalServerError, "Failed to create audio directory", nil, "")
350344
}
351345

352-
// Generate filename: uuid + extension
353-
filename := uuid.New().String() + ext
346+
// Save uploaded file to a temp location for transcoding
347+
tmpInput, err := os.CreateTemp("", "ivr-audio-input-*")
348+
if err != nil {
349+
return r.SendErrorEnvelope(fasthttp.StatusInternalServerError, "Failed to create temp file", nil, "")
350+
}
351+
defer os.Remove(tmpInput.Name())
352+
353+
if _, err := tmpInput.Write(data); err != nil {
354+
tmpInput.Close()
355+
return r.SendErrorEnvelope(fasthttp.StatusInternalServerError, "Failed to write temp file", nil, "")
356+
}
357+
tmpInput.Close()
358+
359+
// Transcode to OGG/Opus 48kHz mono for WebRTC compatibility
360+
filename := uuid.New().String() + ".ogg"
354361
filePath := filepath.Join(audioDir, filename)
355362

356-
// Save file
357-
if err := os.WriteFile(filePath, data, 0644); err != nil {
358-
a.Log.Error("Failed to save audio file", "error", err)
359-
return r.SendErrorEnvelope(fasthttp.StatusInternalServerError, "Failed to save audio file", nil, "")
363+
if err := transcodeToOpus(tmpInput.Name(), filePath); err != nil {
364+
a.Log.Error("IVR audio transcoding failed", "error", err, "original_mime", mimeType)
365+
return r.SendErrorEnvelope(fasthttp.StatusInternalServerError, "Failed to transcode audio to Opus format", nil, "")
360366
}
361367

362-
a.Log.Info("IVR audio uploaded", "filename", filename, "mime_type", mimeType, "size", len(data))
368+
a.Log.Info("IVR audio uploaded", "filename", filename, "original_mime", mimeType, "size", len(data))
363369

364370
return r.SendEnvelope(map[string]any{
365371
"filename": filename,

0 commit comments

Comments
 (0)