From d372597bdbbb0618093d0b2cec72b2d1180f52ea Mon Sep 17 00:00:00 2001 From: Robert Resch Date: Mon, 11 Nov 2024 09:27:21 +0100 Subject: [PATCH 1/3] Lower codec not matched error for ffmpeg to debug --- internal/rtsp/rtsp.go | 9 +++++- internal/streams/add_consumer.go | 48 ++++++++++++++++++++------------ 2 files changed, 38 insertions(+), 19 deletions(-) diff --git a/internal/rtsp/rtsp.go b/internal/rtsp/rtsp.go index a4075f6c..cc6d5727 100644 --- a/internal/rtsp/rtsp.go +++ b/internal/rtsp/rtsp.go @@ -192,7 +192,14 @@ func tcpHandler(conn *rtsp.Conn) { conn.Connection.Source = query.Get("source") if err := stream.AddConsumer(conn); err != nil { - log.Warn().Err(err).Str("stream", name).Msg("[rtsp]") + logEvent := log.Warn() + + if _, ok := err.(*streams.CodecNotMatchedError); ok && strings.HasPrefix(query.Get("source"), "ffmpeg") { + // lower codec not matched error for ffmpeg to debug + logEvent = log.Debug() + } + + logEvent.Err(err).Str("stream", name).Msg("[rtsp]") return } diff --git a/internal/streams/add_consumer.go b/internal/streams/add_consumer.go index d72e17ee..0b8f6cf0 100644 --- a/internal/streams/add_consumer.go +++ b/internal/streams/add_consumer.go @@ -130,25 +130,10 @@ func formatError(consMedias, prodMedias []*core.Media, prodErrors []error) error // 2. Return "codecs not matched" if prodMedias != nil { - var prod, cons string - - for _, media := range prodMedias { - if media.Direction == core.DirectionRecvonly { - for _, codec := range media.Codecs { - prod = appendString(prod, codec.PrintName()) - } - } + return &CodecNotMatchedError{ + producerMedias: prodMedias, + consumerMedias: consMedias, } - - for _, media := range consMedias { - if media.Direction == core.DirectionSendonly { - for _, codec := range media.Codecs { - cons = appendString(cons, codec.PrintName()) - } - } - } - - return errors.New("streams: codecs not matched: " + prod + " => " + cons) } // 3. Return unknown error @@ -164,3 +149,30 @@ func appendString(s, elem string) string { } return s + ", " + elem } + +type CodecNotMatchedError struct { + producerMedias []*core.Media + consumerMedias []*core.Media +} + +func (e *CodecNotMatchedError) Error() string { + var prod, cons string + + for _, media := range e.producerMedias { + if media.Direction == core.DirectionRecvonly { + for _, codec := range media.Codecs { + prod = appendString(prod, codec.PrintName()) + } + } + } + + for _, media := range e.consumerMedias { + if media.Direction == core.DirectionSendonly { + for _, codec := range media.Codecs { + cons = appendString(cons, codec.PrintName()) + } + } + } + + return "streams: codecs not matched: " + prod + " => " + cons +} From 831aa03c9f184b0be20b624569bcd5dda8510e50 Mon Sep 17 00:00:00 2001 From: Robert Resch Date: Mon, 11 Nov 2024 11:16:12 +0100 Subject: [PATCH 2/3] Implement suggestion --- internal/ffmpeg/ffmpeg.go | 2 ++ internal/rtsp/rtsp.go | 8 +++-- internal/streams/add_consumer.go | 62 ++++++++++++++++++-------------- 3 files changed, 42 insertions(+), 30 deletions(-) diff --git a/internal/ffmpeg/ffmpeg.go b/internal/ffmpeg/ffmpeg.go index b934be53..b57dcc70 100644 --- a/internal/ffmpeg/ffmpeg.go +++ b/internal/ffmpeg/ffmpeg.go @@ -223,6 +223,8 @@ func parseArgs(s string) *ffmpeg.Args { s += "?video&audio" } s += "&source=ffmpeg:" + url.QueryEscape(source) + // change codec not matched error level to debug + s += "&" + string(streams.CodecNotMatchedErrorCode) + "=" + zerolog.DebugLevel.String() args.Input = inputTemplate("rtsp", s, query) } else if i = strings.Index(s, "?"); i > 0 { switch s[:i] { diff --git a/internal/rtsp/rtsp.go b/internal/rtsp/rtsp.go index cc6d5727..1bb41d83 100644 --- a/internal/rtsp/rtsp.go +++ b/internal/rtsp/rtsp.go @@ -194,9 +194,11 @@ func tcpHandler(conn *rtsp.Conn) { if err := stream.AddConsumer(conn); err != nil { logEvent := log.Warn() - if _, ok := err.(*streams.CodecNotMatchedError); ok && strings.HasPrefix(query.Get("source"), "ffmpeg") { - // lower codec not matched error for ffmpeg to debug - logEvent = log.Debug() + if err, ok := err.(*streams.ErrorWithErrorCode); ok { + level, parseErr := zerolog.ParseLevel(query.Get(err.Code())) + if parseErr == nil { + logEvent = log.WithLevel(level) + } } logEvent.Err(err).Str("stream", name).Msg("[rtsp]") diff --git a/internal/streams/add_consumer.go b/internal/streams/add_consumer.go index 0b8f6cf0..efe8542b 100644 --- a/internal/streams/add_consumer.go +++ b/internal/streams/add_consumer.go @@ -1,7 +1,6 @@ package streams import ( - "errors" "strings" "github.com/AlexxIT/go2rtc/pkg/core" @@ -125,19 +124,34 @@ func formatError(consMedias, prodMedias []*core.Media, prodErrors []error) error } if len(text) != 0 { - return errors.New("streams: " + text) + return &ErrorWithErrorCode{MultipleErrorCode, "streams: " + text} } // 2. Return "codecs not matched" if prodMedias != nil { - return &CodecNotMatchedError{ - producerMedias: prodMedias, - consumerMedias: consMedias, + var prod, cons string + + for _, media := range prodMedias { + if media.Direction == core.DirectionRecvonly { + for _, codec := range media.Codecs { + prod = appendString(prod, codec.PrintName()) + } + } } + + for _, media := range consMedias { + if media.Direction == core.DirectionSendonly { + for _, codec := range media.Codecs { + cons = appendString(cons, codec.PrintName()) + } + } + } + + return &ErrorWithErrorCode{CodecNotMatchedErrorCode, "streams: codecs not matched: " + prod + " => " + cons} } // 3. Return unknown error - return errors.New("streams: unknown error") + return &ErrorWithErrorCode{UnknownErrorCode, "streams: unknown error"} } func appendString(s, elem string) string { @@ -150,29 +164,23 @@ func appendString(s, elem string) string { return s + ", " + elem } -type CodecNotMatchedError struct { - producerMedias []*core.Media - consumerMedias []*core.Media -} +type ErrorCode string -func (e *CodecNotMatchedError) Error() string { - var prod, cons string +const ( + CodecNotMatchedErrorCode ErrorCode = "codecNotMatched" + MultipleErrorCode ErrorCode = "multiple" + UnknownErrorCode ErrorCode = "unknown" +) - for _, media := range e.producerMedias { - if media.Direction == core.DirectionRecvonly { - for _, codec := range media.Codecs { - prod = appendString(prod, codec.PrintName()) - } - } - } +type ErrorWithErrorCode struct { + code ErrorCode + message string +} - for _, media := range e.consumerMedias { - if media.Direction == core.DirectionSendonly { - for _, codec := range media.Codecs { - cons = appendString(cons, codec.PrintName()) - } - } - } +func (e *ErrorWithErrorCode) Error() string { + return e.message +} - return "streams: codecs not matched: " + prod + " => " + cons +func (e *ErrorWithErrorCode) Code() string { + return string(e.code) } From 570b7d0d97ea222b9db719802c4dce0eea0ef7b9 Mon Sep 17 00:00:00 2001 From: Alex X Date: Mon, 11 Nov 2024 17:45:55 +0300 Subject: [PATCH 3/3] Code refactoring for #1450 --- internal/ffmpeg/ffmpeg.go | 5 +++-- internal/rtsp/rtsp.go | 21 ++++++++++----------- internal/streams/add_consumer.go | 28 ++++------------------------ 3 files changed, 17 insertions(+), 37 deletions(-) diff --git a/internal/ffmpeg/ffmpeg.go b/internal/ffmpeg/ffmpeg.go index b57dcc70..25d61e4b 100644 --- a/internal/ffmpeg/ffmpeg.go +++ b/internal/ffmpeg/ffmpeg.go @@ -223,8 +223,9 @@ func parseArgs(s string) *ffmpeg.Args { s += "?video&audio" } s += "&source=ffmpeg:" + url.QueryEscape(source) - // change codec not matched error level to debug - s += "&" + string(streams.CodecNotMatchedErrorCode) + "=" + zerolog.DebugLevel.String() + for _, v := range query["query"] { + s += "&" + v + } args.Input = inputTemplate("rtsp", s, query) } else if i = strings.Index(s, "?"); i > 0 { switch s[:i] { diff --git a/internal/rtsp/rtsp.go b/internal/rtsp/rtsp.go index 1bb41d83..0fe135f8 100644 --- a/internal/rtsp/rtsp.go +++ b/internal/rtsp/rtsp.go @@ -147,6 +147,7 @@ func tcpHandler(conn *rtsp.Conn) { var closer func() trace := log.Trace().Enabled() + level := zerolog.WarnLevel conn.Listen(func(msg any) { if trace { @@ -188,20 +189,18 @@ func tcpHandler(conn *rtsp.Conn) { conn.PacketSize = uint16(core.Atoi(s)) } + // param name like ffmpeg style https://ffmpeg.org/ffmpeg-protocols.html + if s := query.Get("log_level"); s != "" { + if lvl, err := zerolog.ParseLevel(s); err == nil { + level = lvl + } + } + // will help to protect looping requests to same source conn.Connection.Source = query.Get("source") if err := stream.AddConsumer(conn); err != nil { - logEvent := log.Warn() - - if err, ok := err.(*streams.ErrorWithErrorCode); ok { - level, parseErr := zerolog.ParseLevel(query.Get(err.Code())) - if parseErr == nil { - logEvent = log.WithLevel(level) - } - } - - logEvent.Err(err).Str("stream", name).Msg("[rtsp]") + log.WithLevel(level).Err(err).Str("stream", name).Msg("[rtsp]") return } @@ -239,7 +238,7 @@ func tcpHandler(conn *rtsp.Conn) { if err := conn.Accept(); err != nil { if err != io.EOF { - log.Warn().Err(err).Caller().Send() + log.WithLevel(level).Err(err).Caller().Send() } if closer != nil { closer() diff --git a/internal/streams/add_consumer.go b/internal/streams/add_consumer.go index efe8542b..d72e17ee 100644 --- a/internal/streams/add_consumer.go +++ b/internal/streams/add_consumer.go @@ -1,6 +1,7 @@ package streams import ( + "errors" "strings" "github.com/AlexxIT/go2rtc/pkg/core" @@ -124,7 +125,7 @@ func formatError(consMedias, prodMedias []*core.Media, prodErrors []error) error } if len(text) != 0 { - return &ErrorWithErrorCode{MultipleErrorCode, "streams: " + text} + return errors.New("streams: " + text) } // 2. Return "codecs not matched" @@ -147,11 +148,11 @@ func formatError(consMedias, prodMedias []*core.Media, prodErrors []error) error } } - return &ErrorWithErrorCode{CodecNotMatchedErrorCode, "streams: codecs not matched: " + prod + " => " + cons} + return errors.New("streams: codecs not matched: " + prod + " => " + cons) } // 3. Return unknown error - return &ErrorWithErrorCode{UnknownErrorCode, "streams: unknown error"} + return errors.New("streams: unknown error") } func appendString(s, elem string) string { @@ -163,24 +164,3 @@ func appendString(s, elem string) string { } return s + ", " + elem } - -type ErrorCode string - -const ( - CodecNotMatchedErrorCode ErrorCode = "codecNotMatched" - MultipleErrorCode ErrorCode = "multiple" - UnknownErrorCode ErrorCode = "unknown" -) - -type ErrorWithErrorCode struct { - code ErrorCode - message string -} - -func (e *ErrorWithErrorCode) Error() string { - return e.message -} - -func (e *ErrorWithErrorCode) Code() string { - return string(e.code) -}