Browse Source

update gohlslib (#2125)

pull/2126/head
Alessandro Ros 2 years ago committed by GitHub
parent
commit
83484b1e82
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      go.mod
  2. 12
      go.sum
  3. 12
      internal/core/hls_manager.go
  4. 34
      internal/core/hls_muxer.go
  5. 13
      internal/core/hls_source.go
  6. 43
      internal/core/mpegts_buffered_reader.go
  7. 11
      internal/core/udp_source.go

6
go.mod

@ -6,10 +6,10 @@ require (
code.cloudfoundry.org/bytefmt v0.0.0 code.cloudfoundry.org/bytefmt v0.0.0
github.com/abema/go-mp4 v0.11.0 github.com/abema/go-mp4 v0.11.0
github.com/alecthomas/kong v0.8.0 github.com/alecthomas/kong v0.8.0
github.com/asticode/go-astits v1.11.0 github.com/asticode/go-astits v1.11.1-0.20230727094110-0df190a2dd87
github.com/bluenviron/gohlslib v0.3.0 github.com/bluenviron/gohlslib v0.3.1-0.20230730162911-eb9f86511072
github.com/bluenviron/gortsplib/v3 v3.9.0 github.com/bluenviron/gortsplib/v3 v3.9.0
github.com/bluenviron/mediacommon v0.7.0 github.com/bluenviron/mediacommon v0.7.1-0.20230730144331-10b74a4f6eda
github.com/fsnotify/fsnotify v1.6.0 github.com/fsnotify/fsnotify v1.6.0
github.com/gin-gonic/gin v1.9.1 github.com/gin-gonic/gin v1.9.1
github.com/google/uuid v1.3.0 github.com/google/uuid v1.3.0

12
go.sum

@ -8,14 +8,14 @@ github.com/aler9/writerseeker v0.0.0-20220601075008-6f0e685b9c82 h1:9WgSzBLo3a9T
github.com/aler9/writerseeker v0.0.0-20220601075008-6f0e685b9c82/go.mod h1:qsMrZCbeBf/mCLOeF16KDkPu4gktn/pOWyaq1aYQE7U= github.com/aler9/writerseeker v0.0.0-20220601075008-6f0e685b9c82/go.mod h1:qsMrZCbeBf/mCLOeF16KDkPu4gktn/pOWyaq1aYQE7U=
github.com/asticode/go-astikit v0.30.0 h1:DkBkRQRIxYcknlaU7W7ksNfn4gMFsB0tqMJflxkRsZA= github.com/asticode/go-astikit v0.30.0 h1:DkBkRQRIxYcknlaU7W7ksNfn4gMFsB0tqMJflxkRsZA=
github.com/asticode/go-astikit v0.30.0/go.mod h1:h4ly7idim1tNhaVkdVBeXQZEE3L0xblP7fCWbgwipF0= github.com/asticode/go-astikit v0.30.0/go.mod h1:h4ly7idim1tNhaVkdVBeXQZEE3L0xblP7fCWbgwipF0=
github.com/asticode/go-astits v1.11.0 h1:GTHUXht0ZXAJXsVbsLIcyfHr1Bchi4QQwMARw2ZWAng= github.com/asticode/go-astits v1.11.1-0.20230727094110-0df190a2dd87 h1:SCAqalLhgKGDghGz03yYVWr8TavHluP/i7IwshKU9yA=
github.com/asticode/go-astits v1.11.0/go.mod h1:QSHmknZ51pf6KJdHKZHJTLlMegIrhega3LPWz3ND/iI= github.com/asticode/go-astits v1.11.1-0.20230727094110-0df190a2dd87/go.mod h1:QSHmknZ51pf6KJdHKZHJTLlMegIrhega3LPWz3ND/iI=
github.com/bluenviron/gohlslib v0.3.0 h1:ze8cCKszGC2LAWp0B+qIXZIlCZocB7a3BKeBo9E8Sr0= github.com/bluenviron/gohlslib v0.3.1-0.20230730162911-eb9f86511072 h1:pAbC7frXsTMxP7Ck3E50hl7oFeSeD2dgc2lWjmHXztQ=
github.com/bluenviron/gohlslib v0.3.0/go.mod h1:aO69Vu0mMUxWrLmgS6g/S3Y3sfAhyg2SXaMEL7yNlWc= github.com/bluenviron/gohlslib v0.3.1-0.20230730162911-eb9f86511072/go.mod h1:rK4b161qErs82QqvBEl84vpi2xhdZBUT0yubXuytZ7E=
github.com/bluenviron/gortsplib/v3 v3.9.0 h1:aAHV6MhsDtgBF6yKaNBBCdvtSpLB8ne4kyUfLQlN7nM= github.com/bluenviron/gortsplib/v3 v3.9.0 h1:aAHV6MhsDtgBF6yKaNBBCdvtSpLB8ne4kyUfLQlN7nM=
github.com/bluenviron/gortsplib/v3 v3.9.0/go.mod h1:5h3Zu7jkzwDknYrf+89q2saab//oioKgM9mgvBEX3pg= github.com/bluenviron/gortsplib/v3 v3.9.0/go.mod h1:5h3Zu7jkzwDknYrf+89q2saab//oioKgM9mgvBEX3pg=
github.com/bluenviron/mediacommon v0.7.0 h1:dJWLLL9oDbAqfK8KuNfnDUQwNbeMAtGeRjZc9Vo95js= github.com/bluenviron/mediacommon v0.7.1-0.20230730144331-10b74a4f6eda h1:+ungCWRNDjsy/CVL1l/UjAj4vYL4+NIJQoJJWbR3Xw8=
github.com/bluenviron/mediacommon v0.7.0/go.mod h1:wuLJdxcITiSPgY1MvQqrX+qPlKmNfeV9wNvXth5M98I= github.com/bluenviron/mediacommon v0.7.1-0.20230730144331-10b74a4f6eda/go.mod h1:tfk0qGPhqnOxVCrElu8ct3LKQn6Cj4Tpu3zbbJBTKj4=
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s=
github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=

12
internal/core/hls_manager.go

@ -57,7 +57,7 @@ type hlsManager struct {
chPathReady chan *path chPathReady chan *path
chPathNotReady chan *path chPathNotReady chan *path
chHandleRequest chan hlsMuxerHandleRequestReq chHandleRequest chan hlsMuxerHandleRequestReq
chMuxerClose chan *hlsMuxer chCloseMuxer chan *hlsMuxer
chAPIMuxerList chan hlsManagerAPIMuxersListReq chAPIMuxerList chan hlsManagerAPIMuxersListReq
chAPIMuxerGet chan hlsManagerAPIMuxersGetReq chAPIMuxerGet chan hlsManagerAPIMuxersGetReq
} }
@ -104,7 +104,7 @@ func newHLSManager(
chPathReady: make(chan *path), chPathReady: make(chan *path),
chPathNotReady: make(chan *path), chPathNotReady: make(chan *path),
chHandleRequest: make(chan hlsMuxerHandleRequestReq), chHandleRequest: make(chan hlsMuxerHandleRequestReq),
chMuxerClose: make(chan *hlsMuxer), chCloseMuxer: make(chan *hlsMuxer),
chAPIMuxerList: make(chan hlsManagerAPIMuxersListReq), chAPIMuxerList: make(chan hlsManagerAPIMuxersListReq),
chAPIMuxerGet: make(chan hlsManagerAPIMuxersGetReq), chAPIMuxerGet: make(chan hlsManagerAPIMuxersGetReq),
} }
@ -182,7 +182,7 @@ outer:
r.processRequest(&req) r.processRequest(&req)
} }
case c := <-m.chMuxerClose: case c := <-m.chCloseMuxer:
if c2, ok := m.muxers[c.PathName()]; !ok || c2 != c { if c2, ok := m.muxers[c.PathName()]; !ok || c2 != c {
continue continue
} }
@ -250,10 +250,10 @@ func (m *hlsManager) createMuxer(pathName string, remoteAddr string) *hlsMuxer {
return r return r
} }
// muxerClose is called by hlsMuxer. // closeMuxer is called by hlsMuxer.
func (m *hlsManager) muxerClose(c *hlsMuxer) { func (m *hlsManager) closeMuxer(c *hlsMuxer) {
select { select {
case m.chMuxerClose <- c: case m.chCloseMuxer <- c:
case <-m.ctx.Done(): case <-m.ctx.Done():
} }
} }

34
internal/core/hls_muxer.go

@ -54,7 +54,7 @@ type hlsMuxerHandleRequestReq struct {
type hlsMuxerParent interface { type hlsMuxerParent interface {
logger.Writer logger.Writer
muxerClose(*hlsMuxer) closeMuxer(*hlsMuxer)
} }
type hlsMuxer struct { type hlsMuxer struct {
@ -228,7 +228,7 @@ func (m *hlsMuxer) run() {
m.clearQueuedRequests() m.clearQueuedRequests()
m.parent.muxerClose(m) m.parent.closeMuxer(m)
m.Log(logger.Info, "destroyed (%v)", err) m.Log(logger.Info, "destroyed (%v)", err)
} }
@ -340,8 +340,8 @@ func (m *hlsMuxer) createVideoTrack(stream *stream.Stream) (*media.Media, *gohls
videoMedia := stream.Medias().FindFormat(&videoFormatH265) videoMedia := stream.Medias().FindFormat(&videoFormatH265)
if videoFormatH265 != nil { if videoFormatH265 != nil {
videoStartPTSFilled := false startPTSFilled := false
var videoStartPTS time.Duration var startPTS time.Duration
stream.AddReader(m, videoMedia, videoFormatH265, func(unit formatprocessor.Unit) { stream.AddReader(m, videoMedia, videoFormatH265, func(unit formatprocessor.Unit) {
m.ringBuffer.Push(func() error { m.ringBuffer.Push(func() error {
@ -351,12 +351,12 @@ func (m *hlsMuxer) createVideoTrack(stream *stream.Stream) (*media.Media, *gohls
return nil return nil
} }
if !videoStartPTSFilled { if !startPTSFilled {
videoStartPTSFilled = true startPTSFilled = true
videoStartPTS = tunit.PTS startPTS = tunit.PTS
} }
pts := tunit.PTS - videoStartPTS
pts := tunit.PTS - startPTS
err := m.muxer.WriteH26x(tunit.NTP, pts, tunit.AU) err := m.muxer.WriteH26x(tunit.NTP, pts, tunit.AU)
if err != nil { if err != nil {
return fmt.Errorf("muxer error: %v", err) return fmt.Errorf("muxer error: %v", err)
@ -381,8 +381,8 @@ func (m *hlsMuxer) createVideoTrack(stream *stream.Stream) (*media.Media, *gohls
videoMedia = stream.Medias().FindFormat(&videoFormatH264) videoMedia = stream.Medias().FindFormat(&videoFormatH264)
if videoFormatH264 != nil { if videoFormatH264 != nil {
videoStartPTSFilled := false startPTSFilled := false
var videoStartPTS time.Duration var startPTS time.Duration
stream.AddReader(m, videoMedia, videoFormatH264, func(unit formatprocessor.Unit) { stream.AddReader(m, videoMedia, videoFormatH264, func(unit formatprocessor.Unit) {
m.ringBuffer.Push(func() error { m.ringBuffer.Push(func() error {
@ -392,12 +392,12 @@ func (m *hlsMuxer) createVideoTrack(stream *stream.Stream) (*media.Media, *gohls
return nil return nil
} }
if !videoStartPTSFilled { if !startPTSFilled {
videoStartPTSFilled = true startPTSFilled = true
videoStartPTS = tunit.PTS startPTS = tunit.PTS
} }
pts := tunit.PTS - videoStartPTS
pts := tunit.PTS - startPTS
err := m.muxer.WriteH26x(tunit.NTP, pts, tunit.AU) err := m.muxer.WriteH26x(tunit.NTP, pts, tunit.AU)
if err != nil { if err != nil {
return fmt.Errorf("muxer error: %v", err) return fmt.Errorf("muxer error: %v", err)
@ -440,8 +440,8 @@ func (m *hlsMuxer) createAudioTrack(stream *stream.Stream) (*media.Media, *gohls
audioStartPTSFilled = true audioStartPTSFilled = true
audioStartPTS = tunit.PTS audioStartPTS = tunit.PTS
} }
pts := tunit.PTS - audioStartPTS
pts := tunit.PTS - audioStartPTS
err := m.muxer.WriteMPEG4Audio( err := m.muxer.WriteMPEG4Audio(
tunit.NTP, tunit.NTP,
pts, pts,
@ -483,8 +483,8 @@ func (m *hlsMuxer) createAudioTrack(stream *stream.Stream) (*media.Media, *gohls
audioStartPTSFilled = true audioStartPTSFilled = true
audioStartPTS = tunit.PTS audioStartPTS = tunit.PTS
} }
pts := tunit.PTS - audioStartPTS
pts := tunit.PTS - audioStartPTS
err := m.muxer.WriteMPEG4Audio( err := m.muxer.WriteMPEG4Audio(
tunit.NTP, tunit.NTP,
pts, pts,
@ -519,8 +519,8 @@ func (m *hlsMuxer) createAudioTrack(stream *stream.Stream) (*media.Media, *gohls
audioStartPTSFilled = true audioStartPTSFilled = true
audioStartPTS = tunit.PTS audioStartPTS = tunit.PTS
} }
pts := tunit.PTS - audioStartPTS
pts := tunit.PTS - audioStartPTS
err := m.muxer.WriteOpus( err := m.muxer.WriteOpus(
tunit.NTP, tunit.NTP,
pts, pts,

13
internal/core/hls_source.go

@ -55,8 +55,17 @@ func (s *hlsSource) run(ctx context.Context, cnf *conf.PathConf, reloadConf chan
TLSClientConfig: tlsConfigForFingerprint(cnf.SourceFingerprint), TLSClientConfig: tlsConfigForFingerprint(cnf.SourceFingerprint),
}, },
}, },
Log: func(level gohlslib.LogLevel, format string, args ...interface{}) { OnDownloadPrimaryPlaylist: func(u string) {
s.Log(logger.Level(level), format, args...) s.Log(logger.Debug, "downloading primary playlist %u", u)
},
OnDownloadStreamPlaylist: func(u string) {
s.Log(logger.Debug, "downloading stream playlist %u", u)
},
OnDownloadSegment: func(u string) {
s.Log(logger.Debug, "downloading segment %u", u)
},
OnDecodeError: func(err error) {
s.Log(logger.Warn, err.Error())
}, },
} }

43
internal/core/mpegts_buffered_reader.go

@ -1,43 +0,0 @@
package core
import (
"fmt"
"io"
)
// mpegtsBufferedReader is a buffered reader optimized for MPEG-TS.
type mpegtsBufferedReader struct {
r io.Reader
midbuf []byte
midbufpos int
}
func newMPEGTSBufferedReader(r io.Reader) *mpegtsBufferedReader {
return &mpegtsBufferedReader{
r: r,
midbuf: make([]byte, 0, 1500),
}
}
// Read implements io.Reader.
func (r *mpegtsBufferedReader) Read(p []byte) (int, error) {
if r.midbufpos < len(r.midbuf) {
n := copy(p, r.midbuf[r.midbufpos:])
r.midbufpos += n
return n, nil
}
mn, err := r.r.Read(r.midbuf[:cap(r.midbuf)])
if err != nil {
return 0, err
}
if (mn % 188) != 0 {
return 0, fmt.Errorf("received packet with size %d not multiple of 188", mn)
}
r.midbuf = r.midbuf[:mn]
n := copy(p, r.midbuf)
r.midbufpos = n
return n, nil
}

11
internal/core/udp_source.go

@ -47,17 +47,17 @@ func joinMulticastGroupOnAtLeastOneInterface(p *ipv4.PacketConn, listenIP net.IP
} }
type packetConnReader struct { type packetConnReader struct {
pc net.PacketConn net.PacketConn
} }
func newPacketConnReader(pc net.PacketConn) *packetConnReader { func newPacketConnReader(pc net.PacketConn) *packetConnReader {
return &packetConnReader{ return &packetConnReader{
pc: pc, PacketConn: pc,
} }
} }
func (r *packetConnReader) Read(p []byte) (int, error) { func (r *packetConnReader) Read(p []byte) (int, error) {
n, _, err := r.pc.ReadFrom(p) n, _, err := r.PacketConn.ReadFrom(p)
return n, err return n, err
} }
@ -116,7 +116,6 @@ func (s *udpSource) run(ctx context.Context, cnf *conf.PathConf, _ chan *conf.Pa
} }
readerErr := make(chan error) readerErr := make(chan error)
go func() { go func() {
readerErr <- s.runReader(pc) readerErr <- s.runReader(pc)
}() }()
@ -134,7 +133,7 @@ func (s *udpSource) run(ctx context.Context, cnf *conf.PathConf, _ chan *conf.Pa
func (s *udpSource) runReader(pc net.PacketConn) error { func (s *udpSource) runReader(pc net.PacketConn) error {
pc.SetReadDeadline(time.Now().Add(time.Duration(s.readTimeout))) pc.SetReadDeadline(time.Now().Add(time.Duration(s.readTimeout)))
r, err := mpegts.NewReader(newMPEGTSBufferedReader(newPacketConnReader(pc))) r, err := mpegts.NewReader(mpegts.NewBufferedReader(newPacketConnReader(pc)))
if err != nil { if err != nil {
return err return err
} }
@ -150,7 +149,7 @@ func (s *udpSource) runReader(pc net.PacketConn) error {
return td.Decode(t) return td.Decode(t)
} }
for _, track := range r.Tracks() { for _, track := range r.Tracks() { //nolint:dupl
var medi *media.Media var medi *media.Media
switch tcodec := track.Codec.(type) { switch tcodec := track.Codec.(type) {

Loading…
Cancel
Save