Browse Source

rename path id into path name

pull/80/head
aler9 6 years ago
parent
commit
1399543e90
  1. 32
      client.go
  2. 10
      conf.go
  3. 46
      main.go
  4. 38
      path.go
  5. 12
      source.go

32
client.go

@ -83,7 +83,7 @@ type client struct {
p *program p *program
conn *gortsplib.ConnServer conn *gortsplib.ConnServer
state clientState state clientState
pathId string pathName string
authUser string authUser string
authPass string authPass string
authHelper *gortsplib.AuthServer authHelper *gortsplib.AuthServer
@ -459,8 +459,8 @@ func (c *client) handleRequest(req *gortsplib.Request) bool {
return true return true
} }
if c.pathId != "" && basePath != c.pathId { if c.pathName != "" && basePath != c.pathName {
c.writeResError(req, gortsplib.StatusBadRequest, fmt.Errorf("path has changed, was '%s', now is '%s'", c.pathId, basePath)) c.writeResError(req, gortsplib.StatusBadRequest, fmt.Errorf("path has changed, was '%s', now is '%s'", c.pathName, basePath))
return false return false
} }
@ -592,9 +592,9 @@ func (c *client) handleRequest(req *gortsplib.Request) bool {
return false return false
} }
// after ANNOUNCE, c.pathId is already set // after ANNOUNCE, c.pathName is already set
if basePath != c.pathId { if basePath != c.pathName {
c.writeResError(req, gortsplib.StatusBadRequest, fmt.Errorf("path has changed, was '%s', now is '%s'", c.pathId, basePath)) c.writeResError(req, gortsplib.StatusBadRequest, fmt.Errorf("path has changed, was '%s', now is '%s'", c.pathName, basePath))
return false return false
} }
@ -626,7 +626,7 @@ func (c *client) handleRequest(req *gortsplib.Request) bool {
return false return false
} }
if len(c.streamTracks) >= len(c.p.paths[c.pathId].publisherSdpParsed.MediaDescriptions) { if len(c.streamTracks) >= len(c.p.paths[c.pathName].publisherSdpParsed.MediaDescriptions) {
c.writeResError(req, gortsplib.StatusBadRequest, fmt.Errorf("all the tracks have already been setup")) c.writeResError(req, gortsplib.StatusBadRequest, fmt.Errorf("all the tracks have already been setup"))
return false return false
} }
@ -684,7 +684,7 @@ func (c *client) handleRequest(req *gortsplib.Request) bool {
return false return false
} }
if len(c.streamTracks) >= len(c.p.paths[c.pathId].publisherSdpParsed.MediaDescriptions) { if len(c.streamTracks) >= len(c.p.paths[c.pathName].publisherSdpParsed.MediaDescriptions) {
c.writeResError(req, gortsplib.StatusBadRequest, fmt.Errorf("all the tracks have already been setup")) c.writeResError(req, gortsplib.StatusBadRequest, fmt.Errorf("all the tracks have already been setup"))
return false return false
} }
@ -737,8 +737,8 @@ func (c *client) handleRequest(req *gortsplib.Request) bool {
// path can end with a slash, remove it // path can end with a slash, remove it
path = strings.TrimSuffix(path, "/") path = strings.TrimSuffix(path, "/")
if path != c.pathId { if path != c.pathName {
c.writeResError(req, gortsplib.StatusBadRequest, fmt.Errorf("path has changed, was '%s', now is '%s'", c.pathId, path)) c.writeResError(req, gortsplib.StatusBadRequest, fmt.Errorf("path has changed, was '%s', now is '%s'", c.pathName, path))
return false return false
} }
@ -775,12 +775,12 @@ func (c *client) handleRequest(req *gortsplib.Request) bool {
// path can end with a slash, remove it // path can end with a slash, remove it
path = strings.TrimSuffix(path, "/") path = strings.TrimSuffix(path, "/")
if path != c.pathId { if path != c.pathName {
c.writeResError(req, gortsplib.StatusBadRequest, fmt.Errorf("path has changed, was '%s', now is '%s'", c.pathId, path)) c.writeResError(req, gortsplib.StatusBadRequest, fmt.Errorf("path has changed, was '%s', now is '%s'", c.pathName, path))
return false return false
} }
if len(c.streamTracks) != len(c.p.paths[c.pathId].publisherSdpParsed.MediaDescriptions) { if len(c.streamTracks) != len(c.p.paths[c.pathName].publisherSdpParsed.MediaDescriptions) {
c.writeResError(req, gortsplib.StatusBadRequest, fmt.Errorf("not all tracks have been setup")) c.writeResError(req, gortsplib.StatusBadRequest, fmt.Errorf("not all tracks have been setup"))
return false return false
} }
@ -819,7 +819,7 @@ func (c *client) runPlay(path string) {
c.p.events <- programEventClientPlay2{done, c} c.p.events <- programEventClientPlay2{done, c}
<-done <-done
c.log("is receiving on path '%s', %d %s via %s", c.pathId, len(c.streamTracks), func() string { c.log("is receiving on path '%s', %d %s via %s", c.pathName, len(c.streamTracks), func() string {
if len(c.streamTracks) == 1 { if len(c.streamTracks) == 1 {
return "track" return "track"
} }
@ -921,7 +921,7 @@ func (c *client) runRecord(path string) {
c.p.events <- programEventClientRecord{done, c} c.p.events <- programEventClientRecord{done, c}
<-done <-done
c.log("is publishing on path '%s', %d %s via %s", c.pathId, len(c.streamTracks), func() string { c.log("is publishing on path '%s', %d %s via %s", c.pathName, len(c.streamTracks), func() string {
if len(c.streamTracks) == 1 { if len(c.streamTracks) == 1 {
return "track" return "track"
} }
@ -1025,7 +1025,7 @@ func (c *client) runRecord(path string) {
c.rtcpReceivers[frame.TrackId].OnFrame(frame.StreamType, frame.Content) c.rtcpReceivers[frame.TrackId].OnFrame(frame.StreamType, frame.Content)
c.p.events <- programEventClientFrameTcp{ c.p.events <- programEventClientFrameTcp{
c.pathId, c.pathName,
frame.TrackId, frame.TrackId,
frame.StreamType, frame.StreamType,
frame.Content, frame.Content,

10
conf.go

@ -174,10 +174,10 @@ func loadConf(fpath string, stdin io.Reader) (*conf, error) {
} }
} }
for path, confp := range conf.Paths { for name, confp := range conf.Paths {
if confp == nil { if confp == nil {
conf.Paths[path] = &confPath{} conf.Paths[name] = &confPath{}
confp = conf.Paths[path] confp = conf.Paths[name]
} }
if confp.Source == "" { if confp.Source == "" {
@ -185,7 +185,7 @@ func loadConf(fpath string, stdin io.Reader) (*conf, error) {
} }
if confp.Source != "record" { if confp.Source != "record" {
if path == "all" { if name == "all" {
return nil, fmt.Errorf("path 'all' cannot have a RTSP source; use another path") return nil, fmt.Errorf("path 'all' cannot have a RTSP source; use another path")
} }
@ -260,7 +260,7 @@ func loadConf(fpath string, stdin io.Reader) (*conf, error) {
return nil, err return nil, err
} }
if confp.RunOnDemand != "" && path == "all" { if confp.RunOnDemand != "" && name == "all" {
return nil, fmt.Errorf("path 'all' does not support option 'runOnDemand'; use another path") return nil, fmt.Errorf("path 'all' does not support option 'runOnDemand'; use another path")
} }
} }

46
main.go

@ -218,17 +218,17 @@ func newProgram(args []string, stdin io.Reader) (*program, error) {
p.log("rtsp-simple-server %s", Version) p.log("rtsp-simple-server %s", Version)
for path, confp := range conf.Paths { for name, confp := range conf.Paths {
if path == "all" { if name == "all" {
continue continue
} }
p.paths[path] = newPath(p, path, confp, true) p.paths[name] = newPath(p, name, confp, true)
if confp.Source != "record" { if confp.Source != "record" {
s := newSource(p, path, confp) s := newSource(p, name, confp)
p.sources = append(p.sources, s) p.sources = append(p.sources, s)
p.paths[path].publisher = s p.paths[name].publisher = s
} }
} }
@ -262,11 +262,11 @@ func newProgram(args []string, stdin io.Reader) (*program, error) {
return nil, err return nil, err
} }
for path, confp := range conf.Paths { for name, confp := range conf.Paths {
if confp.RunOnInit != "" { if confp.RunOnInit != "" {
onInitCmd := exec.Command("/bin/sh", "-c", confp.RunOnInit) onInitCmd := exec.Command("/bin/sh", "-c", confp.RunOnInit)
onInitCmd.Env = append(os.Environ(), onInitCmd.Env = append(os.Environ(),
"RTSP_SERVER_PATH="+path, "RTSP_SERVER_PATH="+name,
) )
onInitCmd.Stdout = os.Stdout onInitCmd.Stdout = os.Stdout
onInitCmd.Stderr = os.Stderr onInitCmd.Stderr = os.Stderr
@ -334,13 +334,13 @@ outer:
case programEventClientClose: case programEventClientClose:
delete(p.clients, evt.client) delete(p.clients, evt.client)
if evt.client.pathId != "" { if evt.client.pathName != "" {
if path, ok := p.paths[evt.client.pathId]; ok { if path, ok := p.paths[evt.client.pathName]; ok {
if path.publisher == evt.client { if path.publisher == evt.client {
path.publisherRemove() path.publisherRemove()
if !path.permanent { if !path.permanent {
delete(p.paths, evt.client.pathId) delete(p.paths, evt.client.pathName)
} }
} }
} }
@ -373,7 +373,7 @@ outer:
p.paths[evt.path].publisherSdpText = evt.sdpText p.paths[evt.path].publisherSdpText = evt.sdpText
p.paths[evt.path].publisherSdpParsed = evt.sdpParsed p.paths[evt.path].publisherSdpParsed = evt.sdpParsed
evt.client.pathId = evt.path evt.client.pathName = evt.path
evt.client.state = clientStateAnnounce evt.client.state = clientStateAnnounce
evt.res <- nil evt.res <- nil
@ -389,7 +389,7 @@ outer:
continue continue
} }
evt.client.pathId = evt.path evt.client.pathName = evt.path
evt.client.state = clientStatePrePlay evt.client.state = clientStatePrePlay
evt.res <- nil evt.res <- nil
@ -398,9 +398,9 @@ outer:
evt.res <- nil evt.res <- nil
case programEventClientPlay1: case programEventClientPlay1:
path, ok := p.paths[evt.client.pathId] path, ok := p.paths[evt.client.pathName]
if !ok || !path.publisherReady { if !ok || !path.publisherReady {
evt.res <- fmt.Errorf("no one is publishing on path '%s'", evt.client.pathId) evt.res <- fmt.Errorf("no one is publishing on path '%s'", evt.client.pathName)
continue continue
} }
@ -427,7 +427,7 @@ outer:
if evt.client.streamProtocol == gortsplib.StreamProtocolUdp { if evt.client.streamProtocol == gortsplib.StreamProtocolUdp {
p.udpClientPublishers[makeIpKey(evt.client.ip())] = evt.client p.udpClientPublishers[makeIpKey(evt.client.ip())] = evt.client
} }
p.paths[evt.client.pathId].publisherSetReady() p.paths[evt.client.pathName].publisherSetReady()
close(evt.done) close(evt.done)
case programEventClientRecordStop: case programEventClientRecordStop:
@ -436,7 +436,7 @@ outer:
if evt.client.streamProtocol == gortsplib.StreamProtocolUdp { if evt.client.streamProtocol == gortsplib.StreamProtocolUdp {
delete(p.udpClientPublishers, makeIpKey(evt.client.ip())) delete(p.udpClientPublishers, makeIpKey(evt.client.ip()))
} }
p.paths[evt.client.pathId].publisherSetNotReady() p.paths[evt.client.pathName].publisherSetNotReady()
close(evt.done) close(evt.done)
case programEventClientFrameUdp: case programEventClientFrameUdp:
@ -446,21 +446,21 @@ outer:
} }
client.rtcpReceivers[trackId].OnFrame(evt.streamType, evt.buf) client.rtcpReceivers[trackId].OnFrame(evt.streamType, evt.buf)
p.forwardFrame(client.pathId, trackId, evt.streamType, evt.buf) p.forwardFrame(client.pathName, trackId, evt.streamType, evt.buf)
case programEventClientFrameTcp: case programEventClientFrameTcp:
p.forwardFrame(evt.path, evt.trackId, evt.streamType, evt.buf) p.forwardFrame(evt.path, evt.trackId, evt.streamType, evt.buf)
case programEventSourceReady: case programEventSourceReady:
evt.source.log("ready") evt.source.log("ready")
p.paths[evt.source.pathId].publisherSetReady() p.paths[evt.source.pathName].publisherSetReady()
case programEventSourceNotReady: case programEventSourceNotReady:
evt.source.log("not ready") evt.source.log("not ready")
p.paths[evt.source.pathId].publisherSetNotReady() p.paths[evt.source.pathName].publisherSetNotReady()
case programEventSourceFrame: case programEventSourceFrame:
p.forwardFrame(evt.source.pathId, evt.trackId, evt.streamType, evt.buf) p.forwardFrame(evt.source.pathName, evt.trackId, evt.streamType, evt.buf)
case programEventTerminate: case programEventTerminate:
break outer break outer
@ -543,8 +543,8 @@ func (p *program) close() {
<-p.done <-p.done
} }
func (p *program) findConfForPath(path string) *confPath { func (p *program) findConfForPath(name string) *confPath {
if confp, ok := p.conf.Paths[path]; ok { if confp, ok := p.conf.Paths[name]; ok {
return confp return confp
} }
@ -576,7 +576,7 @@ func (p *program) findUdpClientPublisher(addr *net.UDPAddr, streamType gortsplib
func (p *program) forwardFrame(path string, trackId int, streamType gortsplib.StreamType, frame []byte) { func (p *program) forwardFrame(path string, trackId int, streamType gortsplib.StreamType, frame []byte) {
for c := range p.clients { for c := range p.clients {
if c.pathId != path || if c.pathName != path ||
c.state != clientStatePlay { c.state != clientStatePlay {
continue continue
} }

38
path.go

@ -16,7 +16,7 @@ type publisher interface {
type path struct { type path struct {
p *program p *program
id string name string
confp *confPath confp *confPath
permanent bool permanent bool
publisher publisher publisher publisher
@ -28,10 +28,10 @@ type path struct {
onDemandCmd *exec.Cmd onDemandCmd *exec.Cmd
} }
func newPath(p *program, id string, confp *confPath, permanent bool) *path { func newPath(p *program, name string, confp *confPath, permanent bool) *path {
pa := &path{ pa := &path{
p: p, p: p,
id: id, name: name,
confp: confp, confp: confp,
permanent: permanent, permanent: permanent,
} }
@ -42,7 +42,7 @@ func newPath(p *program, id string, confp *confPath, permanent bool) *path {
func (pa *path) check() { func (pa *path) check() {
hasClientsWaitingDescribe := func() bool { hasClientsWaitingDescribe := func() bool {
for c := range pa.p.clients { for c := range pa.p.clients {
if c.state == clientStateWaitingDescription && c.pathId == pa.id { if c.state == clientStateWaitingDescription && c.pathName == pa.name {
return true return true
} }
} }
@ -54,10 +54,10 @@ func (pa *path) check() {
time.Since(pa.lastActivation) >= 5*time.Second { time.Since(pa.lastActivation) >= 5*time.Second {
for c := range pa.p.clients { for c := range pa.p.clients {
if c.state == clientStateWaitingDescription && if c.state == clientStateWaitingDescription &&
c.pathId == pa.id { c.pathName == pa.name {
c.pathId = "" c.pathName = ""
c.state = clientStateInitial c.state = clientStateInitial
c.describeRes <- describeRes{nil, fmt.Errorf("publisher of path '%s' has timed out", pa.id)} c.describeRes <- describeRes{nil, fmt.Errorf("publisher of path '%s' has timed out", pa.name)}
} }
} }
@ -73,7 +73,7 @@ func (pa *path) check() {
hasClients := func() bool { hasClients := func() bool {
for c := range pa.p.clients { for c := range pa.p.clients {
if c.pathId == pa.id { if c.pathName == pa.name {
return true return true
} }
} }
@ -93,7 +93,7 @@ func (pa *path) check() {
hasClientReaders := func() bool { hasClientReaders := func() bool {
for c := range pa.p.clients { for c := range pa.p.clients {
if c.pathId == pa.id && c != pa.publisher { if c.pathName == pa.name && c != pa.publisher {
return true return true
} }
} }
@ -123,7 +123,7 @@ func (pa *path) describe(client *client) {
pa.lastActivation = time.Now() pa.lastActivation = time.Now()
pa.onDemandCmd = exec.Command("/bin/sh", "-c", pa.confp.RunOnDemand) pa.onDemandCmd = exec.Command("/bin/sh", "-c", pa.confp.RunOnDemand)
pa.onDemandCmd.Env = append(os.Environ(), pa.onDemandCmd.Env = append(os.Environ(),
"RTSP_SERVER_PATH="+pa.id, "RTSP_SERVER_PATH="+pa.name,
) )
pa.onDemandCmd.Stdout = os.Stdout pa.onDemandCmd.Stdout = os.Stdout
pa.onDemandCmd.Stderr = os.Stderr pa.onDemandCmd.Stderr = os.Stderr
@ -133,13 +133,13 @@ func (pa *path) describe(client *client) {
} }
} }
client.pathId = pa.id client.pathName = pa.name
client.state = clientStateWaitingDescription client.state = clientStateWaitingDescription
return return
} }
// no on-demand: reply with 404 // no on-demand: reply with 404
client.describeRes <- describeRes{nil, fmt.Errorf("no one is publishing on path '%s'", pa.id)} client.describeRes <- describeRes{nil, fmt.Errorf("no one is publishing on path '%s'", pa.name)}
return return
} }
@ -153,7 +153,7 @@ func (pa *path) describe(client *client) {
source.events <- sourceEventApplyState{source.state} source.events <- sourceEventApplyState{source.state}
} }
client.pathId = pa.id client.pathName = pa.name
client.state = clientStateWaitingDescription client.state = clientStateWaitingDescription
return return
} }
@ -165,10 +165,10 @@ func (pa *path) describe(client *client) {
func (pa *path) publisherRemove() { func (pa *path) publisherRemove() {
for c := range pa.p.clients { for c := range pa.p.clients {
if c.state == clientStateWaitingDescription && if c.state == clientStateWaitingDescription &&
c.pathId == pa.id { c.pathName == pa.name {
c.pathId = "" c.pathName = ""
c.state = clientStateInitial c.state = clientStateInitial
c.describeRes <- describeRes{nil, fmt.Errorf("publisher of path '%s' is not available anymore", pa.id)} c.describeRes <- describeRes{nil, fmt.Errorf("publisher of path '%s' is not available anymore", pa.name)}
} }
} }
@ -181,8 +181,8 @@ func (pa *path) publisherSetReady() {
// reply to all clients that are waiting for a description // reply to all clients that are waiting for a description
for c := range pa.p.clients { for c := range pa.p.clients {
if c.state == clientStateWaitingDescription && if c.state == clientStateWaitingDescription &&
c.pathId == pa.id { c.pathName == pa.name {
c.pathId = "" c.pathName = ""
c.state = clientStateInitial c.state = clientStateInitial
c.describeRes <- describeRes{pa.publisherSdpText, nil} c.describeRes <- describeRes{pa.publisherSdpText, nil}
} }
@ -196,7 +196,7 @@ func (pa *path) publisherSetNotReady() {
for c := range pa.p.clients { for c := range pa.p.clients {
if c.state != clientStateWaitingDescription && if c.state != clientStateWaitingDescription &&
c != pa.publisher && c != pa.publisher &&
c.pathId == pa.id { c.pathName == pa.name {
c.conn.NetConn().Close() c.conn.NetConn().Close()
} }
} }

12
source.go

@ -39,7 +39,7 @@ func (sourceEventTerminate) isSourceEvent() {}
type source struct { type source struct {
p *program p *program
pathId string pathName string
confp *confPath confp *confPath
state sourceState state sourceState
tracks []*gortsplib.Track tracks []*gortsplib.Track
@ -48,10 +48,10 @@ type source struct {
done chan struct{} done chan struct{}
} }
func newSource(p *program, pathId string, confp *confPath) *source { func newSource(p *program, pathName string, confp *confPath) *source {
s := &source{ s := &source{
p: p, p: p,
pathId: pathId, pathName: pathName,
confp: confp, confp: confp,
events: make(chan sourceEvent), events: make(chan sourceEvent),
done: make(chan struct{}), done: make(chan struct{}),
@ -67,7 +67,7 @@ func newSource(p *program, pathId string, confp *confPath) *source {
} }
func (s *source) log(format string, args ...interface{}) { func (s *source) log(format string, args ...interface{}) {
s.p.log("[source "+s.pathId+"] "+format, args...) s.p.log("[source "+s.pathName+"] "+format, args...)
} }
func (s *source) isPublisher() {} func (s *source) isPublisher() {}
@ -188,8 +188,8 @@ func (s *source) doInner(terminate chan struct{}) bool {
serverSdpParsed, serverSdpText := sdpForServer(tracks) serverSdpParsed, serverSdpText := sdpForServer(tracks)
s.tracks = tracks s.tracks = tracks
s.p.paths[s.pathId].publisherSdpText = serverSdpText s.p.paths[s.pathName].publisherSdpText = serverSdpText
s.p.paths[s.pathId].publisherSdpParsed = serverSdpParsed s.p.paths[s.pathName].publisherSdpParsed = serverSdpParsed
if s.confp.sourceProtocolParsed == gortsplib.StreamProtocolUdp { if s.confp.sourceProtocolParsed == gortsplib.StreamProtocolUdp {
return s.runUdp(terminate, conn) return s.runUdp(terminate, conn)

Loading…
Cancel
Save