AlexxIT/go2rtc · error
unsupported iso audio
Error message
unsupported iso audio: ${codec} What it means
WriteAudio in the ISO BMFF (MP4) muxer panics when given an audio codec with no implemented sample entry. Supported entries include Opus, PCMU (ulaw), PCMA (alaw) and others handled by the switch; any unlisted core.Codec reaches the default branch and panics.
Solutions
- Transcode the audio to a supported codec (e.g. Opus, PCMU/PCMA) before muxing.
- Guard the call: check the codec against the supported set and return an error instead of panicking.
- Extend the switch in pkg/iso/codecs.go WriteAudio with the needed sample entry atom if the codec must be supported.
- Wrap muxing with recover to translate the panic into an error for callers.
Example fix
// before
m.WriteAudio(trackID, core.CodecMP3, ...) // panics: unsupported iso audio: MP3
// after
switch codec {
case core.CodecOpus, core.CodecPCMU, core.CodecPCMA:
m.WriteAudio(trackID, codec, ...)
default:
return fmt.Errorf("mp4 muxer: unsupported audio codec %s", codec)
} Defensive patterns
Strategy: validation
Validate before calling
var supportedAudio = map[core.Codec]bool{core.CodecOpus: true, core.CodecPCMU: true, core.CodecPCMA: true}
if !supportedAudio[codec] {
return fmt.Errorf("unsupported iso audio codec: %s", codec)
}
m.WriteAudio(trackID, codec, w, timescale) Type guard
func isSupportedISOAudio(c core.Codec) bool {
switch c {
case core.CodecOpus, core.CodecPCMU, core.CodecPCMA:
return true
}
return false
} Try / catch
func safeWriteAudio(m *iso.Muxer, args...) (err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("iso muxer panic: %v", r)
}
}()
m.WriteAudio(args...)
return nil
} Prevention
- Whitelist supported audio codecs before calling WriteAudio.
- Transcode audio to Opus/PCMU/PCMA when the source uses another codec.
- Keep pkg/iso codec switches in sync with core.Codec additions.
- Recover panics at mux boundaries and surface them as errors.
When it happens
Trigger: Calling WriteAudio with a codec not covered by the switch (e.g. AAC variants not mapped, G.722, MP3) while muxing an audio track into MP4.
Common situations: Camera or SIP stream publishing an audio codec the muxer does not know; passing codec values straight through from an RTSP SDP without mapping; new codec added to core.Codec without updating pkg/iso.
Related errors
- unsupported iso video
- mp4: unsupported codec:
- not implemented
- pcm: unsupported audio format
- waw: unsupported codec
AI-assisted analysis of AlexxIT/go2rtc@c245815e75 (2026-09-07).
Data as JSON: /api/errors/52dcb2809b4204bd.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/iso/codecs.go:65
m.EndAtom()
m.EndAtom() // AVC1
}
func (m *Movie) WriteAudio(codec string, channels uint16, sampleRate uint32, conf []byte) {
switch codec {
case core.CodecAAC, core.CodecMP3:
m.StartAtom("mp4a") // supported in all players and browsers
case core.CodecFLAC:
m.StartAtom("fLaC") // supported in all players and browsers
case core.CodecOpus:
m.StartAtom("Opus") // supported in Chrome and Firefox
case core.CodecPCMU:
m.StartAtom("ulaw")
case core.CodecPCMA:
m.StartAtom("alaw")
default:
panic("unsupported iso audio: " + codec)
}
if channels == 0 {
channels = 1
}
m.Skip(6)
m.WriteUint16(1) // data_reference_index
m.Skip(2) // version
m.Skip(2) // revision
m.Skip(4) // vendor
m.WriteUint16(channels) // channel_count
m.WriteUint16(16) // sample_size
m.Skip(2) // compression id
m.Skip(2) // reserved
m.WriteFloat32(float64(sampleRate)) // sample_rate
switch codec {View on GitHub (pinned to c245815e75)