diff --git a/README.md b/README.md index 9299317d..edb8988b 100644 --- a/README.md +++ b/README.md @@ -120,7 +120,7 @@ https://pkg.go.dev/github.com/bluenviron/gortsplib/v3#pkg-index Related projects -* rtsp-simple-server https://github.com/aler9/rtsp-simple-server +* MediaMTX https://github.com/aler9/mediamtx * pion/sdp (SDP library used internally) https://github.com/pion/sdp * pion/rtp (RTP library used internally) https://github.com/pion/rtp * pion/rtcp (RTCP library used internally) https://github.com/pion/rtcp diff --git a/client.go b/client.go index 2a1489e6..91bab5f7 100644 --- a/client.go +++ b/client.go @@ -1494,7 +1494,7 @@ func (c *Client) doPlay(ra *headers.Range, isSwitchingProtocol bool) (*base.Resp return nil, err } - // open the firewall by sending test packets to the counterpart. + // open the firewall by sending empty packets to the counterpart. // do this before sending the request. // don't do this with multicast, otherwise the RTP packet is going to be broadcasted // to all listeners, including us, messing up the stream. diff --git a/server_play_test.go b/server_play_test.go index 9692d087..be82ffa6 100644 --- a/server_play_test.go +++ b/server_play_test.go @@ -79,14 +79,22 @@ func doDescribe(t *testing.T, conn *conn.Conn) *sdp.SessionDescription { return &desc } -func doSetup(t *testing.T, conn *conn.Conn, u string, inTH *headers.Transport) (*base.Response, *headers.Transport) { +func doSetup(t *testing.T, conn *conn.Conn, u string, + inTH *headers.Transport, session string, +) (*base.Response, *headers.Transport) { + h := base.Header{ + "CSeq": base.HeaderValue{"1"}, + "Transport": inTH.Marshal(), + } + + if session != "" { + h["Session"] = base.HeaderValue{session} + } + res, err := writeReqReadRes(conn, base.Request{ Method: base.Setup, URL: mustParseURL(u), - Header: base.Header{ - "CSeq": base.HeaderValue{"1"}, - "Transport": inTH.Marshal(), - }, + Header: h, }) require.NoError(t, err) require.Equal(t, base.StatusOK, res.StatusCode) @@ -124,6 +132,19 @@ func doPause(t *testing.T, conn *conn.Conn, u string, session string) { require.Equal(t, base.StatusOK, res.StatusCode) } +func doTeardown(t *testing.T, conn *conn.Conn, u string, session string) { + res, err := writeReqReadRes(conn, base.Request{ + Method: base.Teardown, + URL: mustParseURL(u), + Header: base.Header{ + "CSeq": base.HeaderValue{"1"}, + "Session": base.HeaderValue{session}, + }, + }) + require.NoError(t, err) + require.Equal(t, base.StatusOK, res.StatusCode) +} + func readSession(t *testing.T, res *base.Response) string { var sx headers.Session err := sx.Unmarshal(res.Header["Session"]) @@ -249,7 +270,7 @@ func TestServerPlayPath(t *testing.T) { res, _ := doSetup(t, conn, strings.ReplaceAll(ca.setupURL, "[control]", "/"+ relativeControlAttribute(desc.MediaDescriptions[1])), - th) + th, "") session := readSession(t, res) @@ -614,7 +635,7 @@ func TestServerPlay(t *testing.T) { inTH.InterleavedIDs = &[2]int{4, 5} } - res, th := doSetup(t, conn, absoluteControlAttribute(desc.MediaDescriptions[0]), inTH) + res, th := doSetup(t, conn, absoluteControlAttribute(desc.MediaDescriptions[0]), inTH, "") var l1 net.PacketConn var l2 net.PacketConn @@ -779,16 +800,7 @@ func TestServerPlay(t *testing.T) { require.Equal(t, base.StatusOK, res.StatusCode) } - res, err = writeReqReadRes(conn, base.Request{ - Method: base.Teardown, - URL: mustParseURL("rtsp://" + listenIP + ":8554/teststream"), - Header: base.Header{ - "CSeq": base.HeaderValue{"6"}, - "Session": base.HeaderValue{session}, - }, - }) - require.NoError(t, err) - require.Equal(t, base.StatusOK, res.StatusCode) + doTeardown(t, conn, "rtsp://"+listenIP+":8554/teststream", session) <-sessionClosed @@ -883,7 +895,7 @@ func TestServerPlayDecodeErrors(t *testing.T) { inTH.InterleavedIDs = &[2]int{0, 1} } - res, resTH := doSetup(t, conn, absoluteControlAttribute(desc.MediaDescriptions[0]), inTH) + res, resTH := doSetup(t, conn, absoluteControlAttribute(desc.MediaDescriptions[0]), inTH, "") var l1 net.PacketConn var l2 net.PacketConn @@ -995,7 +1007,7 @@ func TestServerPlayRTCPReport(t *testing.T) { inTH.InterleavedIDs = &[2]int{0, 1} } - res, _ := doSetup(t, conn, absoluteControlAttribute(desc.MediaDescriptions[0]), inTH) + res, _ := doSetup(t, conn, absoluteControlAttribute(desc.MediaDescriptions[0]), inTH, "") var l1 net.PacketConn var l2 net.PacketConn @@ -1054,16 +1066,7 @@ func TestServerPlayRTCPReport(t *testing.T) { OctetCount: 2, }, packets[0]) - res, err = writeReqReadRes(conn, base.Request{ - Method: base.Teardown, - URL: mustParseURL("rtsp://localhost:8554/teststream"), - Header: base.Header{ - "CSeq": base.HeaderValue{"4"}, - "Session": base.HeaderValue{session}, - }, - }) - require.NoError(t, err) - require.Equal(t, base.StatusOK, res.StatusCode) + doTeardown(t, conn, "rtsp://localhost:8554/teststream", session) }) } } @@ -1190,7 +1193,7 @@ func TestServerPlayTCPResponseBeforeFrames(t *testing.T) { InterleavedIDs: &[2]int{0, 1}, } - res, _ := doSetup(t, conn, absoluteControlAttribute(desc.MediaDescriptions[0]), inTH) + res, _ := doSetup(t, conn, absoluteControlAttribute(desc.MediaDescriptions[0]), inTH, "") session := readSession(t, res) @@ -1251,7 +1254,7 @@ func TestServerPlayPlayPlay(t *testing.T) { ClientPorts: &[2]int{30450, 30451}, } - res, _ := doSetup(t, conn, absoluteControlAttribute(desc.MediaDescriptions[0]), inTH) + res, _ := doSetup(t, conn, absoluteControlAttribute(desc.MediaDescriptions[0]), inTH, "") session := readSession(t, res) @@ -1340,7 +1343,7 @@ func TestServerPlayPlayPausePlay(t *testing.T) { InterleavedIDs: &[2]int{0, 1}, } - res, _ := doSetup(t, conn, absoluteControlAttribute(desc.MediaDescriptions[0]), inTH) + res, _ := doSetup(t, conn, absoluteControlAttribute(desc.MediaDescriptions[0]), inTH, "") session := readSession(t, res) @@ -1426,7 +1429,7 @@ func TestServerPlayPlayPausePause(t *testing.T) { InterleavedIDs: &[2]int{0, 1}, } - res, _ := doSetup(t, conn, absoluteControlAttribute(desc.MediaDescriptions[0]), inTH) + res, _ := doSetup(t, conn, absoluteControlAttribute(desc.MediaDescriptions[0]), inTH, "") session := readSession(t, res) @@ -1518,7 +1521,7 @@ func TestServerPlayTimeout(t *testing.T) { inTH.Protocol = headers.TransportProtocolUDP } - res, _ := doSetup(t, conn, absoluteControlAttribute(desc.MediaDescriptions[0]), inTH) + res, _ := doSetup(t, conn, absoluteControlAttribute(desc.MediaDescriptions[0]), inTH, "") session := readSession(t, res) @@ -1605,7 +1608,7 @@ func TestServerPlayWithoutTeardown(t *testing.T) { inTH.InterleavedIDs = &[2]int{0, 1} } - res, _ := doSetup(t, conn, absoluteControlAttribute(desc.MediaDescriptions[0]), inTH) + res, _ := doSetup(t, conn, absoluteControlAttribute(desc.MediaDescriptions[0]), inTH, "") session := readSession(t, res) @@ -1678,7 +1681,7 @@ func TestServerPlayUDPChangeConn(t *testing.T) { ClientPorts: &[2]int{35466, 35467}, } - res, _ := doSetup(t, conn, absoluteControlAttribute(desc.MediaDescriptions[0]), inTH) + res, _ := doSetup(t, conn, absoluteControlAttribute(desc.MediaDescriptions[0]), inTH, "") session := readSession(t, res) @@ -1761,7 +1764,7 @@ func TestServerPlayPartialMedias(t *testing.T) { InterleavedIDs: &[2]int{4, 5}, } - res, _ := doSetup(t, conn, absoluteControlAttribute(desc.MediaDescriptions[0]), inTH) + res, _ := doSetup(t, conn, absoluteControlAttribute(desc.MediaDescriptions[0]), inTH, "") session := readSession(t, res) @@ -1795,7 +1798,7 @@ func TestServerPlayAdditionalInfos(t *testing.T) { InterleavedIDs: &[2]int{0, 1}, } - res, th := doSetup(t, conn, absoluteControlAttribute(desc.MediaDescriptions[0]), inTH) + res, th := doSetup(t, conn, absoluteControlAttribute(desc.MediaDescriptions[0]), inTH, "") ssrcs := make([]*uint32, 2) ssrcs[0] = th.SSRC @@ -1815,21 +1818,8 @@ func TestServerPlayAdditionalInfos(t *testing.T) { session := readSession(t, res) - res, err = writeReqReadRes(conn, base.Request{ - Method: base.Setup, - URL: mustParseURL(absoluteControlAttribute(desc.MediaDescriptions[1])), - Header: base.Header{ - "CSeq": base.HeaderValue{"3"}, - "Transport": inTH.Marshal(), - "Session": base.HeaderValue{session}, - }, - }) - require.NoError(t, err) - require.Equal(t, base.StatusOK, res.StatusCode) + _, th = doSetup(t, conn, absoluteControlAttribute(desc.MediaDescriptions[1]), inTH, session) - th = &headers.Transport{} - err = th.Unmarshal(res.Header["Transport"]) - require.NoError(t, err) ssrcs[1] = th.SSRC doPlay(t, conn, "rtsp://localhost:8554/teststream", session) @@ -2035,26 +2025,13 @@ func TestServerPlayNoInterleavedIDs(t *testing.T) { Protocol: headers.TransportProtocolTCP, } - res, th := doSetup(t, conn, absoluteControlAttribute(desc.MediaDescriptions[0]), inTH) + res, th := doSetup(t, conn, absoluteControlAttribute(desc.MediaDescriptions[0]), inTH, "") require.Equal(t, &[2]int{0, 1}, th.InterleavedIDs) session := readSession(t, res) - res, err = writeReqReadRes(conn, base.Request{ - Method: base.Setup, - URL: mustParseURL(absoluteControlAttribute(desc.MediaDescriptions[1])), - Header: base.Header{ - "CSeq": base.HeaderValue{"3"}, - "Transport": inTH.Marshal(), - "Session": base.HeaderValue{session}, - }, - }) - require.NoError(t, err) - require.Equal(t, base.StatusOK, res.StatusCode) - - err = th.Unmarshal(res.Header["Transport"]) - require.NoError(t, err) + _, th = doSetup(t, conn, absoluteControlAttribute(desc.MediaDescriptions[1]), inTH, session) require.Equal(t, &[2]int{2, 3}, th.InterleavedIDs) diff --git a/server_record_test.go b/server_record_test.go index dbc78283..631903ae 100644 --- a/server_record_test.go +++ b/server_record_test.go @@ -21,7 +21,53 @@ import ( "github.com/bluenviron/gortsplib/v3/pkg/sdp" ) +func doAnnounce(t *testing.T, conn *conn.Conn, u string, medias media.Medias) { + res, err := writeReqReadRes(conn, base.Request{ + Method: base.Announce, + URL: mustParseURL(u), + Header: base.Header{ + "CSeq": base.HeaderValue{"1"}, + "Content-Type": base.HeaderValue{"application/sdp"}, + }, + Body: mustMarshalMedias(medias), + }) + require.NoError(t, err) + require.Equal(t, base.StatusOK, res.StatusCode) +} + +func doRecord(t *testing.T, conn *conn.Conn, u string, session string) { + res, err := writeReqReadRes(conn, base.Request{ + Method: base.Record, + URL: mustParseURL(u), + Header: base.Header{ + "CSeq": base.HeaderValue{"1"}, + "Session": base.HeaderValue{session}, + }, + }) + require.NoError(t, err) + require.Equal(t, base.StatusOK, res.StatusCode) +} + func invalidURLAnnounceReq(t *testing.T, control string) base.Request { + medi := testH264Media + medi.Control = control + + sout := &sdp.SessionDescription{ + SessionName: psdp.SessionName("Stream"), + Origin: psdp.Origin{ + Username: "-", + NetworkType: "IN", + AddressType: "IP4", + UnicastAddress: "127.0.0.1", + }, + TimeDescriptions: []psdp.TimeDescription{ + {Timing: psdp.Timing{0, 0}}, //nolint:govet + }, + MediaDescriptions: []*psdp.MediaDescription{medi.Marshal()}, + } + + byts, _ := sout.Marshal() + return base.Request{ Method: base.Announce, URL: mustParseURL("rtsp://localhost:8554/teststream"), @@ -29,27 +75,7 @@ func invalidURLAnnounceReq(t *testing.T, control string) base.Request { "CSeq": base.HeaderValue{"1"}, "Content-Type": base.HeaderValue{"application/sdp"}, }, - Body: func() []byte { - medi := testH264Media - medi.Control = control - - sout := &sdp.SessionDescription{ - SessionName: psdp.SessionName("Stream"), - Origin: psdp.Origin{ - Username: "-", - NetworkType: "IN", - AddressType: "IP4", - UnicastAddress: "127.0.0.1", - }, - TimeDescriptions: []psdp.TimeDescription{ - {Timing: psdp.Timing{0, 0}}, //nolint:govet - }, - MediaDescriptions: []*psdp.MediaDescription{medi.Marshal()}, - } - - byts, _ := sout.Marshal() - return byts - }(), + Body: byts, } } @@ -276,20 +302,11 @@ func TestServerRecordPath(t *testing.T) { InterleavedIDs: &[2]int{0, 1}, } - res, _ = doSetup(t, conn, ca.setupURL, th) + res, _ = doSetup(t, conn, ca.setupURL, th, "") session := readSession(t, res) - res, err = writeReqReadRes(conn, base.Request{ - Method: base.Record, - URL: mustParseURL(ca.announceURL), - Header: base.Header{ - "CSeq": base.HeaderValue{"3"}, - "Session": base.HeaderValue{session}, - }, - }) - require.NoError(t, err) - require.Equal(t, base.StatusOK, res.StatusCode) + doRecord(t, conn, ca.announceURL, session) }) } } @@ -328,17 +345,7 @@ func TestServerRecordErrorSetupMediaTwice(t *testing.T) { medias := media.Medias{testH264Media} resetMediaControls(medias) - res, err := writeReqReadRes(conn, base.Request{ - Method: base.Announce, - URL: mustParseURL("rtsp://localhost:8554/teststream"), - Header: base.Header{ - "CSeq": base.HeaderValue{"1"}, - "Content-Type": base.HeaderValue{"application/sdp"}, - }, - Body: mustMarshalMedias(medias), - }) - require.NoError(t, err) - require.Equal(t, base.StatusOK, res.StatusCode) + doAnnounce(t, conn, "rtsp://localhost:8554/teststream", medias) inTH := &headers.Transport{ Protocol: headers.TransportProtocolTCP, @@ -353,28 +360,30 @@ func TestServerRecordErrorSetupMediaTwice(t *testing.T) { InterleavedIDs: &[2]int{0, 1}, } - res, _ = doSetup(t, conn, "rtsp://localhost:8554/teststream/"+medias[0].Control, inTH) + res, _ := doSetup(t, conn, "rtsp://localhost:8554/teststream/"+medias[0].Control, inTH, "") session := readSession(t, res) + inTH = &headers.Transport{ + Protocol: headers.TransportProtocolTCP, + Delivery: func() *headers.TransportDelivery { + v := headers.TransportDeliveryUnicast + return &v + }(), + Mode: func() *headers.TransportMode { + v := headers.TransportModeRecord + return &v + }(), + InterleavedIDs: &[2]int{2, 3}, + } + res, err = writeReqReadRes(conn, base.Request{ Method: base.Setup, URL: mustParseURL("rtsp://localhost:8554/teststream/" + medias[0].Control), Header: base.Header{ - "CSeq": base.HeaderValue{"3"}, - "Transport": headers.Transport{ - Protocol: headers.TransportProtocolTCP, - Delivery: func() *headers.TransportDelivery { - v := headers.TransportDeliveryUnicast - return &v - }(), - Mode: func() *headers.TransportMode { - v := headers.TransportModeRecord - return &v - }(), - InterleavedIDs: &[2]int{2, 3}, - }.Marshal(), - "Session": base.HeaderValue{session}, + "CSeq": base.HeaderValue{"3"}, + "Transport": inTH.Marshal(), + "Session": base.HeaderValue{session}, }, }) require.NoError(t, err) @@ -439,17 +448,7 @@ func TestServerRecordErrorRecordPartialMedias(t *testing.T) { } resetMediaControls(medias) - res, err := writeReqReadRes(conn, base.Request{ - Method: base.Announce, - URL: mustParseURL("rtsp://localhost:8554/teststream"), - Header: base.Header{ - "CSeq": base.HeaderValue{"1"}, - "Content-Type": base.HeaderValue{"application/sdp"}, - }, - Body: mustMarshalMedias(medias), - }) - require.NoError(t, err) - require.Equal(t, base.StatusOK, res.StatusCode) + doAnnounce(t, conn, "rtsp://localhost:8554/teststream", medias) inTH := &headers.Transport{ Protocol: headers.TransportProtocolTCP, @@ -464,7 +463,7 @@ func TestServerRecordErrorRecordPartialMedias(t *testing.T) { InterleavedIDs: &[2]int{0, 1}, } - res, _ = doSetup(t, conn, "rtsp://localhost:8554/teststream/"+medias[0].Control, inTH) + res, _ := doSetup(t, conn, "rtsp://localhost:8554/teststream/"+medias[0].Control, inTH, "") session := readSession(t, res) @@ -601,17 +600,7 @@ func TestServerRecord(t *testing.T) { } resetMediaControls(medias) - res, err := writeReqReadRes(conn, base.Request{ - Method: base.Announce, - URL: mustParseURL("rtsp://localhost:8554/teststream"), - Header: base.Header{ - "CSeq": base.HeaderValue{"1"}, - "Content-Type": base.HeaderValue{"application/sdp"}, - }, - Body: mustMarshalMedias(medias), - }) - require.NoError(t, err) - require.Equal(t, base.StatusOK, res.StatusCode) + doAnnounce(t, conn, "rtsp://localhost:8554/teststream", medias) <-sessionOpened @@ -648,29 +637,16 @@ func TestServerRecord(t *testing.T) { inTH.InterleavedIDs = &[2]int{2 + i*2, 3 + i*2} } - res, _ := doSetup(t, conn, "rtsp://localhost:8554/teststream/"+medias[i].Control, inTH) + res, th := doSetup(t, conn, "rtsp://localhost:8554/teststream/"+medias[i].Control, inTH, "") session = readSession(t, res) - var th headers.Transport - err = th.Unmarshal(res.Header["Transport"]) - require.NoError(t, err) - if transport == "udp" { serverPorts[i] = th.ServerPorts } } - res, err = writeReqReadRes(conn, base.Request{ - Method: base.Record, - URL: mustParseURL("rtsp://localhost:8554/teststream"), - Header: base.Header{ - "CSeq": base.HeaderValue{"3"}, - "Session": base.HeaderValue{session}, - }, - }) - require.NoError(t, err) - require.Equal(t, base.StatusOK, res.StatusCode) + doRecord(t, conn, "rtsp://localhost:8554/teststream", session) for i := 0; i < 2; i++ { // server -> client (direct) @@ -734,16 +710,7 @@ func TestServerRecord(t *testing.T) { } } - res, err = writeReqReadRes(conn, base.Request{ - Method: base.Teardown, - URL: mustParseURL("rtsp://localhost:8554/teststream"), - Header: base.Header{ - "CSeq": base.HeaderValue{"3"}, - "Session": base.HeaderValue{session}, - }, - }) - require.NoError(t, err) - require.Equal(t, base.StatusOK, res.StatusCode) + doTeardown(t, conn, "rtsp://localhost:8554/teststream", session) <-sessionClosed @@ -795,17 +762,7 @@ func TestServerRecordErrorInvalidProtocol(t *testing.T) { medias := media.Medias{testH264Media} resetMediaControls(medias) - res, err := writeReqReadRes(conn, base.Request{ - Method: base.Announce, - URL: mustParseURL("rtsp://localhost:8554/teststream"), - Header: base.Header{ - "CSeq": base.HeaderValue{"1"}, - "Content-Type": base.HeaderValue{"application/sdp"}, - }, - Body: mustMarshalMedias(medias), - }) - require.NoError(t, err) - require.Equal(t, base.StatusOK, res.StatusCode) + doAnnounce(t, conn, "rtsp://localhost:8554/teststream", medias) inTH := &headers.Transport{ Delivery: func() *headers.TransportDelivery { @@ -820,24 +777,11 @@ func TestServerRecordErrorInvalidProtocol(t *testing.T) { ClientPorts: &[2]int{35466, 35467}, } - res, _ = doSetup(t, conn, "rtsp://localhost:8554/teststream/"+medias[0].Control, inTH) + res, _ := doSetup(t, conn, "rtsp://localhost:8554/teststream/"+medias[0].Control, inTH, "") session := readSession(t, res) - var th headers.Transport - err = th.Unmarshal(res.Header["Transport"]) - require.NoError(t, err) - - res, err = writeReqReadRes(conn, base.Request{ - Method: base.Record, - URL: mustParseURL("rtsp://localhost:8554/teststream"), - Header: base.Header{ - "CSeq": base.HeaderValue{"3"}, - "Session": base.HeaderValue{session}, - }, - }) - require.NoError(t, err) - require.Equal(t, base.StatusOK, res.StatusCode) + doRecord(t, conn, "rtsp://localhost:8554/teststream", session) err = conn.WriteInterleavedFrame(&base.InterleavedFrame{ Channel: 0, @@ -885,17 +829,7 @@ func TestServerRecordRTCPReport(t *testing.T) { medias := media.Medias{testH264Media} resetMediaControls(medias) - res, err := writeReqReadRes(conn, base.Request{ - Method: base.Announce, - URL: mustParseURL("rtsp://localhost:8554/teststream"), - Header: base.Header{ - "CSeq": base.HeaderValue{"1"}, - "Content-Type": base.HeaderValue{"application/sdp"}, - }, - Body: mustMarshalMedias(medias), - }) - require.NoError(t, err) - require.Equal(t, base.StatusOK, res.StatusCode) + doAnnounce(t, conn, "rtsp://localhost:8554/teststream", medias) l1, err := net.ListenPacket("udp", "localhost:34556") require.NoError(t, err) @@ -918,24 +852,11 @@ func TestServerRecordRTCPReport(t *testing.T) { ClientPorts: &[2]int{34556, 34557}, } - res, _ = doSetup(t, conn, "rtsp://localhost:8554/teststream/"+medias[0].Control, inTH) + res, th := doSetup(t, conn, "rtsp://localhost:8554/teststream/"+medias[0].Control, inTH, "") session := readSession(t, res) - var th headers.Transport - err = th.Unmarshal(res.Header["Transport"]) - require.NoError(t, err) - - res, err = writeReqReadRes(conn, base.Request{ - Method: base.Record, - URL: mustParseURL("rtsp://localhost:8554/teststream"), - Header: base.Header{ - "CSeq": base.HeaderValue{"3"}, - "Session": base.HeaderValue{session}, - }, - }) - require.NoError(t, err) - require.Equal(t, base.StatusOK, res.StatusCode) + doRecord(t, conn, "rtsp://localhost:8554/teststream", session) byts, _ := (&rtp.Packet{ Header: rtp.Header{ @@ -1051,17 +972,7 @@ func TestServerRecordTimeout(t *testing.T) { medias := media.Medias{testH264Media} resetMediaControls(medias) - res, err := writeReqReadRes(conn, base.Request{ - Method: base.Announce, - URL: mustParseURL("rtsp://localhost:8554/teststream"), - Header: base.Header{ - "CSeq": base.HeaderValue{"1"}, - "Content-Type": base.HeaderValue{"application/sdp"}, - }, - Body: mustMarshalMedias(medias), - }) - require.NoError(t, err) - require.Equal(t, base.StatusOK, res.StatusCode) + doAnnounce(t, conn, "rtsp://localhost:8554/teststream", medias) inTH := &headers.Transport{ Delivery: func() *headers.TransportDelivery { @@ -1082,24 +993,11 @@ func TestServerRecordTimeout(t *testing.T) { inTH.InterleavedIDs = &[2]int{0, 1} } - res, _ = doSetup(t, conn, "rtsp://localhost:8554/teststream/"+medias[0].Control, inTH) + res, _ := doSetup(t, conn, "rtsp://localhost:8554/teststream/"+medias[0].Control, inTH, "") session := readSession(t, res) - var th headers.Transport - err = th.Unmarshal(res.Header["Transport"]) - require.NoError(t, err) - - res, err = writeReqReadRes(conn, base.Request{ - Method: base.Record, - URL: mustParseURL("rtsp://localhost:8554/teststream"), - Header: base.Header{ - "CSeq": base.HeaderValue{"3"}, - "Session": base.HeaderValue{session}, - }, - }) - require.NoError(t, err) - require.Equal(t, base.StatusOK, res.StatusCode) + doRecord(t, conn, "rtsp://localhost:8554/teststream", session) <-sessionClosed @@ -1163,17 +1061,7 @@ func TestServerRecordWithoutTeardown(t *testing.T) { medias := media.Medias{testH264Media} resetMediaControls(medias) - res, err := writeReqReadRes(conn, base.Request{ - Method: base.Announce, - URL: mustParseURL("rtsp://localhost:8554/teststream"), - Header: base.Header{ - "CSeq": base.HeaderValue{"1"}, - "Content-Type": base.HeaderValue{"application/sdp"}, - }, - Body: mustMarshalMedias(medias), - }) - require.NoError(t, err) - require.Equal(t, base.StatusOK, res.StatusCode) + doAnnounce(t, conn, "rtsp://localhost:8554/teststream", medias) inTH := &headers.Transport{ Delivery: func() *headers.TransportDelivery { @@ -1194,24 +1082,11 @@ func TestServerRecordWithoutTeardown(t *testing.T) { inTH.InterleavedIDs = &[2]int{0, 1} } - res, _ = doSetup(t, conn, "rtsp://localhost:8554/teststream/"+medias[0].Control, inTH) + res, _ := doSetup(t, conn, "rtsp://localhost:8554/teststream/"+medias[0].Control, inTH, "") session := readSession(t, res) - var th headers.Transport - err = th.Unmarshal(res.Header["Transport"]) - require.NoError(t, err) - - res, err = writeReqReadRes(conn, base.Request{ - Method: base.Record, - URL: mustParseURL("rtsp://localhost:8554/teststream"), - Header: base.Header{ - "CSeq": base.HeaderValue{"3"}, - "Session": base.HeaderValue{session}, - }, - }) - require.NoError(t, err) - require.Equal(t, base.StatusOK, res.StatusCode) + doRecord(t, conn, "rtsp://localhost:8554/teststream", session) nconn.Close() @@ -1265,17 +1140,7 @@ func TestServerRecordUDPChangeConn(t *testing.T) { medias := media.Medias{testH264Media} resetMediaControls(medias) - res, err := writeReqReadRes(conn, base.Request{ - Method: base.Announce, - URL: mustParseURL("rtsp://localhost:8554/teststream"), - Header: base.Header{ - "CSeq": base.HeaderValue{"1"}, - "Content-Type": base.HeaderValue{"application/sdp"}, - }, - Body: mustMarshalMedias(medias), - }) - require.NoError(t, err) - require.Equal(t, base.StatusOK, res.StatusCode) + doAnnounce(t, conn, "rtsp://localhost:8554/teststream", medias) inTH := &headers.Transport{ Delivery: func() *headers.TransportDelivery { @@ -1290,20 +1155,11 @@ func TestServerRecordUDPChangeConn(t *testing.T) { ClientPorts: &[2]int{35466, 35467}, } - res, _ = doSetup(t, conn, "rtsp://localhost:8554/teststream/"+medias[0].Control, inTH) + res, _ := doSetup(t, conn, "rtsp://localhost:8554/teststream/"+medias[0].Control, inTH, "") session := readSession(t, res) - res, err = writeReqReadRes(conn, base.Request{ - Method: base.Record, - URL: mustParseURL("rtsp://localhost:8554/teststream"), - Header: base.Header{ - "CSeq": base.HeaderValue{"3"}, - "Session": base.HeaderValue{session}, - }, - }) - require.NoError(t, err) - require.Equal(t, base.StatusOK, res.StatusCode) + doRecord(t, conn, "rtsp://localhost:8554/teststream", session) sxID = session }() @@ -1412,17 +1268,7 @@ func TestServerRecordDecodeErrors(t *testing.T) { }} resetMediaControls(medias) - res, err := writeReqReadRes(conn, base.Request{ - Method: base.Announce, - URL: mustParseURL("rtsp://localhost:8554/teststream"), - Header: base.Header{ - "CSeq": base.HeaderValue{"1"}, - "Content-Type": base.HeaderValue{"application/sdp"}, - }, - Body: mustMarshalMedias(medias), - }) - require.NoError(t, err) - require.Equal(t, base.StatusOK, res.StatusCode) + doAnnounce(t, conn, "rtsp://localhost:8554/teststream", medias) inTH := &headers.Transport{ Delivery: func() *headers.TransportDelivery { @@ -1456,24 +1302,11 @@ func TestServerRecordDecodeErrors(t *testing.T) { defer l2.Close() } - res, _ = doSetup(t, conn, "rtsp://localhost:8554/teststream/"+medias[0].Control, inTH) + res, resTH := doSetup(t, conn, "rtsp://localhost:8554/teststream/"+medias[0].Control, inTH, "") session := readSession(t, res) - var resTH headers.Transport - err = resTH.Unmarshal(res.Header["Transport"]) - require.NoError(t, err) - - res, err = writeReqReadRes(conn, base.Request{ - Method: base.Record, - URL: mustParseURL("rtsp://localhost:8554/teststream"), - Header: base.Header{ - "CSeq": base.HeaderValue{"3"}, - "Session": base.HeaderValue{session}, - }, - }) - require.NoError(t, err) - require.Equal(t, base.StatusOK, res.StatusCode) + doRecord(t, conn, "rtsp://localhost:8554/teststream", session) switch { //nolint:dupl case ca.proto == "udp" && ca.name == "rtp invalid": diff --git a/server_session_media.go b/server_session_media.go index c1b48302..83439cba 100644 --- a/server_session_media.go +++ b/server_session_media.go @@ -92,7 +92,7 @@ func (sm *serverSessionMedia) start() { // readers can send RTCP packets only sm.ss.s.udpRTCPListener.addClient(sm.ss.author.ip(), sm.udpRTCPReadPort, sm) } else { - // open the firewall by sending test packets to the counterpart. + // open the firewall by sending empty packets to the counterpart. sm.ss.WritePacketRTP(sm.media, &rtp.Packet{Header: rtp.Header{Version: 2}}) sm.ss.WritePacketRTCP(sm.media, &rtcp.ReceiverReport{}) diff --git a/server_test.go b/server_test.go index 82d9778d..16b36fa6 100644 --- a/server_test.go +++ b/server_test.go @@ -376,7 +376,7 @@ func TestServerErrorMethodNotImplemented(t *testing.T) { InterleavedIDs: &[2]int{0, 1}, } - res, _ := doSetup(t, conn, absoluteControlAttribute(desc.MediaDescriptions[0]), inTH) + res, _ := doSetup(t, conn, absoluteControlAttribute(desc.MediaDescriptions[0]), inTH, "") session = readSession(t, res) } @@ -468,7 +468,7 @@ func TestServerErrorTCPTwoConnOneSession(t *testing.T) { InterleavedIDs: &[2]int{0, 1}, } - res, _ := doSetup(t, conn1, absoluteControlAttribute(desc1.MediaDescriptions[0]), inTH) + res, _ := doSetup(t, conn1, absoluteControlAttribute(desc1.MediaDescriptions[0]), inTH, "") session := readSession(t, res) @@ -559,7 +559,7 @@ func TestServerErrorTCPOneConnTwoSessions(t *testing.T) { InterleavedIDs: &[2]int{0, 1}, } - res, _ := doSetup(t, conn, absoluteControlAttribute(desc.MediaDescriptions[0]), inTH) + res, _ := doSetup(t, conn, absoluteControlAttribute(desc.MediaDescriptions[0]), inTH, "") session := readSession(t, res) @@ -745,7 +745,7 @@ func TestServerGetSetParameter(t *testing.T) { InterleavedIDs: &[2]int{0, 1}, } - res, _ := doSetup(t, conn, absoluteControlAttribute(desc.MediaDescriptions[0]), inTH) + res, _ := doSetup(t, conn, absoluteControlAttribute(desc.MediaDescriptions[0]), inTH, "") session = readSession(t, res) } @@ -887,7 +887,7 @@ func TestServerSessionClose(t *testing.T) { InterleavedIDs: &[2]int{0, 1}, } - doSetup(t, conn, absoluteControlAttribute(desc.MediaDescriptions[0]), inTH) + doSetup(t, conn, absoluteControlAttribute(desc.MediaDescriptions[0]), inTH, "") session.Close() session.Close() @@ -1027,20 +1027,11 @@ func TestServerSessionTeardown(t *testing.T) { InterleavedIDs: &[2]int{0, 1}, } - res, _ := doSetup(t, conn, absoluteControlAttribute(desc.MediaDescriptions[0]), inTH) + res, _ := doSetup(t, conn, absoluteControlAttribute(desc.MediaDescriptions[0]), inTH, "") session := readSession(t, res) - res, err = writeReqReadRes(conn, base.Request{ - Method: base.Teardown, - URL: mustParseURL("rtsp://localhost:8554/"), - Header: base.Header{ - "CSeq": base.HeaderValue{"2"}, - "Session": base.HeaderValue{session}, - }, - }) - require.NoError(t, err) - require.Equal(t, base.StatusOK, res.StatusCode) + doTeardown(t, conn, "rtsp://localhost:8554/", session) res, err = writeReqReadRes(conn, base.Request{ Method: base.Options,