mirror of
https://github.com/bluenviron/mediamtx.git
synced 2025-12-20 02:00:05 -08:00
fix OPTIONS method; reorder methods
This commit is contained in:
parent
b801f29a12
commit
c3e99ee583
2 changed files with 56 additions and 51 deletions
|
|
@ -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).
|
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 />
|
<br />
|
||||||
|
|
|
||||||
102
rtsp_client.go
102
rtsp_client.go
|
|
@ -104,9 +104,11 @@ func (c *rtspClient) run(wg sync.WaitGroup) {
|
||||||
"CSeq": cseq,
|
"CSeq": cseq,
|
||||||
"Public": strings.Join([]string{
|
"Public": strings.Join([]string{
|
||||||
"DESCRIBE",
|
"DESCRIBE",
|
||||||
|
"ANNOUNCE",
|
||||||
"SETUP",
|
"SETUP",
|
||||||
"PLAY",
|
"PLAY",
|
||||||
"PAUSE",
|
"PAUSE",
|
||||||
|
"RECORD",
|
||||||
"TEARDOWN",
|
"TEARDOWN",
|
||||||
}, ", "),
|
}, ", "),
|
||||||
},
|
},
|
||||||
|
|
@ -152,6 +154,56 @@ func (c *rtspClient) run(wg sync.WaitGroup) {
|
||||||
return
|
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":
|
case "SETUP":
|
||||||
transport, ok := req.Headers["Transport"]
|
transport, ok := req.Headers["Transport"]
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
@ -354,56 +406,6 @@ func (c *rtspClient) run(wg sync.WaitGroup) {
|
||||||
c.state = "RECORD"
|
c.state = "RECORD"
|
||||||
c.p.mutex.Unlock()
|
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":
|
case "TEARDOWN":
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue