chenhg5/cc-connect · error
ffmpeg AMR conversion failed
Error message
ffmpeg AMR conversion failed: %w (stderr: %s)
What it means
ConvertAudioToAMR shells out to ffmpeg; when cmd.Run() fails it wraps the error along with the captured stderr buffer. This signals that ffmpeg ran but the AMR conversion itself failed — the wrapper text differs per converter ("AMR conversion failed") so callers can tell which stage broke. The stderr content is ffmpeg's own error output and is the primary diagnostic.
Solutions
- Check the stderr in the wrapped error for ffmpeg's exact failure (invalid data, unknown encoder, etc.).
- Install an ffmpeg build with AMR support (`ffmpeg -encoders | grep amr_nb`).
- Correct the srcFormat on the caller side so it matches the real input codec.
- If the error stems from context cancellation, increase the timeout; reject empty payloads before calling.
Example fix
// before
if err == nil && len(data) == 0 { /* conversion attempted with empty data */ }
amr, err := core.ConvertAudioToAMR(ctx, data, format)
// after
if len(data) == 0 {
return fmt.Errorf("refusing to convert empty audio")
}
amr, err := core.ConvertAudioToAMR(ctx, data, format) Defensive patterns
Strategy: try-catch
Validate before calling
if len(audio) == 0 || !bytes.HasPrefix(audio, []byte("#!AMR")) && format == "amr" {
return fmt.Errorf("audio payload is not valid AMR")
}
Try / catch
amr, err := core.ConvertAudioToAMR(ctx, audio, srcFormat)
if err != nil {
var exitErr *exec.ExitError
if errors.As(err, &exitErr) {
log.Error("AMR conversion failed", "stderr", extractStderr(err))
}
return fmt.Errorf("convert to AMR: %w", err)
} Prevention
- Confirm the ffmpeg build supports amr_nb (`ffmpeg -encoders | grep amr_nb`).
- Check the format declaration against the file's magic bytes before conversion.
- Reject empty/truncated downloads at the fetch layer.
- Use a context timeout scaled to audio length so conversions are not killed early.
When it happens
Trigger: SendAudio (or a direct call) supplies bytes that cannot be decoded to AMR-NB: input already at a sample rate/codec ffmpeg refuses for amr_nb without resampling context, empty buffer, srcFormat mismatch (declared "silk" but actually mp3), missing amr_nb encoder in the ffmpeg build, or ctx cancellation terminating the process.
Common situations: Minimal ffmpeg builds without native AMR encoder; voice files from platforms that claim one codec but carry another; zero-byte uploads after a failed download; short conversion timeouts on slow hardware.
Related errors
- ffmpeg MP3 to AMR conversion failed
- ffmpeg conversion failed
- ffmpeg MP3 to OGG conversion failed
- ffmpeg opus conversion failed
- dingtalk: convert MP3 to AMR failed
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/d7903e5ce6aa0322.
Report an issue: GitHub.
Appendix: source
Thrown at core/speech.go:395
"-c:a", "amr_nb",
"-ar", "8000", // 8kHz sample rate (AMR-NB standard)
"-ac", "1", // mono
"-b:a", "12.2k", // 12.2 kbps bitrate (AMR-NB max)
"-f", "amr",
"-y",
"pipe:1",
}
if srcFormat == "amr" || srcFormat == "silk" {
args = append([]string{"-f", srcFormat}, args...)
}
cmd := exec.CommandContext(ctx, ffmpegPath, args...)
cmd.Stdin = bytes.NewReader(audio)
var stdout, stderr bytes.Buffer
cmd.Stdout = &stdout
cmd.Stderr = &stderr
if err := cmd.Run(); err != nil {
return nil, fmt.Errorf("ffmpeg AMR conversion failed: %w (stderr: %s)", err, stderr.String())
}
return stdout.Bytes(), nil
}
// ConvertMP3ToOGG converts MP3 audio to OGG format using ffmpeg with stdin/stdout pipes.
// Optimized for voice: Opus codec, 16kHz mono, 32kbps, voip application.
func ConvertMP3ToOGG(ctx context.Context, mp3Data []byte) ([]byte, error) {
ffmpegPath, err := exec.LookPath("ffmpeg")
if err != nil {
return nil, fmt.Errorf("ffmpeg not found in PATH: %w", err)
}
args := []string{
"-i", "pipe:0",
"-c:a", "libopus",
"-ar", "16000", // 16kHz sample rate for voice
"-ac", "1", // mono
"-b:a", "32k", // 32 kbps bitrate (voice quality)View on GitHub (pinned to 4000b2338a)