{"record":{"id":"0fe10d3398f17a4e","repo":"AlexxIT/go2rtc","slug":"no-video","errorCode":null,"errorMessage":"no video","messagePattern":"no video","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/xiaomi/miss/producer.go","lineNumber":66,"sourceCode":"\t\t\tMedias:     medias,\n\t\t\tTransport:  client,\n\t\t},\n\t\tclient: client,\n\t}, nil\n}\n\nfunc probe(client *Client, audio bool) ([]*core.Media, error) {\n\t_ = client.SetDeadline(time.Now().Add(15 * time.Second))\n\n\tvar vcodec, acodec *core.Codec\n\n\tfor {\n\t\tpkt, err := client.ReadPacket()\n\t\tif err != nil {\n\t\t\tif vcodec != nil {\n\t\t\t\terr = fmt.Errorf(\"no audio\")\n\t\t\t} else if acodec != nil {\n\t\t\t\terr = fmt.Errorf(\"no video\")\n\t\t\t}\n\t\t\treturn nil, fmt.Errorf(\"xiaomi: probe: %w\", err)\n\t\t}\n\n\t\tswitch pkt.CodecID {\n\t\tcase codecH264:\n\t\t\tif vcodec == nil {\n\t\t\t\tbuf := annexb.EncodeToAVCC(pkt.Payload)\n\t\t\t\tif h264.NALUType(buf) == h264.NALUTypeSPS {\n\t\t\t\t\tvcodec = h264.AVCCToCodec(buf)\n\t\t\t\t}\n\t\t\t}\n\t\tcase codecH265:\n\t\t\tif vcodec == nil {\n\t\t\t\tbuf := annexb.EncodeToAVCC(pkt.Payload)\n\t\t\t\tif h265.NALUType(buf) == h265.NALUTypeVPS {\n\t\t\t\t\tvcodec = h265.AVCCToCodec(buf)\n\t\t\t\t}","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/AlexxIT/go2rtc/blob/c245815e75e2a5fd60b4290f12bfc04e55a984d3/pkg/xiaomi/miss/producer.go#L48-L84","documentation":"During probing of a Xiaomi stream, the connection ended (ReadPacket returned an error) before any video codec was negotiated, while an audio codec was present. The library rewrites the read failure as \"no video\" and wraps it as \"xiaomi: probe: no video\". It indicates an audio-only stream, or a source that drops before the first H264/H265 packet.","triggerScenarios":"Calling Dial on a stream where audio packets arrive but ReadPacket errors out before any packet with CodecID codecH264/codecH265 is seen (acodec != nil, vcodec == nil).","commonSituations":"Camera configured as audio-only intercom/mic stream; broken camera firmware sending audio first then dying; firewall or NAT cutting the connection before keyframe delivery.","solutions":["Verify the camera outputs a video track (H264/H265) in its stream settings and re-enable video if disabled.","Probe the URL with ffprobe to confirm the container actually contains video.","Handle the error in the caller as an audio-only stream if that is acceptable.","Check network path stability; if video packets never arrive, the connection is dying early."],"exampleFix":"// before\nproducer, err := miss.Dial(ctx, url) // fails: xiaomi: probe: no video\n// after\nproducer, err := miss.Dial(ctx, url)\nif err != nil && strings.Contains(err.Error(), \"no video\") {\n    return nil, fmt.Errorf(\"stream %s is audio-only; enable video on camera: %w\", url, err)\n}","handlingStrategy":"try-catch","validationCode":"out, err := exec.Command(\"ffprobe\", \"-v\", \"error\", \"-select_streams\", \"v\", \"-show_entries\", \"stream=codec_name\", \"-of\", \"csv=p=0\", url).Output()\nif err != nil || len(strings.TrimSpace(string(out))) == 0 {\n    // stream has no video track; do not attempt Dial\n}","typeGuard":null,"tryCatchPattern":"producer, err := miss.Dial(ctx, url)\nif err != nil {\n    if strings.Contains(err.Error(), \"no video\") {\n        return fmt.Errorf(\"audio-only stream %s: enable camera video: %w\", url, err)\n    }\n    return err\n}","preventionTips":["Confirm the camera profile emits H264/H265 video.","Validate stream URLs with ffprobe before production use.","Avoid audio-only intercom profiles when video is required.","Check NAT/firewall timeouts that may kill the connection before keyframes."],"tags":["streaming","video","rtsp","camera","probe"],"backgroundTag":"missing-video-track","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"}