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 + +const ( + CodecNotMatchedErrorCode ErrorCode = "codecNotMatched" + MultipleErrorCode ErrorCode = "multiple" + UnknownErrorCode ErrorCode = "unknown" +) + +type ErrorWithErrorCode struct { + code ErrorCode + message string } -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 +func (e *ErrorWithErrorCode) Error() string { + return e.message +} + +func (e *ErrorWithErrorCode) Code() string { + return string(e.code) }