{"record":{"id":"35cf4a544060b3b4","repo":"AlexxIT/go2rtc","slug":"streams","errorCode":null,"errorMessage":"streams: ","messagePattern":"streams: ","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/streams/add_consumer.go","lineNumber":128,"sourceCode":"\tfor _, prod := range prodStarts {\n\t\tprod.start()\n\t}\n\n\treturn nil\n}\n\nfunc formatError(consMedias, prodMedias []*core.Media, prodErrors []error) error {\n\t// 1. Return errors if any not nil\n\tvar text string\n\n\tfor _, err := range prodErrors {\n\t\tif err != nil {\n\t\t\ttext = appendString(text, err.Error())\n\t\t}\n\t}\n\n\tif len(text) != 0 {\n\t\treturn errors.New(\"streams: \" + text)\n\t}\n\n\t// 2. Return \"codecs not matched\"\n\tif prodMedias != nil {\n\t\tvar prod, cons string\n\n\t\tfor _, media := range prodMedias {\n\t\t\tif media.Direction == core.DirectionRecvonly {\n\t\t\t\tfor _, codec := range media.Codecs {\n\t\t\t\t\tprod = appendString(prod, media.Kind+\":\"+codec.PrintName())\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor _, media := range consMedias {\n\t\t\tif media.Direction == core.DirectionSendonly {\n\t\t\t\tfor _, codec := range media.Codecs {\n\t\t\t\t\tcons = appendString(cons, media.Kind+\":\"+codec.PrintName())","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/AlexxIT/go2rtc/blob/c245815e75e2a5fd60b4290f12bfc04e55a984d3/internal/streams/add_consumer.go#L110-L146","documentation":"streams.AddConsumer collects all error messages gathered while trying to link a consumer to a producer's medias/codecs. If any errors were accumulated (text non-empty), it returns \"streams: <combined errors>\" via formatError. This typically wraps codec-negotiation or media-mismatch failures between the stream's producer and the requested consumer.","triggerScenarios":"Calling AddConsumer on a stream whose producer's medias don't match what the consumer can accept, or producer/consumer errors occurred during medias matching — e.g. camera publishes codecs the consumer can't handle (H.265 to an MJPEG consumer, missing audio to audio-only consumer, etc.).","commonSituations":"Playing a stream whose codecs are unsupported by the browser (H.265/HEVC in MSE), requesting a consumer type incompatible with the producer's media, or cameras with exotic codec combinations.","solutions":["Check the producer's codecs (via the streams info API) and use a consumer supporting them","Add transcoding (e.g. exec: ffmpeg with -c:v libx264) or a source that emits compatible codecs","Use a consumer type that matches the producer (e.g. HLS/WebRTC for H.265 instead of MSE)","Read the text after \"streams: \" — it contains the per-media underlying errors"],"exampleFix":"// before — H.265 source to MSE (unsupported)\nstreams: {cam: \"rtsp://cam/track1?h265\"}\n// after — transcode to H.264\nstreams:\n  cam:\n    - rtsp://cam/track1\n    - exec:ffmpeg#input=rtsp://cam/track1#output=rtp://127.0.0.1:10000#encoder=libx264","handlingStrategy":"try-catch","validationCode":"// Query producer codecs before AddConsumer\ncurl -f \"http://host:1984/api/streams?src=cam\"  # inspect medias/codecs","typeGuard":null,"tryCatchPattern":"// Go\nif err := stream.AddConsumer(cons); err != nil {\n    if strings.HasPrefix(err.Error(), \"streams: \") {\n        log.Warn().Msgf(\"codec/media mismatch: %v\", err) // details after prefix\n    }\n    return err\n}","preventionTips":["Match consumer type to producer codecs (H.265 => HLS/WebRTC, not MSE)","Use exec:ffmpeg transcoding for incompatible codecs","Read the concatenated detail after \"streams: \" to identify the failing media","Test camera codec output before wiring consumers"],"tags":["streams","codec-mismatch","consumer","addconsumer"],"backgroundTag":"codec-negotiation-failed","analyzedSha":"c245815e75e2a5fd60b4290f12bfc04e55a984d3","analyzedAt":"2026-09-07T11:47:02.965Z","contentChangedAt":"2026-09-07T11:47:02.965Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}