diff --git a/examples/server-tls.go b/examples/server-tls.go index 180e805a..1ddb0418 100644 --- a/examples/server-tls.go +++ b/examples/server-tls.go @@ -20,8 +20,8 @@ import ( var mutex sync.Mutex var publisher *gortsplib.ServerConn -var sdp []byte var readers = make(map[*gortsplib.ServerConn]struct{}) +var sdp []byte // this is called for each incoming connection func handleConn(conn *gortsplib.ServerConn) { @@ -117,7 +117,7 @@ func handleConn(conn *gortsplib.ServerConn) { }, nil } - // called after receiving a Frame. + // called after receiving a frame. onFrame := func(trackID int, typ gortsplib.StreamType, buf []byte) { mutex.Lock() defer mutex.Unlock() diff --git a/examples/server-udp.go b/examples/server-udp.go index efee9fda..4dd2440b 100644 --- a/examples/server-udp.go +++ b/examples/server-udp.go @@ -19,8 +19,8 @@ import ( var mutex sync.Mutex var publisher *gortsplib.ServerConn -var sdp []byte var readers = make(map[*gortsplib.ServerConn]struct{}) +var sdp []byte // this is called for each incoming connection func handleConn(conn *gortsplib.ServerConn) { @@ -116,7 +116,7 @@ func handleConn(conn *gortsplib.ServerConn) { }, nil } - // called after receiving a Frame. + // called after receiving a frame. onFrame := func(trackID int, typ gortsplib.StreamType, buf []byte) { mutex.Lock() defer mutex.Unlock() diff --git a/examples/server.go b/examples/server.go index 990a4b92..82c99a6f 100644 --- a/examples/server.go +++ b/examples/server.go @@ -19,8 +19,8 @@ import ( var mutex sync.Mutex var publisher *gortsplib.ServerConn -var sdp []byte var readers = make(map[*gortsplib.ServerConn]struct{}) +var sdp []byte // this is called for each incoming connection func handleConn(conn *gortsplib.ServerConn) { @@ -116,7 +116,7 @@ func handleConn(conn *gortsplib.ServerConn) { }, nil } - // called after receiving a Frame. + // called after receiving a frame. onFrame := func(trackID int, typ gortsplib.StreamType, buf []byte) { mutex.Lock() defer mutex.Unlock() diff --git a/serverconf_test.go b/serverconf_test.go index cd26600f..e8e638f3 100644 --- a/serverconf_test.go +++ b/serverconf_test.go @@ -413,6 +413,75 @@ func TestServerTeardownResponse(t *testing.T) { require.Equal(t, io.EOF, err) } +func TestServerSetupWithoutTrackID(t *testing.T) { + ts, err := newTestServ(nil) + require.NoError(t, err) + defer ts.close() + + cnt1, err := newContainer("ffmpeg", "publish", []string{ + "-re", + "-stream_loop", "-1", + "-i", "emptyvideo.ts", + "-c", "copy", + "-f", "rtsp", + "-rtsp_transport", "tcp", + "rtsp://localhost:8554/teststream", + }) + require.NoError(t, err) + defer cnt1.close() + + time.Sleep(1 * time.Second) + + conn, err := net.Dial("tcp", "localhost:8554") + require.NoError(t, err) + defer conn.Close() + bconn := bufio.NewReadWriter(bufio.NewReader(conn), bufio.NewWriter(conn)) + + err = base.Request{ + Method: base.Setup, + URL: base.MustParseURL("rtsp://localhost:8554/teststream"), + Header: base.Header{ + "CSeq": base.HeaderValue{"1"}, + "Transport": headers.Transport{ + Protocol: StreamProtocolTCP, + Delivery: func() *base.StreamDelivery { + v := base.StreamDeliveryUnicast + return &v + }(), + Mode: func() *headers.TransportMode { + v := headers.TransportModePlay + return &v + }(), + InterleavedIds: &[2]int{0, 1}, + }.Write(), + }, + }.Write(bconn.Writer) + require.NoError(t, err) + + var res base.Response + err = res.Read(bconn.Reader) + require.NoError(t, err) + require.Equal(t, base.StatusOK, res.StatusCode) + + err = base.Request{ + Method: base.Play, + URL: base.MustParseURL("rtsp://localhost:8554/teststream"), + Header: base.Header{ + "CSeq": base.HeaderValue{"2"}, + }, + }.Write(bconn.Writer) + require.NoError(t, err) + + err = res.Read(bconn.Reader) + require.NoError(t, err) + require.Equal(t, base.StatusOK, res.StatusCode) + + var fr base.InterleavedFrame + fr.Payload = make([]byte, 2048) + err = fr.Read(bconn.Reader) + require.NoError(t, err) +} + func TestServerResponseBeforeFrames(t *testing.T) { ts, err := newTestServ(nil) require.NoError(t, err) diff --git a/serverconn.go b/serverconn.go index 3b386547..bdbfc892 100644 --- a/serverconn.go +++ b/serverconn.go @@ -70,8 +70,10 @@ type ServerConnTrack struct { func extractTrackID(pathAndQuery string, mode *headers.TransportMode, trackLen int) (int, error) { if mode == nil || *mode == headers.TransportModePlay { i := strings.Index(pathAndQuery, "/trackID=") + + // URL doesn't contain trackID - we assume it's track 0 if i < 0 { - return 0, fmt.Errorf("unable to find control attribute (%s)", pathAndQuery) + return 0, nil } tmp, err := strconv.ParseInt(pathAndQuery[i+len("/trackID="):], 10, 64) @@ -128,7 +130,7 @@ type ServerConnReadHandlers struct { // if nil, it is generated automatically. OnTeardown func(req *base.Request) (*base.Response, error) - // called after receiving a Frame. + // called after receiving a frame. OnFrame func(trackID int, streamType StreamType, payload []byte) }