add *Server argument to NewServerStream()

This commit is contained in:
aler9
2023-08-12 20:19:29 +02:00
parent ca87733ded
commit 68d4bf8da0
10 changed files with 191 additions and 156 deletions

View File

@@ -2,7 +2,6 @@ package main
import (
"log"
"sync"
"time"
"github.com/bluenviron/gortsplib/v4"
@@ -18,12 +17,13 @@ const (
)
type client struct {
mutex sync.RWMutex
stream *gortsplib.ServerStream
s *server
}
func newClient() *client {
c := &client{}
func newClient(s *server) *client {
c := &client{
s: s,
}
// start a separated routine
go c.run()
@@ -40,12 +40,6 @@ func (c *client) run() {
}
}
func (c *client) getStream() *gortsplib.ServerStream {
c.mutex.RLock()
defer c.mutex.RUnlock()
return c.stream
}
func (c *client) read() error {
rc := gortsplib.Client{}
@@ -74,24 +68,11 @@ func (c *client) read() error {
return err
}
// create a server stream
stream := gortsplib.NewServerStream(medias)
defer stream.Close()
stream := c.s.setStreamReady(medias)
defer c.s.setStreamUnready()
log.Printf("stream is ready and can be read from the server at rtsp://localhost:8554/stream\n")
// make stream available by using getStream()
c.mutex.Lock()
c.stream = stream
c.mutex.Unlock()
defer func() {
// remove stream from getStream()
c.mutex.Lock()
c.stream = nil
c.mutex.Unlock()
}()
// called when a RTP packet arrives
rc.OnPacketRTPAny(func(medi *media.Media, forma formats.Format, pkt *rtp.Packet) {
// route incoming packets to the server stream

View File

@@ -1,14 +1,21 @@
package main
import "log"
// This example shows how to
// 1. read an existing stream from an external server or camera, with a client
// 2. create a server that allow to proxy that stream
// 1. create a server that allow to serve a stream.
// 2. create a client, read an existing stream from an external server or camera,
// pass the stream to the server in order to serve it.
func main() {
// allocate the client
c := newClient()
// allocate the server.
// give server access to the method client.getStream().
newServer(c.getStream)
s := newServer()
// allocate the client.
// give client access to the server.
newClient(s)
// start server and wait until a fatal error
log.Printf("server is ready")
s.s.StartAndWait()
}

View File

@@ -2,24 +2,24 @@ package main
import (
"log"
"sync"
"github.com/bluenviron/gortsplib/v4"
"github.com/bluenviron/gortsplib/v4/pkg/base"
"github.com/bluenviron/gortsplib/v4/pkg/media"
)
type server struct {
getStream func() *gortsplib.ServerStream
s *gortsplib.Server
mutex sync.Mutex
stream *gortsplib.ServerStream
}
func newServer(
getStream func() *gortsplib.ServerStream,
) *server {
s := &server{
getStream: getStream,
}
func newServer() *server {
s := &server{}
// configure the server
rs := &gortsplib.Server{
s.s = &gortsplib.Server{
Handler: s,
RTSPAddress: ":8554",
UDPRTPAddress: ":8000",
@@ -29,9 +29,7 @@ func newServer(
MulticastRTCPPort: 8003,
}
// start server and wait until a fatal error
log.Printf("server is ready")
panic(rs.StartAndWait())
return s
}
// called when a connection is opened.
@@ -58,10 +56,11 @@ func (s *server) OnSessionClose(ctx *gortsplib.ServerHandlerOnSessionCloseCtx) {
func (s *server) OnDescribe(ctx *gortsplib.ServerHandlerOnDescribeCtx) (*base.Response, *gortsplib.ServerStream, error) {
log.Printf("describe request")
stream := s.getStream()
s.mutex.Lock()
defer s.mutex.Unlock()
// stream is not available yet
if stream == nil {
if s.stream == nil {
return &base.Response{
StatusCode: base.StatusNotFound,
}, nil, nil
@@ -69,17 +68,18 @@ func (s *server) OnDescribe(ctx *gortsplib.ServerHandlerOnDescribeCtx) (*base.Re
return &base.Response{
StatusCode: base.StatusOK,
}, stream, nil
}, s.stream, nil
}
// called when receiving a SETUP request.
func (s *server) OnSetup(ctx *gortsplib.ServerHandlerOnSetupCtx) (*base.Response, *gortsplib.ServerStream, error) {
log.Printf("setup request")
stream := s.getStream()
s.mutex.Lock()
defer s.mutex.Unlock()
// stream is not available yet
if stream == nil {
if s.stream == nil {
return &base.Response{
StatusCode: base.StatusNotFound,
}, nil, nil
@@ -87,7 +87,7 @@ func (s *server) OnSetup(ctx *gortsplib.ServerHandlerOnSetupCtx) (*base.Response
return &base.Response{
StatusCode: base.StatusOK,
}, stream, nil
}, s.stream, nil
}
// called when receiving a PLAY request.
@@ -98,3 +98,17 @@ func (s *server) OnPlay(ctx *gortsplib.ServerHandlerOnPlayCtx) (*base.Response,
StatusCode: base.StatusOK,
}, nil
}
func (s *server) setStreamReady(medias media.Medias) *gortsplib.ServerStream {
s.mutex.Lock()
defer s.mutex.Unlock()
s.stream = gortsplib.NewServerStream(s.s, medias)
return s.stream
}
func (s *server) setStreamUnready() {
s.mutex.Lock()
defer s.mutex.Unlock()
s.stream.Close()
s.stream = nil
}