diff --git a/cmd/rtsp/rtsp.go b/cmd/rtsp/rtsp.go index f94b4ec7..5c51242b 100644 --- a/cmd/rtsp/rtsp.go +++ b/cmd/rtsp/rtsp.go @@ -65,8 +65,17 @@ func rtspHandler(url string) (streamer.Producer, error) { if err = conn.Dial(); err != nil { return nil, err } + + conn.Backchannel = true if err = conn.Describe(); err != nil { - return nil, err + // second try without backchannel, we need to reconnect + if err = conn.Dial(); err != nil { + return nil, err + } + conn.Backchannel = false + if err = conn.Describe(); err != nil { + return nil, err + } } return conn, nil diff --git a/pkg/rtsp/conn.go b/pkg/rtsp/conn.go index 572e050c..598f0fc8 100644 --- a/pkg/rtsp/conn.go +++ b/pkg/rtsp/conn.go @@ -50,6 +50,8 @@ type Conn struct { // public + Backchannel bool + Medias []*streamer.Media Session string UserAgent string @@ -106,6 +108,9 @@ func (c *Conn) Dial() (err error) { //if c.state != StateClientInit { // panic("wrong state") //} + if c.conn != nil && c.auth != nil { + c.auth.Reset() + } c.conn, err = net.DialTimeout( "tcp", c.URL.Host, 10*time.Second, @@ -258,21 +263,17 @@ func (c *Conn) Describe() error { Method: MethodDescribe, URL: c.URL, Header: map[string][]string{ - "Accept": {"application/sdp"}, - "Require": {"www.onvif.org/ver20/backchannel"}, + "Accept": {"application/sdp"}, }, } + if c.Backchannel { + req.Header.Set("Require", "www.onvif.org/ver20/backchannel") + } + res, err := c.Do(req) if err != nil { - if res != nil { - // if we have answer - give second chanse without onvif header - req.Header.Del("Require") - res, err = c.Do(req) - } - if err != nil { - return err - } + return err } if val := res.Header.Get("Content-Base"); val != "" { diff --git a/pkg/tcp/auth.go b/pkg/tcp/auth.go index 27cb2e94..7d35ee26 100644 --- a/pkg/tcp/auth.go +++ b/pkg/tcp/auth.go @@ -80,6 +80,12 @@ func (a *Auth) Write(req *Request) { } } +func (a *Auth) Reset() { + if a.Method == AuthDigest { + a.Method = AuthUnknown + } +} + func Between(s, sub1, sub2 string) string { i := strings.Index(s, sub1) if i < 0 {