Browse Source

move sdp code into gortsplib

pull/80/head
aler9 6 years ago
parent
commit
79d0f2d053
  1. 33
      client.go
  2. 3
      go.mod
  3. 4
      go.sum
  4. 6
      main.go
  5. 10
      path.go
  6. 6
      source.go
  7. 56
      utils.go

33
client.go

@ -13,7 +13,6 @@ import (
"time" "time"
"github.com/aler9/gortsplib" "github.com/aler9/gortsplib"
"github.com/aler9/sdp-dirty/v3"
) )
const ( const (
@ -31,11 +30,11 @@ type clientDescribeReq struct {
} }
type clientAnnounceReq struct { type clientAnnounceReq struct {
res chan error res chan error
client *client client *client
pathName string pathName string
sdpText []byte trackCount int
sdpParsed *sdp.SessionDescription sdp []byte
} }
type clientSetupPlayReq struct { type clientSetupPlayReq struct {
@ -449,29 +448,21 @@ func (c *client) handleRequest(req *gortsplib.Request) error {
return errRunTerminate return errRunTerminate
} }
sdpParsed := &sdp.SessionDescription{} tracks, err := gortsplib.ReadTracks(req.Content)
err = sdpParsed.Unmarshal(req.Content)
if err != nil { if err != nil {
c.writeResError(cseq, gortsplib.StatusBadRequest, fmt.Errorf("invalid SDP: %s", err)) c.writeResError(cseq, gortsplib.StatusBadRequest, fmt.Errorf("invalid SDP: %s", err))
return errRunTerminate return errRunTerminate
} }
if len(sdpParsed.MediaDescriptions) == 0 { if len(tracks) == 0 {
c.writeResError(cseq, gortsplib.StatusBadRequest, fmt.Errorf("no tracks defined")) c.writeResError(cseq, gortsplib.StatusBadRequest, fmt.Errorf("no tracks defined"))
return errRunTerminate return errRunTerminate
} }
var tracks []*gortsplib.Track sdp := tracks.Write()
for i, media := range sdpParsed.MediaDescriptions {
tracks = append(tracks, &gortsplib.Track{
Id: i,
Media: media,
})
}
sdpParsed, req.Content = sdpForServer(tracks)
res := make(chan error) res := make(chan error)
c.p.clientAnnounce <- clientAnnounceReq{res, c, pathName, req.Content, sdpParsed} c.p.clientAnnounce <- clientAnnounceReq{res, c, pathName, len(tracks), sdp}
err = <-res err = <-res
if err != nil { if err != nil {
c.writeResError(cseq, gortsplib.StatusBadRequest, err) c.writeResError(cseq, gortsplib.StatusBadRequest, err)
@ -669,7 +660,7 @@ func (c *client) handleRequest(req *gortsplib.Request) error {
return errRunTerminate return errRunTerminate
} }
if len(c.streamTracks) >= len(c.path.publisherSdpParsed.MediaDescriptions) { if len(c.streamTracks) >= c.path.publisherTrackCount {
c.writeResError(cseq, gortsplib.StatusBadRequest, fmt.Errorf("all the tracks have already been setup")) c.writeResError(cseq, gortsplib.StatusBadRequest, fmt.Errorf("all the tracks have already been setup"))
return errRunTerminate return errRunTerminate
} }
@ -719,7 +710,7 @@ func (c *client) handleRequest(req *gortsplib.Request) error {
return errRunTerminate return errRunTerminate
} }
if len(c.streamTracks) >= len(c.path.publisherSdpParsed.MediaDescriptions) { if len(c.streamTracks) >= c.path.publisherTrackCount {
c.writeResError(cseq, gortsplib.StatusBadRequest, fmt.Errorf("all the tracks have already been setup")) c.writeResError(cseq, gortsplib.StatusBadRequest, fmt.Errorf("all the tracks have already been setup"))
return errRunTerminate return errRunTerminate
} }
@ -802,7 +793,7 @@ func (c *client) handleRequest(req *gortsplib.Request) error {
return errRunTerminate return errRunTerminate
} }
if len(c.streamTracks) != len(c.path.publisherSdpParsed.MediaDescriptions) { if len(c.streamTracks) != c.path.publisherTrackCount {
c.writeResError(cseq, gortsplib.StatusBadRequest, fmt.Errorf("not all tracks have been setup")) c.writeResError(cseq, gortsplib.StatusBadRequest, fmt.Errorf("not all tracks have been setup"))
return errRunTerminate return errRunTerminate
} }

3
go.mod

@ -5,8 +5,7 @@ go 1.12
require ( require (
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d // indirect github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d // indirect
github.com/aler9/gortsplib v0.0.0-20200905105840-e895fcfc3776 github.com/aler9/gortsplib v0.0.0-20200905123647-6d46442a79c9
github.com/aler9/sdp-dirty/v3 v3.0.0-20200905103724-214b7cc25cfd
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/stretchr/testify v1.6.1 github.com/stretchr/testify v1.6.1
gopkg.in/alecthomas/kingpin.v2 v2.2.6 gopkg.in/alecthomas/kingpin.v2 v2.2.6

4
go.sum

@ -2,8 +2,8 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafo
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/aler9/gortsplib v0.0.0-20200905105840-e895fcfc3776 h1:sQA2DjBj1VHYja5znLKmyIcSKv1/+kpyAn6qg/1WYJQ= github.com/aler9/gortsplib v0.0.0-20200905123647-6d46442a79c9 h1:0igRBY+6YHv6YoAB5WTftCf6pFnoItrSy7NrQV8tfco=
github.com/aler9/gortsplib v0.0.0-20200905105840-e895fcfc3776/go.mod h1:XybE/Zt1yFtnNEjNhAyg2w6VjD8aJ79GFfpSjkfLNd8= github.com/aler9/gortsplib v0.0.0-20200905123647-6d46442a79c9/go.mod h1:XybE/Zt1yFtnNEjNhAyg2w6VjD8aJ79GFfpSjkfLNd8=
github.com/aler9/sdp-dirty/v3 v3.0.0-20200905103724-214b7cc25cfd h1:s/l20rPNGiyjggMdkhsLu0aQ0K0OFcROUMBDu7fGT+I= github.com/aler9/sdp-dirty/v3 v3.0.0-20200905103724-214b7cc25cfd h1:s/l20rPNGiyjggMdkhsLu0aQ0K0OFcROUMBDu7fGT+I=
github.com/aler9/sdp-dirty/v3 v3.0.0-20200905103724-214b7cc25cfd/go.mod h1:5bO/aUQr9m3OasDatNNcVqKAgs7r5hgGXmszWHaC6mI= github.com/aler9/sdp-dirty/v3 v3.0.0-20200905103724-214b7cc25cfd/go.mod h1:5bO/aUQr9m3OasDatNNcVqKAgs7r5hgGXmszWHaC6mI=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=

6
main.go

@ -242,8 +242,8 @@ outer:
} }
p.paths[req.pathName].publisher = req.client p.paths[req.pathName].publisher = req.client
p.paths[req.pathName].publisherSdpText = req.sdpText p.paths[req.pathName].publisherTrackCount = req.trackCount
p.paths[req.pathName].publisherSdpParsed = req.sdpParsed p.paths[req.pathName].publisherSdp = req.sdp
req.client.path = p.paths[req.pathName] req.client.path = p.paths[req.pathName]
req.client.state = clientStatePreRecord req.client.state = clientStatePreRecord
@ -256,7 +256,7 @@ outer:
continue continue
} }
if req.trackId >= len(path.publisherSdpParsed.MediaDescriptions) { if req.trackId >= path.publisherTrackCount {
req.res <- fmt.Errorf("track %d does not exist", req.trackId) req.res <- fmt.Errorf("track %d does not exist", req.trackId)
continue continue
} }

10
path.go

@ -5,8 +5,6 @@ import (
"os" "os"
"os/exec" "os/exec"
"time" "time"
"github.com/aler9/sdp-dirty/v3"
) )
const ( const (
@ -28,8 +26,8 @@ type path struct {
source *source source *source
publisher publisher publisher publisher
publisherReady bool publisherReady bool
publisherSdpText []byte publisherTrackCount int
publisherSdpParsed *sdp.SessionDescription publisherSdp []byte
lastDescribeReq time.Time lastDescribeReq time.Time
lastDescribeActivation time.Time lastDescribeActivation time.Time
onInitCmd *exec.Cmd onInitCmd *exec.Cmd
@ -206,7 +204,7 @@ func (pa *path) onPublisherSetReady() {
c.path == pa { c.path == pa {
c.path = nil c.path = nil
c.state = clientStateInitial c.state = clientStateInitial
c.describe <- describeRes{pa.publisherSdpText, nil} c.describe <- describeRes{pa.publisherSdp, nil}
} }
} }
} }
@ -269,6 +267,6 @@ func (pa *path) onDescribe(client *client) {
// publisher was found and is ready // publisher was found and is ready
} else { } else {
client.describe <- describeRes{pa.publisherSdpText, nil} client.describe <- describeRes{pa.publisherSdp, nil}
} }
} }

6
source.go

@ -176,11 +176,11 @@ func (s *source) runInnerInner() bool {
} }
// create a filtered SDP that is used by the server (not by the client) // create a filtered SDP that is used by the server (not by the client)
serverSdpParsed, serverSdpText := sdpForServer(tracks) serverSdp := tracks.Write()
s.tracks = tracks s.tracks = tracks
s.path.publisherSdpText = serverSdpText s.path.publisherTrackCount = len(tracks)
s.path.publisherSdpParsed = serverSdpParsed s.path.publisherSdp = serverSdp
if s.confp.sourceProtocolParsed == gortsplib.StreamProtocolUDP { if s.confp.sourceProtocolParsed == gortsplib.StreamProtocolUDP {
return s.runUDP(conn) return s.runUDP(conn)

56
utils.go

@ -4,10 +4,6 @@ import (
"fmt" "fmt"
"net" "net"
"regexp" "regexp"
"strconv"
"github.com/aler9/gortsplib"
"github.com/aler9/sdp-dirty/v3"
) )
func parseIpCidrList(in []string) ([]interface{}, error) { func parseIpCidrList(in []string) ([]interface{}, error) {
@ -76,58 +72,6 @@ func (mb *multiBuffer) next() []byte {
return ret return ret
} }
// generate a sdp from scratch
func sdpForServer(tracks []*gortsplib.Track) (*sdp.SessionDescription, []byte) {
sout := &sdp.SessionDescription{
SessionName: func() *sdp.SessionName {
ret := sdp.SessionName("Stream")
return &ret
}(),
Origin: &sdp.Origin{
Username: "-",
NetworkType: "IN",
AddressType: "IP4",
UnicastAddress: "127.0.0.1",
},
TimeDescriptions: []sdp.TimeDescription{
{Timing: sdp.Timing{0, 0}},
},
}
for i, track := range tracks {
mout := &sdp.MediaDescription{
MediaName: sdp.MediaName{
Media: track.Media.MediaName.Media,
Protos: []string{"RTP", "AVP"}, // override protocol
Formats: track.Media.MediaName.Formats,
},
Bandwidth: track.Media.Bandwidth,
Attributes: func() []sdp.Attribute {
var ret []sdp.Attribute
for _, attr := range track.Media.Attributes {
if attr.Key == "rtpmap" || attr.Key == "fmtp" {
ret = append(ret, attr)
}
}
// control attribute is the path that is appended
// to the stream path in SETUP
ret = append(ret, sdp.Attribute{
Key: "control",
Value: "trackID=" + strconv.FormatInt(int64(i), 10),
})
return ret
}(),
}
sout.MediaDescriptions = append(sout.MediaDescriptions, mout)
}
bytsout, _ := sout.Marshal()
return sout, bytsout
}
func splitPath(path string) (string, string, error) { func splitPath(path string) (string, string, error) {
pos := func() int { pos := func() int {
for i := len(path) - 1; i >= 0; i-- { for i := len(path) - 1; i >= 0; i-- {

Loading…
Cancel
Save