BIG rewrite stream info
This commit is contained in:
+14
-2
@@ -20,7 +20,13 @@ import (
|
||||
var Timeout = time.Second * 5
|
||||
|
||||
func NewClient(uri string) *Conn {
|
||||
return &Conn{uri: uri}
|
||||
return &Conn{
|
||||
Connection: core.Connection{
|
||||
ID: core.NewID(),
|
||||
FormatName: "rtsp",
|
||||
},
|
||||
uri: uri,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Conn) Dial() (err error) {
|
||||
@@ -36,8 +42,10 @@ func (c *Conn) Dial() (err error) {
|
||||
timeout = time.Second * time.Duration(c.Timeout)
|
||||
}
|
||||
conn, err = tcp.Dial(c.URL, timeout)
|
||||
c.Protocol = "rtsp+tcp"
|
||||
} else {
|
||||
conn, err = websocket.Dial(c.Transport)
|
||||
c.Protocol = "ws"
|
||||
}
|
||||
if err != nil {
|
||||
return
|
||||
@@ -53,6 +61,10 @@ func (c *Conn) Dial() (err error) {
|
||||
c.sequence = 0
|
||||
c.state = StateConn
|
||||
|
||||
c.Connection.RemoteAddr = conn.RemoteAddr().String()
|
||||
c.Connection.Transport = conn
|
||||
c.Connection.URL = c.uri
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -143,7 +155,7 @@ func (c *Conn) Describe() error {
|
||||
}
|
||||
}
|
||||
|
||||
c.sdp = string(res.Body) // for info
|
||||
c.SDP = string(res.Body) // for info
|
||||
|
||||
medias, err := UnmarshalSDP(res.Body)
|
||||
if err != nil {
|
||||
|
||||
+5
-15
@@ -18,6 +18,7 @@ import (
|
||||
)
|
||||
|
||||
type Conn struct {
|
||||
core.Connection
|
||||
core.Listener
|
||||
|
||||
// public
|
||||
@@ -30,9 +31,7 @@ type Conn struct {
|
||||
Timeout int
|
||||
Transport string // custom transport support, ex. RTSP over WebSocket
|
||||
|
||||
Medias []*core.Media
|
||||
UserAgent string
|
||||
URL *url.URL
|
||||
URL *url.URL
|
||||
|
||||
// internal
|
||||
|
||||
@@ -44,19 +43,10 @@ type Conn struct {
|
||||
reader *bufio.Reader
|
||||
sequence int
|
||||
session string
|
||||
sdp string
|
||||
uri string
|
||||
|
||||
state State
|
||||
stateMu sync.Mutex
|
||||
|
||||
receivers []*core.Receiver
|
||||
senders []*core.Sender
|
||||
|
||||
// stats
|
||||
|
||||
recv int
|
||||
send int
|
||||
}
|
||||
|
||||
const (
|
||||
@@ -114,7 +104,7 @@ func (c *Conn) Handle() (err error) {
|
||||
// polling frames from remote RTSP Server (ex Camera)
|
||||
timeout = time.Second * 5
|
||||
|
||||
if len(c.receivers) == 0 {
|
||||
if len(c.Receivers) == 0 {
|
||||
// if we only send audio to camera
|
||||
// https://github.com/AlexxIT/go2rtc/issues/659
|
||||
timeout += keepaliveDT
|
||||
@@ -239,7 +229,7 @@ func (c *Conn) Handle() (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
c.recv += int(size)
|
||||
c.Recv += int(size)
|
||||
|
||||
if channelID&1 == 0 {
|
||||
packet := &rtp.Packet{}
|
||||
@@ -247,7 +237,7 @@ func (c *Conn) Handle() (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
for _, receiver := range c.receivers {
|
||||
for _, receiver := range c.Receivers {
|
||||
if receiver.ID == channelID {
|
||||
receiver.WriteRTP(packet)
|
||||
break
|
||||
|
||||
+4
-13
@@ -18,15 +18,6 @@ func (c *Conn) GetMedias() []*core.Media {
|
||||
}
|
||||
|
||||
func (c *Conn) AddTrack(media *core.Media, codec *core.Codec, track *core.Receiver) (err error) {
|
||||
core.Assert(media.Direction == core.DirectionSendonly)
|
||||
|
||||
for _, sender := range c.senders {
|
||||
if sender.Codec == codec {
|
||||
sender.HandleRTP(track)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
var channel byte
|
||||
|
||||
switch c.mode {
|
||||
@@ -47,12 +38,12 @@ func (c *Conn) AddTrack(media *core.Media, codec *core.Codec, track *core.Receiv
|
||||
c.state = StateSetup
|
||||
|
||||
case core.ModePassiveConsumer:
|
||||
channel = byte(len(c.senders)) * 2
|
||||
channel = byte(len(c.Senders)) * 2
|
||||
|
||||
// for consumer is better to use original track codec
|
||||
codec = track.Codec.Clone()
|
||||
// generate new payload type, starting from 96
|
||||
codec.PayloadType = byte(96 + len(c.senders))
|
||||
codec.PayloadType = byte(96 + len(c.Senders))
|
||||
|
||||
default:
|
||||
panic(core.Caller())
|
||||
@@ -70,7 +61,7 @@ func (c *Conn) AddTrack(media *core.Media, codec *core.Codec, track *core.Receiv
|
||||
|
||||
sender.HandleRTP(track)
|
||||
|
||||
c.senders = append(c.senders, sender)
|
||||
c.Senders = append(c.Senders, sender)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -99,7 +90,7 @@ func (c *Conn) packetWriter(codec *core.Codec, channel, payloadType uint8) core.
|
||||
}
|
||||
//log.Printf("[rtsp] channel:%2d write_size:%6d buffer_size:%6d", channel, n, len(buf))
|
||||
if _, err := c.conn.Write(buf[:n]); err == nil {
|
||||
c.send += n
|
||||
c.Send += n
|
||||
}
|
||||
n = 0
|
||||
}
|
||||
|
||||
+7
-25
@@ -10,7 +10,7 @@ import (
|
||||
func (c *Conn) GetTrack(media *core.Media, codec *core.Codec) (*core.Receiver, error) {
|
||||
core.Assert(media.Direction == core.DirectionRecvonly)
|
||||
|
||||
for _, track := range c.receivers {
|
||||
for _, track := range c.Receivers {
|
||||
if track.Codec == codec {
|
||||
return track, nil
|
||||
}
|
||||
@@ -34,7 +34,7 @@ func (c *Conn) GetTrack(media *core.Media, codec *core.Codec) (*core.Receiver, e
|
||||
|
||||
track := core.NewReceiver(media, codec)
|
||||
track.ID = channel
|
||||
c.receivers = append(c.receivers, track)
|
||||
c.Receivers = append(c.Receivers, track)
|
||||
|
||||
return track, nil
|
||||
}
|
||||
@@ -81,10 +81,10 @@ func (c *Conn) Start() (err error) {
|
||||
}
|
||||
|
||||
func (c *Conn) Stop() (err error) {
|
||||
for _, receiver := range c.receivers {
|
||||
for _, receiver := range c.Receivers {
|
||||
receiver.Close()
|
||||
}
|
||||
for _, sender := range c.senders {
|
||||
for _, sender := range c.Senders {
|
||||
sender.Close()
|
||||
}
|
||||
|
||||
@@ -99,25 +99,7 @@ func (c *Conn) Stop() (err error) {
|
||||
}
|
||||
|
||||
func (c *Conn) MarshalJSON() ([]byte, error) {
|
||||
info := &core.Info{
|
||||
Type: "RTSP " + c.mode.String(),
|
||||
SDP: c.sdp,
|
||||
UserAgent: c.UserAgent,
|
||||
Medias: c.Medias,
|
||||
Receivers: c.receivers,
|
||||
Senders: c.senders,
|
||||
Recv: c.recv,
|
||||
Send: c.send,
|
||||
}
|
||||
|
||||
if c.URL != nil {
|
||||
info.URL = c.URL.String()
|
||||
}
|
||||
if c.conn != nil {
|
||||
info.RemoteAddr = c.conn.RemoteAddr().String()
|
||||
}
|
||||
|
||||
return json.Marshal(info)
|
||||
return json.Marshal(c.Connection)
|
||||
}
|
||||
|
||||
func (c *Conn) Reconnect() error {
|
||||
@@ -135,12 +117,12 @@ func (c *Conn) Reconnect() error {
|
||||
}
|
||||
|
||||
// restore previous medias
|
||||
for _, receiver := range c.receivers {
|
||||
for _, receiver := range c.Receivers {
|
||||
if _, err := c.SetupMedia(receiver.Media); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, sender := range c.senders {
|
||||
for _, sender := range c.Senders {
|
||||
if _, err := c.SetupMedia(sender.Media); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
+18
-12
@@ -14,10 +14,16 @@ import (
|
||||
)
|
||||
|
||||
func NewServer(conn net.Conn) *Conn {
|
||||
c := new(Conn)
|
||||
c.conn = conn
|
||||
c.reader = bufio.NewReader(conn)
|
||||
return c
|
||||
return &Conn{
|
||||
Connection: core.Connection{
|
||||
ID: core.NewID(),
|
||||
FormatName: "rtsp",
|
||||
Protocol: "rtsp+tcp",
|
||||
RemoteAddr: conn.RemoteAddr().String(),
|
||||
},
|
||||
conn: conn,
|
||||
reader: bufio.NewReader(conn),
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Conn) Auth(username, password string) {
|
||||
@@ -70,7 +76,7 @@ func (c *Conn) Accept() error {
|
||||
return errors.New("wrong content type")
|
||||
}
|
||||
|
||||
c.sdp = string(req.Body) // for info
|
||||
c.SDP = string(req.Body) // for info
|
||||
|
||||
c.Medias, err = UnmarshalSDP(req.Body)
|
||||
if err != nil {
|
||||
@@ -81,7 +87,7 @@ func (c *Conn) Accept() error {
|
||||
for i, media := range c.Medias {
|
||||
track := core.NewReceiver(media, media.Codecs[0])
|
||||
track.ID = byte(i * 2)
|
||||
c.receivers = append(c.receivers, track)
|
||||
c.Receivers = append(c.Receivers, track)
|
||||
}
|
||||
|
||||
c.mode = core.ModePassiveProducer
|
||||
@@ -96,7 +102,7 @@ func (c *Conn) Accept() error {
|
||||
c.mode = core.ModePassiveConsumer
|
||||
c.Fire(MethodDescribe)
|
||||
|
||||
if c.senders == nil {
|
||||
if c.Senders == nil {
|
||||
res := &tcp.Response{
|
||||
Status: "404 Not Found",
|
||||
Request: req,
|
||||
@@ -113,7 +119,7 @@ func (c *Conn) Accept() error {
|
||||
|
||||
// convert tracks to real output medias medias
|
||||
var medias []*core.Media
|
||||
for i, track := range c.senders {
|
||||
for i, track := range c.Senders {
|
||||
media := &core.Media{
|
||||
Kind: core.GetKind(track.Codec.Name),
|
||||
Direction: core.DirectionRecvonly,
|
||||
@@ -128,7 +134,7 @@ func (c *Conn) Accept() error {
|
||||
return err
|
||||
}
|
||||
|
||||
c.sdp = string(res.Body) // for info
|
||||
c.SDP = string(res.Body) // for info
|
||||
|
||||
if err = c.WriteResponse(res); err != nil {
|
||||
return err
|
||||
@@ -148,9 +154,9 @@ func (c *Conn) Accept() error {
|
||||
c.state = StateSetup
|
||||
|
||||
if c.mode == core.ModePassiveConsumer {
|
||||
if i := reqTrackID(req); i >= 0 && i < len(c.senders) {
|
||||
if i := reqTrackID(req); i >= 0 && i < len(c.Senders) {
|
||||
// mark sender as SETUP
|
||||
c.senders[i].Media.ID = MethodSetup
|
||||
c.Senders[i].Media.ID = MethodSetup
|
||||
tr = fmt.Sprintf("RTP/AVP/TCP;unicast;interleaved=%d-%d", i*2, i*2+1)
|
||||
res.Header.Set("Transport", tr)
|
||||
} else {
|
||||
@@ -170,7 +176,7 @@ func (c *Conn) Accept() error {
|
||||
case MethodRecord, MethodPlay:
|
||||
if c.mode == core.ModePassiveConsumer {
|
||||
// stop unconfigured senders
|
||||
for _, track := range c.senders {
|
||||
for _, track := range c.Senders {
|
||||
if track.Media.ID != MethodSetup {
|
||||
track.Close()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user