mirror of
https://github.com/aler9/gortsplib
synced 2025-10-05 23:26:54 +08:00
110 lines
1.9 KiB
Go
110 lines
1.9 KiB
Go
package main
|
|
|
|
import (
|
|
"log"
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/bluenviron/gortsplib/v3"
|
|
"github.com/bluenviron/gortsplib/v3/pkg/formats"
|
|
"github.com/bluenviron/gortsplib/v3/pkg/media"
|
|
"github.com/bluenviron/gortsplib/v3/pkg/url"
|
|
"github.com/pion/rtp"
|
|
)
|
|
|
|
const (
|
|
existingStream = "rtsp://x.x.x.x:8554/mystream"
|
|
reconnectPause = 2 * time.Second
|
|
)
|
|
|
|
type client struct {
|
|
mutex sync.RWMutex
|
|
stream *gortsplib.ServerStream
|
|
}
|
|
|
|
func newClient() *client {
|
|
c := &client{}
|
|
|
|
// start a separated routine
|
|
go c.run()
|
|
|
|
return c
|
|
}
|
|
|
|
func (c *client) run() {
|
|
for {
|
|
err := c.read()
|
|
log.Printf("ERR: %s\n", err)
|
|
|
|
time.Sleep(reconnectPause)
|
|
}
|
|
}
|
|
|
|
func (c *client) getStream() *gortsplib.ServerStream {
|
|
c.mutex.RLock()
|
|
defer c.mutex.RUnlock()
|
|
return c.stream
|
|
}
|
|
|
|
func (c *client) read() error {
|
|
rc := gortsplib.Client{}
|
|
|
|
// parse URL
|
|
u, err := url.Parse(existingStream)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// connect to the server
|
|
err = rc.Start(u.Scheme, u.Host)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer rc.Close()
|
|
|
|
// find published medias
|
|
medias, baseURL, _, err := rc.Describe(u)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// setup all medias
|
|
err = rc.SetupAll(medias, baseURL)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// create a server stream
|
|
stream := gortsplib.NewServerStream(medias)
|
|
defer stream.Close()
|
|
|
|
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
|
|
stream.WritePacketRTP(medi, pkt)
|
|
})
|
|
|
|
// start playing
|
|
_, err = rc.Play(nil)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// wait until a fatal error
|
|
return rc.Wait()
|
|
}
|