AlexxIT/go2rtc · error
mp4: unsupported codec:
Error message
mp4: unsupported codec:
What it means
When consuming an MP4 (muxing incoming tracks into the container), MP4Consumer.AddTrack looks up a registered handler for the track's codec (which supplies both the RTP depacketizer and the muxer sample entry). If track.Codec.Name has no matching handler, handler.Handler stays nil and the function returns this error naming the unsupported codec string.
Solutions
- Transcode to a supported codec before recording, e.g. `ffmpeg ... -c:v libx264 -c:a aac`, since H.264+AAC/PCMA/PCMU have well-supported MP4 handlers.
- Upgrade go2rtc to the latest release — MP4 codec support (H.265, Opus, etc.) grows over time.
- Check the exact codec name of the incoming track (log track.Codec.String()) and confirm it matches a supported handler; fix producers that set non-standard codec names.
- Use a different consumer/record format (e.g. MPEG-TS or MKV via ffmpeg) that supports the codec if MP4 muxing is not mandatory.
Example fix
// before: recording an unsupported codec name directly
cons := mp4.NewConsumer()
cons.AddTrack(track) // track.Codec = MJPEG -> error
// after: force a supported codec via stream transcoding
stream.PutQuery("video", "h264")
stream.PutQuery("audio", "aac")
cons.AddTrack(track) // track.Codec = h264 Defensive patterns
Strategy: try-catch
Validate before calling
var mp4SupportedCodecs = map[string]bool{"h264": true, "aac": true, "pcma": true, "pcmu": true, "h265": true, "opus": true}
func mp4TrackSupported(track core.Track) bool {
return mp4SupportedCodecs[strings.ToLower(track.Codec.Name)]
} Try / catch
cons := mp4.NewConsumer()
if err := cons.AddTrack(track); err != nil && strings.Contains(err.Error(), "mp4: unsupported codec") {
log.Warnf("%s; starting ffmpeg transcode to h264/aac for recording", err)
recorder = startFFmpegRecorder(source) // fallback path
} Prevention
- Log track.Codec.String() and compare against the consumer's supported handler list before adding
- Pin/upgrade go2rtc version so MP4 codec support matches your camera output
- Configure the source to deliver H.264 + AAC (or another well-supported pair) when recording to MP4
- Fall back to a container that supports the codec (MPEG-TS/MKV) when MP4 muxing fails
When it happens
Trigger: Calling mp4.NewConsumer and then AddTrack with a track whose codec is not in the supported set (e.g. H.265 with an exotic profile, AV1, VP9, Opus variants, or a codec string the muxer has no box writer for) — or a misnamed codec coming from a source producer.
Common situations: Recording streams from cameras emitting codecs like H.265+ or MJPEG into MP4; browser streams with codecs (AV1/VP9) not mapped in the muxer; older go2rtc version lacking support for a newly added codec; case/name mismatch between producer codec name and the consumer's handler registry.
Related errors
AI-assisted analysis of AlexxIT/go2rtc@c245815e75 (2026-09-07).
Data as JSON: /api/errors/35864e6b392f9ff7.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/mp4/consumer.go:156
case core.CodecOpus, core.CodecMP3: // no changes
case core.CodecPCMA, core.CodecPCMU, core.CodecPCM, core.CodecPCML:
codec.Name = core.CodecFLAC
if codec.Channels == 2 {
// hacky way for support two channels audio
codec.Channels = 1
codec.ClockRate *= 2
}
handler.Handler = pcm.FLACEncoder(track.Codec.Name, codec.ClockRate, handler.Handler)
default:
handler.Handler = nil
}
}
if handler.Handler == nil {
s := "mp4: unsupported codec: " + track.Codec.String()
println(s)
return errors.New(s)
}
c.muxer.AddTrack(codec)
handler.HandleRTP(track)
c.Senders = append(c.Senders, handler)
return nil
}
func (c *Consumer) WriteTo(wr io.Writer) (int64, error) {
if len(c.Senders) == 1 && c.Senders[0].Codec.IsAudio() {
c.start = true
}
init, err := c.muxer.GetInit()
if err != nil {
return 0, errView on GitHub (pinned to c245815e75)