diff --git a/pkg/rtsp/client_command_session.go b/pkg/rtsp/client_command_session.go index b2c432a..705493f 100644 --- a/pkg/rtsp/client_command_session.go +++ b/pkg/rtsp/client_command_session.go @@ -39,6 +39,10 @@ const ( CcstPushSession ) +var ( + ErrUnsupportedTransport = fmt.Errorf("Unsupported Transport") +) + type ClientCommandSessionOption struct { DoTimeoutMs int OverTcp bool @@ -389,29 +393,49 @@ func (session *ClientCommandSession) writeAnnounce() error { } func (session *ClientCommandSession) writeSetup() error { - if session.sdpCtx.HasVideoAControl() { - uri := session.sdpCtx.MakeVideoSetupUri(session.urlCtx.RawUrlWithoutUserInfo) + setup := func(setupUri string) error { if session.option.OverTcp { - if err := session.writeOneSetupTcp(uri); err != nil { - return err + if err := session.writeOneSetupTcp(setupUri); err != nil { + // 461情况下尝试切换UDP重试 + if err == ErrUnsupportedTransport { + if err := session.writeOneSetup(setupUri); err != nil { + return err + } + + session.option.OverTcp = false + } else { + return err + } } } else { - if err := session.writeOneSetup(uri); err != nil { - return err + if err := session.writeOneSetup(setupUri); err != nil { + // 461情况尝试切换TCP重试 + if err == ErrUnsupportedTransport { + if err = session.writeOneSetupTcp(setupUri); err != nil { + return err + } + + session.option.OverTcp = true + } else { + return err + } } } + + return nil + } + + if session.sdpCtx.HasVideoAControl() { + uri := session.sdpCtx.MakeVideoSetupUri(session.urlCtx.RawUrlWithoutUserInfo) + if err := setup(uri); err != nil { + return err + } } // can't else if if session.sdpCtx.HasAudioAControl() { uri := session.sdpCtx.MakeAudioSetupUri(session.urlCtx.RawUrlWithoutUserInfo) - if session.option.OverTcp { - if err := session.writeOneSetupTcp(uri); err != nil { - return err - } - } else { - if err := session.writeOneSetup(uri); err != nil { - return err - } + if err := setup(uri); err != nil { + return err } } return nil @@ -438,6 +462,12 @@ func (session *ClientCommandSession) writeOneSetup(setupUri string) error { return err } + if ctx.StatusCode == "461" { + // 切换transport尝试继续 + err = ErrUnsupportedTransport + return err + } + session.sessionId = strings.Split(ctx.Headers.Get(HeaderSession), ";")[0] rRtpPort, rRtcpPort, err := parseServerPort(ctx.Headers.Get(HeaderTransport)) @@ -508,6 +538,11 @@ func (session *ClientCommandSession) writeOneSetupTcp(setupUri string) error { return err } + if ctx.StatusCode == "461" { + err = ErrUnsupportedTransport + return err + } + session.sessionId = strings.Split(ctx.Headers.Get(HeaderSession), ";")[0] // TODO chef: 这里没有解析回传的channel id了,因为我假定了它和request中的是一致的