mirror of
https://github.com/aler9/gortsplib
synced 2025-10-05 23:26:54 +08:00
server: support reading with VLC and multicast
This commit is contained in:
@@ -1142,7 +1142,7 @@ func (c *Client) doAnnounce(u *base.URL, tracks Tracks) (*base.Response, error)
|
|||||||
Header: base.Header{
|
Header: base.Header{
|
||||||
"Content-Type": base.HeaderValue{"application/sdp"},
|
"Content-Type": base.HeaderValue{"application/sdp"},
|
||||||
},
|
},
|
||||||
Body: tracks.Write(),
|
Body: tracks.Write(false),
|
||||||
}, false)
|
}, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@@ -76,7 +76,7 @@ func TestClientReadTracks(t *testing.T) {
|
|||||||
"Content-Type": base.HeaderValue{"application/sdp"},
|
"Content-Type": base.HeaderValue{"application/sdp"},
|
||||||
"Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"},
|
"Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"},
|
||||||
},
|
},
|
||||||
Body: tracks.Write(),
|
Body: tracks.Write(false),
|
||||||
}.Write(bconn.Writer)
|
}.Write(bconn.Writer)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@@ -237,7 +237,7 @@ func TestClientRead(t *testing.T) {
|
|||||||
"Content-Type": base.HeaderValue{"application/sdp"},
|
"Content-Type": base.HeaderValue{"application/sdp"},
|
||||||
"Content-Base": base.HeaderValue{scheme + "://" + listenIP + ":8554/test/stream?param=value/"},
|
"Content-Base": base.HeaderValue{scheme + "://" + listenIP + ":8554/test/stream?param=value/"},
|
||||||
},
|
},
|
||||||
Body: Tracks{track}.Write(),
|
Body: Tracks{track}.Write(false),
|
||||||
}.Write(bconn.Writer)
|
}.Write(bconn.Writer)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@@ -490,7 +490,7 @@ func TestClientReadNonStandardFrameSize(t *testing.T) {
|
|||||||
"Content-Type": base.HeaderValue{"application/sdp"},
|
"Content-Type": base.HeaderValue{"application/sdp"},
|
||||||
"Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"},
|
"Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"},
|
||||||
},
|
},
|
||||||
Body: Tracks{track}.Write(),
|
Body: Tracks{track}.Write(false),
|
||||||
}.Write(bconn.Writer)
|
}.Write(bconn.Writer)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@@ -591,7 +591,7 @@ func TestClientReadPartial(t *testing.T) {
|
|||||||
"Content-Type": base.HeaderValue{"application/sdp"},
|
"Content-Type": base.HeaderValue{"application/sdp"},
|
||||||
"Content-Base": base.HeaderValue{"rtsp://" + listenIP + ":8554/teststream/"},
|
"Content-Base": base.HeaderValue{"rtsp://" + listenIP + ":8554/teststream/"},
|
||||||
},
|
},
|
||||||
Body: tracks.Write(),
|
Body: tracks.Write(false),
|
||||||
}.Write(bconn.Writer)
|
}.Write(bconn.Writer)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@@ -728,7 +728,7 @@ func TestClientReadNoContentBase(t *testing.T) {
|
|||||||
Header: base.Header{
|
Header: base.Header{
|
||||||
"Content-Type": base.HeaderValue{"application/sdp"},
|
"Content-Type": base.HeaderValue{"application/sdp"},
|
||||||
},
|
},
|
||||||
Body: tracks.Write(),
|
Body: tracks.Write(false),
|
||||||
}.Write(bconn.Writer)
|
}.Write(bconn.Writer)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@@ -840,7 +840,7 @@ func TestClientReadAnyPort(t *testing.T) {
|
|||||||
"Content-Type": base.HeaderValue{"application/sdp"},
|
"Content-Type": base.HeaderValue{"application/sdp"},
|
||||||
"Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"},
|
"Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"},
|
||||||
},
|
},
|
||||||
Body: tracks.Write(),
|
Body: tracks.Write(false),
|
||||||
}.Write(bconn.Writer)
|
}.Write(bconn.Writer)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@@ -968,7 +968,7 @@ func TestClientReadAutomaticProtocol(t *testing.T) {
|
|||||||
"Content-Type": base.HeaderValue{"application/sdp"},
|
"Content-Type": base.HeaderValue{"application/sdp"},
|
||||||
"Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"},
|
"Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"},
|
||||||
},
|
},
|
||||||
Body: tracks.Write(),
|
Body: tracks.Write(false),
|
||||||
}.Write(bconn.Writer)
|
}.Write(bconn.Writer)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@@ -1098,7 +1098,7 @@ func TestClientReadAutomaticProtocol(t *testing.T) {
|
|||||||
"Content-Type": base.HeaderValue{"application/sdp"},
|
"Content-Type": base.HeaderValue{"application/sdp"},
|
||||||
"Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"},
|
"Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"},
|
||||||
},
|
},
|
||||||
Body: tracks.Write(),
|
Body: tracks.Write(false),
|
||||||
}.Write(bconn.Writer)
|
}.Write(bconn.Writer)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@@ -1286,7 +1286,7 @@ func TestClientReadDifferentInterleavedIDs(t *testing.T) {
|
|||||||
"Content-Type": base.HeaderValue{"application/sdp"},
|
"Content-Type": base.HeaderValue{"application/sdp"},
|
||||||
"Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"},
|
"Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"},
|
||||||
},
|
},
|
||||||
Body: tracks.Write(),
|
Body: tracks.Write(false),
|
||||||
}.Write(bconn.Writer)
|
}.Write(bconn.Writer)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@@ -1443,7 +1443,7 @@ func TestClientReadRedirect(t *testing.T) {
|
|||||||
"Content-Type": base.HeaderValue{"application/sdp"},
|
"Content-Type": base.HeaderValue{"application/sdp"},
|
||||||
"Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"},
|
"Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"},
|
||||||
},
|
},
|
||||||
Body: tracks.Write(),
|
Body: tracks.Write(false),
|
||||||
}.Write(bconn.Writer)
|
}.Write(bconn.Writer)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@@ -1600,7 +1600,7 @@ func TestClientReadPause(t *testing.T) {
|
|||||||
"Content-Type": base.HeaderValue{"application/sdp"},
|
"Content-Type": base.HeaderValue{"application/sdp"},
|
||||||
"Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"},
|
"Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"},
|
||||||
},
|
},
|
||||||
Body: tracks.Write(),
|
Body: tracks.Write(false),
|
||||||
}.Write(bconn.Writer)
|
}.Write(bconn.Writer)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@@ -1768,7 +1768,7 @@ func TestClientReadRTCPReport(t *testing.T) {
|
|||||||
"Content-Type": base.HeaderValue{"application/sdp"},
|
"Content-Type": base.HeaderValue{"application/sdp"},
|
||||||
"Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"},
|
"Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"},
|
||||||
},
|
},
|
||||||
Body: tracks.Write(),
|
Body: tracks.Write(false),
|
||||||
}.Write(bconn.Writer)
|
}.Write(bconn.Writer)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@@ -1942,7 +1942,7 @@ func TestClientReadErrorTimeout(t *testing.T) {
|
|||||||
"Content-Type": base.HeaderValue{"application/sdp"},
|
"Content-Type": base.HeaderValue{"application/sdp"},
|
||||||
"Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"},
|
"Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"},
|
||||||
},
|
},
|
||||||
Body: tracks.Write(),
|
Body: tracks.Write(false),
|
||||||
}.Write(bconn.Writer)
|
}.Write(bconn.Writer)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@@ -2096,7 +2096,7 @@ func TestClientReadIgnoreTCPInvalidTrack(t *testing.T) {
|
|||||||
"Content-Type": base.HeaderValue{"application/sdp"},
|
"Content-Type": base.HeaderValue{"application/sdp"},
|
||||||
"Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"},
|
"Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"},
|
||||||
},
|
},
|
||||||
Body: tracks.Write(),
|
Body: tracks.Write(false),
|
||||||
}.Write(bconn.Writer)
|
}.Write(bconn.Writer)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@@ -2221,7 +2221,7 @@ func TestClientReadSeek(t *testing.T) {
|
|||||||
"Content-Type": base.HeaderValue{"application/sdp"},
|
"Content-Type": base.HeaderValue{"application/sdp"},
|
||||||
"Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"},
|
"Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"},
|
||||||
},
|
},
|
||||||
Body: tracks.Write(),
|
Body: tracks.Write(false),
|
||||||
}.Write(bconn.Writer)
|
}.Write(bconn.Writer)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
@@ -80,7 +80,7 @@ func TestClientSession(t *testing.T) {
|
|||||||
"Content-Type": base.HeaderValue{"application/sdp"},
|
"Content-Type": base.HeaderValue{"application/sdp"},
|
||||||
"Session": base.HeaderValue{"123456"},
|
"Session": base.HeaderValue{"123456"},
|
||||||
},
|
},
|
||||||
Body: tracks.Write(),
|
Body: tracks.Write(false),
|
||||||
}.Write(bconn.Writer)
|
}.Write(bconn.Writer)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}()
|
}()
|
||||||
@@ -161,7 +161,7 @@ func TestClientAuth(t *testing.T) {
|
|||||||
Header: base.Header{
|
Header: base.Header{
|
||||||
"Content-Type": base.HeaderValue{"application/sdp"},
|
"Content-Type": base.HeaderValue{"application/sdp"},
|
||||||
},
|
},
|
||||||
Body: tracks.Write(),
|
Body: tracks.Write(false),
|
||||||
}.Write(bconn.Writer)
|
}.Write(bconn.Writer)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}()
|
}()
|
||||||
@@ -225,7 +225,7 @@ func TestClientDescribeCharset(t *testing.T) {
|
|||||||
"Content-Type": base.HeaderValue{"application/sdp; charset=utf-8"},
|
"Content-Type": base.HeaderValue{"application/sdp; charset=utf-8"},
|
||||||
"Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"},
|
"Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"},
|
||||||
},
|
},
|
||||||
Body: Tracks{track1}.Write(),
|
Body: Tracks{track1}.Write(false),
|
||||||
}.Write(bconn.Writer)
|
}.Write(bconn.Writer)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}()
|
}()
|
||||||
|
@@ -372,7 +372,7 @@ func TestServerPublishErrorSetupDifferentPaths(t *testing.T) {
|
|||||||
"CSeq": base.HeaderValue{"1"},
|
"CSeq": base.HeaderValue{"1"},
|
||||||
"Content-Type": base.HeaderValue{"application/sdp"},
|
"Content-Type": base.HeaderValue{"application/sdp"},
|
||||||
},
|
},
|
||||||
Body: tracks.Write(),
|
Body: tracks.Write(false),
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, base.StatusOK, res.StatusCode)
|
require.Equal(t, base.StatusOK, res.StatusCode)
|
||||||
@@ -455,7 +455,7 @@ func TestServerPublishErrorSetupTrackTwice(t *testing.T) {
|
|||||||
"CSeq": base.HeaderValue{"1"},
|
"CSeq": base.HeaderValue{"1"},
|
||||||
"Content-Type": base.HeaderValue{"application/sdp"},
|
"Content-Type": base.HeaderValue{"application/sdp"},
|
||||||
},
|
},
|
||||||
Body: tracks.Write(),
|
Body: tracks.Write(false),
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, base.StatusOK, res.StatusCode)
|
require.Equal(t, base.StatusOK, res.StatusCode)
|
||||||
@@ -558,7 +558,7 @@ func TestServerPublishErrorRecordPartialTracks(t *testing.T) {
|
|||||||
"CSeq": base.HeaderValue{"1"},
|
"CSeq": base.HeaderValue{"1"},
|
||||||
"Content-Type": base.HeaderValue{"application/sdp"},
|
"Content-Type": base.HeaderValue{"application/sdp"},
|
||||||
},
|
},
|
||||||
Body: tracks.Write(),
|
Body: tracks.Write(false),
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, base.StatusOK, res.StatusCode)
|
require.Equal(t, base.StatusOK, res.StatusCode)
|
||||||
@@ -704,7 +704,7 @@ func TestServerPublish(t *testing.T) {
|
|||||||
"CSeq": base.HeaderValue{"1"},
|
"CSeq": base.HeaderValue{"1"},
|
||||||
"Content-Type": base.HeaderValue{"application/sdp"},
|
"Content-Type": base.HeaderValue{"application/sdp"},
|
||||||
},
|
},
|
||||||
Body: tracks.Write(),
|
Body: tracks.Write(false),
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, base.StatusOK, res.StatusCode)
|
require.Equal(t, base.StatusOK, res.StatusCode)
|
||||||
@@ -892,7 +892,7 @@ func TestServerPublishNonStandardFrameSize(t *testing.T) {
|
|||||||
"CSeq": base.HeaderValue{"1"},
|
"CSeq": base.HeaderValue{"1"},
|
||||||
"Content-Type": base.HeaderValue{"application/sdp"},
|
"Content-Type": base.HeaderValue{"application/sdp"},
|
||||||
},
|
},
|
||||||
Body: Tracks{track}.Write(),
|
Body: Tracks{track}.Write(false),
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, base.StatusOK, res.StatusCode)
|
require.Equal(t, base.StatusOK, res.StatusCode)
|
||||||
@@ -996,7 +996,7 @@ func TestServerPublishErrorInvalidProtocol(t *testing.T) {
|
|||||||
"CSeq": base.HeaderValue{"1"},
|
"CSeq": base.HeaderValue{"1"},
|
||||||
"Content-Type": base.HeaderValue{"application/sdp"},
|
"Content-Type": base.HeaderValue{"application/sdp"},
|
||||||
},
|
},
|
||||||
Body: tracks.Write(),
|
Body: tracks.Write(false),
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, base.StatusOK, res.StatusCode)
|
require.Equal(t, base.StatusOK, res.StatusCode)
|
||||||
@@ -1098,7 +1098,7 @@ func TestServerPublishRTCPReport(t *testing.T) {
|
|||||||
"CSeq": base.HeaderValue{"1"},
|
"CSeq": base.HeaderValue{"1"},
|
||||||
"Content-Type": base.HeaderValue{"application/sdp"},
|
"Content-Type": base.HeaderValue{"application/sdp"},
|
||||||
},
|
},
|
||||||
Body: tracks.Write(),
|
Body: tracks.Write(false),
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, base.StatusOK, res.StatusCode)
|
require.Equal(t, base.StatusOK, res.StatusCode)
|
||||||
@@ -1258,7 +1258,7 @@ func TestServerPublishTimeout(t *testing.T) {
|
|||||||
"CSeq": base.HeaderValue{"1"},
|
"CSeq": base.HeaderValue{"1"},
|
||||||
"Content-Type": base.HeaderValue{"application/sdp"},
|
"Content-Type": base.HeaderValue{"application/sdp"},
|
||||||
},
|
},
|
||||||
Body: tracks.Write(),
|
Body: tracks.Write(false),
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, base.StatusOK, res.StatusCode)
|
require.Equal(t, base.StatusOK, res.StatusCode)
|
||||||
@@ -1386,7 +1386,7 @@ func TestServerPublishWithoutTeardown(t *testing.T) {
|
|||||||
"CSeq": base.HeaderValue{"1"},
|
"CSeq": base.HeaderValue{"1"},
|
||||||
"Content-Type": base.HeaderValue{"application/sdp"},
|
"Content-Type": base.HeaderValue{"application/sdp"},
|
||||||
},
|
},
|
||||||
Body: tracks.Write(),
|
Body: tracks.Write(false),
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, base.StatusOK, res.StatusCode)
|
require.Equal(t, base.StatusOK, res.StatusCode)
|
||||||
@@ -1506,7 +1506,7 @@ func TestServerPublishUDPChangeConn(t *testing.T) {
|
|||||||
"CSeq": base.HeaderValue{"1"},
|
"CSeq": base.HeaderValue{"1"},
|
||||||
"Content-Type": base.HeaderValue{"application/sdp"},
|
"Content-Type": base.HeaderValue{"application/sdp"},
|
||||||
},
|
},
|
||||||
Body: tracks.Write(),
|
Body: tracks.Write(false),
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, base.StatusOK, res.StatusCode)
|
require.Equal(t, base.StatusOK, res.StatusCode)
|
||||||
|
@@ -11,6 +11,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pion/rtp"
|
"github.com/pion/rtp"
|
||||||
|
psdp "github.com/pion/sdp/v3"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"golang.org/x/net/ipv4"
|
"golang.org/x/net/ipv4"
|
||||||
|
|
||||||
@@ -570,6 +571,54 @@ func TestServerRead(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestServerReadVLCMulticast(t *testing.T) {
|
||||||
|
track, err := NewTrackH264(96, &TrackConfigH264{[]byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
stream := NewServerStream(Tracks{track})
|
||||||
|
|
||||||
|
listenIP := multicastCapableIP(t)
|
||||||
|
|
||||||
|
s := &Server{
|
||||||
|
Handler: &testServerHandler{
|
||||||
|
onDescribe: func(ctx *ServerHandlerOnDescribeCtx) (*base.Response, *ServerStream, error) {
|
||||||
|
return &base.Response{
|
||||||
|
StatusCode: base.StatusOK,
|
||||||
|
}, stream, nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
RTSPAddress: listenIP + ":8554",
|
||||||
|
MulticastIPRange: "224.1.0.0/16",
|
||||||
|
MulticastRTPPort: 8000,
|
||||||
|
MulticastRTCPPort: 8001,
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.Start()
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer s.Close()
|
||||||
|
|
||||||
|
nconn, err := net.Dial("tcp", listenIP+":8554")
|
||||||
|
require.NoError(t, err)
|
||||||
|
bconn := bufio.NewReadWriter(bufio.NewReader(nconn), bufio.NewWriter(nconn))
|
||||||
|
defer nconn.Close()
|
||||||
|
|
||||||
|
res, err := writeReqReadRes(bconn, base.Request{
|
||||||
|
Method: base.Describe,
|
||||||
|
URL: mustParseURL("rtsp://" + listenIP + ":8554/teststream?vlcmulticast"),
|
||||||
|
Header: base.Header{
|
||||||
|
"CSeq": base.HeaderValue{"1"},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, base.StatusOK, res.StatusCode)
|
||||||
|
|
||||||
|
var desc psdp.SessionDescription
|
||||||
|
err = desc.Unmarshal(res.Body)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.Equal(t, "224.1.0.0", desc.ConnectionInformation.Address.Address)
|
||||||
|
}
|
||||||
|
|
||||||
func TestServerReadNonStandardFrameSize(t *testing.T) {
|
func TestServerReadNonStandardFrameSize(t *testing.T) {
|
||||||
track, err := NewTrackH264(96, &TrackConfigH264{[]byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}})
|
track, err := NewTrackH264(96, &TrackConfigH264{[]byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@@ -1171,7 +1171,7 @@ func TestServerErrorInvalidPath(t *testing.T) {
|
|||||||
"CSeq": base.HeaderValue{"1"},
|
"CSeq": base.HeaderValue{"1"},
|
||||||
"Content-Type": base.HeaderValue{"application/sdp"},
|
"Content-Type": base.HeaderValue{"application/sdp"},
|
||||||
},
|
},
|
||||||
Body: tracks.Write(),
|
Body: tracks.Write(false),
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, base.StatusOK, res.StatusCode)
|
require.Equal(t, base.StatusOK, res.StatusCode)
|
||||||
|
@@ -5,6 +5,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"net"
|
"net"
|
||||||
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -377,8 +378,20 @@ func (sc *ServerConn) handleRequest(req *base.Request) (*base.Response, error) {
|
|||||||
res.Header["Content-Base"] = base.HeaderValue{req.URL.String() + "/"}
|
res.Header["Content-Base"] = base.HeaderValue{req.URL.String() + "/"}
|
||||||
res.Header["Content-Type"] = base.HeaderValue{"application/sdp"}
|
res.Header["Content-Type"] = base.HeaderValue{"application/sdp"}
|
||||||
|
|
||||||
|
// VLC uses multicast if the SDP contains a multicast address.
|
||||||
|
// therefore, we introduce a special query (vlcmulticast) that allows
|
||||||
|
// to return a SDP that contains a multicast address.
|
||||||
|
multicast := false
|
||||||
|
if sc.s.MulticastIPRange != "" {
|
||||||
|
if q, err := url.ParseQuery(query); err == nil {
|
||||||
|
if _, ok := q["vlcmulticast"]; ok {
|
||||||
|
multicast = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if stream != nil {
|
if stream != nil {
|
||||||
res.Body = stream.Tracks().Write()
|
res.Body = stream.Tracks().Write(multicast)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
11
track.go
11
track.go
@@ -128,7 +128,7 @@ type Tracks []*Track
|
|||||||
|
|
||||||
// ReadTracks decodes tracks from SDP.
|
// ReadTracks decodes tracks from SDP.
|
||||||
func ReadTracks(byts []byte) (Tracks, error) {
|
func ReadTracks(byts []byte) (Tracks, error) {
|
||||||
desc := sdp.SessionDescription{}
|
var desc sdp.SessionDescription
|
||||||
err := desc.Unmarshal(byts)
|
err := desc.Unmarshal(byts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -192,7 +192,12 @@ func cloneAndClearTracks(ts Tracks) Tracks {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Write encodes tracks into SDP.
|
// Write encodes tracks into SDP.
|
||||||
func (ts Tracks) Write() []byte {
|
func (ts Tracks) Write(multicast bool) []byte {
|
||||||
|
address := "0.0.0.0"
|
||||||
|
if multicast {
|
||||||
|
address = "224.1.0.0"
|
||||||
|
}
|
||||||
|
|
||||||
sout := &sdp.SessionDescription{
|
sout := &sdp.SessionDescription{
|
||||||
SessionName: psdp.SessionName("Stream"),
|
SessionName: psdp.SessionName("Stream"),
|
||||||
Origin: psdp.Origin{
|
Origin: psdp.Origin{
|
||||||
@@ -205,7 +210,7 @@ func (ts Tracks) Write() []byte {
|
|||||||
ConnectionInformation: &psdp.ConnectionInformation{
|
ConnectionInformation: &psdp.ConnectionInformation{
|
||||||
NetworkType: "IN",
|
NetworkType: "IN",
|
||||||
AddressType: "IP4",
|
AddressType: "IP4",
|
||||||
Address: &psdp.Address{Address: "0.0.0.0"},
|
Address: &psdp.Address{Address: address},
|
||||||
},
|
},
|
||||||
TimeDescriptions: []psdp.TimeDescription{
|
TimeDescriptions: []psdp.TimeDescription{
|
||||||
{Timing: psdp.Timing{0, 0}}, //nolint:govet
|
{Timing: psdp.Timing{0, 0}}, //nolint:govet
|
||||||
|
Reference in New Issue
Block a user