package rtsp import ( "fmt" "net" "net/url" "time" "m7s.live/v5" "m7s.live/v5/pkg/util" ) func NewPullProxy() m7s.IPullProxy { return &RTSPPullProxy{} } type RTSPPullProxy struct { m7s.TCPPullProxy conn Stream } func (d *RTSPPullProxy) Start() (err error) { d.URL, err = url.Parse(d.PullProxyConfig.URL) if err != nil { return } if ips, err := net.LookupIP(d.URL.Hostname()); err != nil { return err } else if len(ips) == 0 { return fmt.Errorf("no IP found for host: %s", d.URL.Hostname()) } else { d.TCPAddr, err = net.ResolveTCPAddr("tcp", net.JoinHostPort(ips[0].String(), d.URL.Port())) if err != nil { return err } if d.TCPAddr.Port == 0 { d.TCPAddr.Port = 554 // Default RTSP port } } d.conn.NetConnection = &NetConnection{ MemoryAllocator: util.NewScalableMemoryAllocator(1 << 12), UserAgent: "monibuca" + m7s.Version, } d.conn.Logger = d.Logger return d.TCPPullProxy.Start() } func (d *RTSPPullProxy) Dispose() { if d.conn.NetConnection != nil && d.conn.NetConnection.Conn != nil { _ = d.conn.Teardown() d.conn.NetConnection.Dispose() d.conn.NetConnection = nil } d.TCPPullProxy.Dispose() d.Info("RTSP pull proxy disposed and all resources cleaned up") } func (d *RTSPPullProxy) GetTickInterval() time.Duration { return time.Second * 5 } func (d *RTSPPullProxy) Tick(any) { var err error switch d.Status { case m7s.PullProxyStatusOffline: err = d.conn.Connect(d.PullProxyConfig.URL) if err != nil { return } d.ChangeStatus(m7s.PullProxyStatusOnline) case m7s.PullProxyStatusOnline, m7s.PullProxyStatusPulling: if d.conn.Conn == nil { err = d.conn.Connect(d.PullProxyConfig.URL) } else { t := time.Now() err = d.conn.Options() d.RTT = time.Since(t) } if err != nil { d.ChangeStatus(m7s.PullProxyStatusOffline) } } }