mirror of
https://github.com/aler9/gortsplib
synced 2025-10-30 10:06:28 +08:00
109
examples/proxy/client.go
Normal file
109
examples/proxy/client.go
Normal file
@@ -0,0 +1,109 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/aler9/gortsplib/v2"
|
||||
"github.com/aler9/gortsplib/v2/pkg/format"
|
||||
"github.com/aler9/gortsplib/v2/pkg/media"
|
||||
"github.com/aler9/gortsplib/v2/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 format.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()
|
||||
}
|
||||
Reference in New Issue
Block a user