Browse Source

make RTMP sources emit RTCP packets

pull/169/head
aler9 5 years ago
parent
commit
c929f3d963
  1. 2
      go.mod
  2. 4
      go.sum
  3. 60
      internal/sourcertmp/source.go

2
go.mod

@ -5,7 +5,7 @@ go 1.15
require ( require (
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d // indirect github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d // indirect
github.com/aler9/gortsplib v0.0.0-20201121145504-a21bced1dd77 github.com/aler9/gortsplib v0.0.0-20201122142543-a4849198e079
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fsnotify/fsnotify v1.4.9 github.com/fsnotify/fsnotify v1.4.9
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51

4
go.sum

@ -2,8 +2,8 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafo
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/aler9/gortsplib v0.0.0-20201121145504-a21bced1dd77 h1:iRfoLMo8Tcbc6XMMm44tcFu3ad8OZyFoDezGqvGPy30= github.com/aler9/gortsplib v0.0.0-20201122142543-a4849198e079 h1:TWNsK8SVomKWW1EO5W4TCefDuF8IfekXe4FxOQSUmrA=
github.com/aler9/gortsplib v0.0.0-20201121145504-a21bced1dd77/go.mod h1:8P09VjpiPJFyfkVosyF5/TY82jNwkMN165NS/7sc32I= github.com/aler9/gortsplib v0.0.0-20201122142543-a4849198e079/go.mod h1:8P09VjpiPJFyfkVosyF5/TY82jNwkMN165NS/7sc32I=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=

60
internal/sourcertmp/source.go

@ -8,6 +8,7 @@ import (
"time" "time"
"github.com/aler9/gortsplib" "github.com/aler9/gortsplib"
"github.com/aler9/gortsplib/pkg/rtcpsender"
"github.com/aler9/gortsplib/pkg/rtpaac" "github.com/aler9/gortsplib/pkg/rtpaac"
"github.com/aler9/gortsplib/pkg/rtph264" "github.com/aler9/gortsplib/pkg/rtph264"
"github.com/notedit/rtmp/av" "github.com/notedit/rtmp/av"
@ -184,9 +185,13 @@ func (s *Source) runInner() bool {
} }
var tracks gortsplib.Tracks var tracks gortsplib.Tracks
var videoTrack *gortsplib.Track var videoTrack *gortsplib.Track
var audioTrack *gortsplib.Track var videoRtcpSender *rtcpsender.RtcpSender
var h264Encoder *rtph264.Encoder var h264Encoder *rtph264.Encoder
var audioTrack *gortsplib.Track
var audioRtcpSender *rtcpsender.RtcpSender
var aacEncoder *rtpaac.Encoder var aacEncoder *rtpaac.Encoder
if h264Sps != nil { if h264Sps != nil {
@ -196,7 +201,10 @@ func (s *Source) runInner() bool {
return true return true
} }
h264Encoder, err = rtph264.NewEncoder(uint8(len(tracks))) clockRate, _ := videoTrack.ClockRate()
videoRtcpSender = rtcpsender.New(clockRate)
h264Encoder, err = rtph264.NewEncoder(96 + uint8(len(tracks)))
if err != nil { if err != nil {
s.parent.Log("rtmp source ERR: %s", err) s.parent.Log("rtmp source ERR: %s", err)
return true return true
@ -206,13 +214,16 @@ func (s *Source) runInner() bool {
} }
if aacConfig != nil { if aacConfig != nil {
audioTrack, err = gortsplib.NewTrackAac(len(tracks), aacConfig) audioTrack, err = gortsplib.NewTrackAAC(len(tracks), aacConfig)
if err != nil { if err != nil {
s.parent.Log("rtmp source ERR: %s", err) s.parent.Log("rtmp source ERR: %s", err)
return true return true
} }
aacEncoder, err = rtpaac.NewEncoder(uint8(len(tracks)), aacConfig) clockRate, _ := audioTrack.ClockRate()
audioRtcpSender = rtcpsender.New(clockRate)
aacEncoder, err = rtpaac.NewEncoder(96+uint8(len(tracks)), clockRate)
if err != nil { if err != nil {
s.parent.Log("rtmp source ERR: %s", err) s.parent.Log("rtmp source ERR: %s", err)
return true return true
@ -230,6 +241,39 @@ func (s *Source) runInner() bool {
s.parent.OnSourceSetReady(tracks) s.parent.OnSourceSetReady(tracks)
defer s.parent.OnSourceSetNotReady() defer s.parent.OnSourceSetNotReady()
rtcpTerminate := make(chan struct{})
rtcpDone := make(chan struct{})
go func() {
close(rtcpDone)
t := time.NewTicker(10 * time.Second)
defer t.Stop()
for {
select {
case <-t.C:
now := time.Now()
if videoRtcpSender != nil {
r := videoRtcpSender.Report(now)
if r != nil {
s.parent.OnFrame(videoTrack.Id, gortsplib.StreamTypeRtcp, r)
}
}
if audioRtcpSender != nil {
r := audioRtcpSender.Report(now)
if r != nil {
s.parent.OnFrame(audioTrack.Id, gortsplib.StreamTypeRtcp, r)
}
}
case <-rtcpTerminate:
return
}
}
}()
readerDone := make(chan error) readerDone := make(chan error)
go func() { go func() {
for { for {
@ -261,6 +305,7 @@ func (s *Source) runInner() bool {
} }
for _, f := range frames { for _, f := range frames {
videoRtcpSender.OnFrame(time.Now(), gortsplib.StreamTypeRtp, f)
s.parent.OnFrame(videoTrack.Id, gortsplib.StreamTypeRtp, f) s.parent.OnFrame(videoTrack.Id, gortsplib.StreamTypeRtp, f)
} }
@ -277,6 +322,7 @@ func (s *Source) runInner() bool {
} }
for _, f := range frames { for _, f := range frames {
audioRtcpSender.OnFrame(time.Now(), gortsplib.StreamTypeRtp, f)
s.parent.OnFrame(audioTrack.Id, gortsplib.StreamTypeRtp, f) s.parent.OnFrame(audioTrack.Id, gortsplib.StreamTypeRtp, f)
} }
@ -292,11 +338,17 @@ func (s *Source) runInner() bool {
case <-s.terminate: case <-s.terminate:
nconn.Close() nconn.Close()
<-readerDone <-readerDone
close(rtcpTerminate)
<-rtcpDone
return false return false
case err := <-readerDone: case err := <-readerDone:
nconn.Close() nconn.Close()
s.parent.Log("rtmp source ERR: %s", err) s.parent.Log("rtmp source ERR: %s", err)
close(rtcpTerminate)
<-rtcpDone
return true return true
} }
} }

Loading…
Cancel
Save