ConnClient: ignore interleaved frames sent before a response

This commit is contained in:
aler9
2020-10-03 13:42:31 +02:00
parent c65213f7b1
commit 8660eaf897

View File

@@ -240,7 +240,8 @@ func (c *ConnClient) WriteFrameUDP(track *Track, streamType StreamType, content
return c.udpRtcpListeners[track.Id].write(content) return c.udpRtcpListeners[track.Id].write(content)
} }
// Do writes a Request and reads a Response. // Do writes a Request and reads a Response. Interleaved frames sent before the
// response are ignored.
func (c *ConnClient) Do(req *Request) (*Response, error) { func (c *ConnClient) Do(req *Request) (*Response, error) {
if req.Header == nil { if req.Header == nil {
req.Header = make(Header) req.Header = make(Header)
@@ -277,8 +278,22 @@ func (c *ConnClient) Do(req *Request) (*Response, error) {
return nil, nil return nil, nil
} }
c.nconn.SetReadDeadline(time.Now().Add(c.conf.ReadTimeout)) // read the response and ignore interleaved frames in between;
res, err := ReadResponse(c.br) // interleaved frames are sent in two situations:
// * when the server is v4lrtspserver, before the PLAY response
// * when the stream is already playing
res, err := func() (*Response, error) {
for {
recv, err := c.readFrameTCPOrResponse()
if err != nil {
return nil, err
}
if res, ok := recv.(*Response); ok {
return res, nil
}
}
}()
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -650,44 +665,14 @@ func (c *ConnClient) Play(u *url.URL) (*Response, error) {
fmt.Errorf("must be called with the same url used for SetupUDP() or SetupTCP()") fmt.Errorf("must be called with the same url used for SetupUDP() or SetupTCP()")
} }
res, err := func() (*Response, error) { if *c.streamProtocol == StreamProtocolTCP {
if *c.streamProtocol == StreamProtocolUDP { c.tcpFrames = newMultiFrame(c.conf.ReadBufferCount, clientTCPFrameReadBufferSize)
res, err := c.Do(&Request{ }
Method: PLAY,
Url: u,
})
if err != nil {
return nil, err
}
return res, nil res, err := c.Do(&Request{
Method: PLAY,
} else { Url: u,
_, err := c.Do(&Request{ })
Method: PLAY,
Url: u,
SkipResponse: true,
})
if err != nil {
return nil, err
}
c.tcpFrames = newMultiFrame(c.conf.ReadBufferCount, clientTCPFrameReadBufferSize)
// v4lrtspserver sends frames before the response.
// ignore them and wait for the response.
for {
recv, err := c.readFrameTCPOrResponse()
if err != nil {
return nil, err
}
if res, ok := recv.(*Response); ok {
return res, nil
}
}
}
}()
if err != nil { if err != nil {
return nil, err return nil, err
} }