Browse Source

fix OPTIONS method; reorder methods

pull/2/head
aler9 5 years ago
parent
commit
c3e99ee583
  1. 5
      README.md
  2. 102
      rtsp_client.go

5
README.md

@ -8,7 +8,10 @@ _rtsp-simple-server_ is a simple, ready-to-use and zero-dependency RTSP server, @@ -8,7 +8,10 @@ _rtsp-simple-server_ is a simple, ready-to-use and zero-dependency RTSP server,
This software was developed with the aim of simulating a live camera feed for debugging purposes, and therefore to use files instead of real streams. Another reason for the development was the deprecation of _FFserver_, the component of the FFmpeg project that allowed to create a RTSP server with _FFmpeg_ (but this server can be used with any software that supports RTSP).
It actually supports *one* publisher, while readers can be more than one.
Features:
* Supports reading and publishing streams
* Supports one publisher at once, while readers can be more than one.
* Supports reading via UDP and TCP
<br />

102
rtsp_client.go

@ -104,9 +104,11 @@ func (c *rtspClient) run(wg sync.WaitGroup) { @@ -104,9 +104,11 @@ func (c *rtspClient) run(wg sync.WaitGroup) {
"CSeq": cseq,
"Public": strings.Join([]string{
"DESCRIBE",
"ANNOUNCE",
"SETUP",
"PLAY",
"PAUSE",
"RECORD",
"TEARDOWN",
}, ", "),
},
@ -152,6 +154,56 @@ func (c *rtspClient) run(wg sync.WaitGroup) { @@ -152,6 +154,56 @@ func (c *rtspClient) run(wg sync.WaitGroup) {
return
}
case "ANNOUNCE":
if c.state != "STARTING" {
c.log("ERR: client is in state '%s'", c.state)
return
}
ct, ok := req.Headers["Content-Type"]
if !ok {
c.log("ERR: Content-Type header missing")
return
}
if ct != "application/sdp" {
c.log("ERR: unsupported Content-Type '%s'", ct)
return
}
err := func() error {
c.p.mutex.Lock()
defer c.p.mutex.Unlock()
if c.p.streamAuthor != nil {
return fmt.Errorf("another client is already streaming")
}
c.p.streamAuthor = c
c.p.streamSdp = req.Content
return nil
}()
if err != nil {
c.log("ERR: %s", err)
return
}
err = c.rconn.WriteResponse(&rtsp.Response{
StatusCode: 200,
Status: "OK",
Headers: map[string]string{
"CSeq": cseq,
},
})
if err != nil {
c.log("ERR: %s", err)
return
}
c.p.mutex.Lock()
c.state = "ANNOUNCE"
c.p.mutex.Unlock()
case "SETUP":
transport, ok := req.Headers["Transport"]
if !ok {
@ -354,56 +406,6 @@ func (c *rtspClient) run(wg sync.WaitGroup) { @@ -354,56 +406,6 @@ func (c *rtspClient) run(wg sync.WaitGroup) {
c.state = "RECORD"
c.p.mutex.Unlock()
case "ANNOUNCE":
if c.state != "STARTING" {
c.log("ERR: client is in state '%s'", c.state)
return
}
ct, ok := req.Headers["Content-Type"]
if !ok {
c.log("ERR: Content-Type header missing")
return
}
if ct != "application/sdp" {
c.log("ERR: unsupported Content-Type '%s'", ct)
return
}
err := func() error {
c.p.mutex.Lock()
defer c.p.mutex.Unlock()
if c.p.streamAuthor != nil {
return fmt.Errorf("another client is already streaming")
}
c.p.streamAuthor = c
c.p.streamSdp = req.Content
return nil
}()
if err != nil {
c.log("ERR: %s", err)
return
}
err = c.rconn.WriteResponse(&rtsp.Response{
StatusCode: 200,
Status: "OK",
Headers: map[string]string{
"CSeq": cseq,
},
})
if err != nil {
c.log("ERR: %s", err)
return
}
c.p.mutex.Lock()
c.state = "ANNOUNCE"
c.p.mutex.Unlock()
case "TEARDOWN":
return

Loading…
Cancel
Save