diff --git a/go.mod b/go.mod index 1f0d969..7ec8583 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/bluenviron/mediacommon v1.5.0 github.com/pion/rtp v1.8.2 go.uber.org/zap v1.24.0 - m7s.live/engine/v4 v4.13.12 + m7s.live/engine/v4 v4.14.3 ) require ( @@ -26,6 +26,7 @@ require ( github.com/pion/rtcp v1.2.10 // indirect github.com/pion/sdp/v3 v3.0.6 // indirect github.com/pion/webrtc/v3 v3.2.14 // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b // indirect github.com/q191201771/naza v0.30.11 // indirect github.com/quic-go/qtls-go1-20 v0.3.1 // indirect diff --git a/go.sum b/go.sum index 0cb3345..deeae21 100644 --- a/go.sum +++ b/go.sum @@ -117,6 +117,7 @@ github.com/pion/webrtc/v3 v3.2.14 h1:GlqnBnnLlcYYA/LOwqLLU1plZYwx0Y/e/57bZ2tzQcU github.com/pion/webrtc/v3 v3.2.14/go.mod h1:r1mtixc2MH847mmQTPwlEvGge7D18C2T5qp8jI9Lm44= github.com/pixelbender/go-sdp v1.1.0/go.mod h1:6IBlz9+BrUHoFTea7gcp4S54khtOhjCW/nVDLhmZBAs= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= @@ -301,5 +302,5 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -m7s.live/engine/v4 v4.13.12 h1:GYdIPlvwkS57DbZGvQxgMJIKL+hyYZpOv/8qNjGbY6E= -m7s.live/engine/v4 v4.13.12/go.mod h1:cRR/WOZbPSAQfYxIHuCkj1YMg+C54CYlFpOJ88q+OG4= +m7s.live/engine/v4 v4.14.3 h1:yTUm40lQ+wI7/IkO2UvPZAbKAS5ovmbdm2DPe+twhl4= +m7s.live/engine/v4 v4.14.3/go.mod h1:cRR/WOZbPSAQfYxIHuCkj1YMg+C54CYlFpOJ88q+OG4= diff --git a/publisher.go b/publisher.go index 646c928..ee380cd 100644 --- a/publisher.go +++ b/publisher.go @@ -57,7 +57,14 @@ func (p *RTSPPublisher) SetTracks() error { } if len(f.PPS) > 0 { vt.WriteSliceBytes(f.PPS) + } + case *format.AV1: + vt := p.VideoTrack + if vt == nil { + vt = NewAV1(p.Stream, f.PayloadType()) + p.VideoTrack = vt } + p.Tracks[track] = p.VideoTrack case *format.MPEG4Audio: at := p.AudioTrack if at == nil { @@ -82,6 +89,12 @@ func (p *RTSPPublisher) SetTracks() error { p.AudioTrack = at } p.Tracks[track] = p.AudioTrack + case *format.Opus: + at := p.AudioTrack + if at == nil { + at := NewOpus(p.Stream, f.PayloadType(), uint32(f.ClockRate())) + p.AudioTrack = at + } default: rtpMap := strings.ToLower(forma.RTPMap()) if strings.Contains(rtpMap, "pcm") { diff --git a/subscriber.go b/subscriber.go index 7d375f3..86dd62f 100644 --- a/subscriber.go +++ b/subscriber.go @@ -25,7 +25,7 @@ func (s *RTSPSubscriber) OnEvent(event any) { } switch v.CodecID { case codec.CodecID_H264: - video := &description.Media{ + s.videoTrack = &description.Media{ Type: description.MediaTypeVideo, Formats: []format.Format{&format.H264{ PacketizationMode: 1, @@ -34,10 +34,8 @@ func (s *RTSPSubscriber) OnEvent(event any) { PPS: v.ParamaterSets[1], }}, } - s.videoTrack = video - s.tracks = append(s.tracks, video) case codec.CodecID_H265: - video := &description.Media{ + s.videoTrack = &description.Media{ Type: description.MediaTypeVideo, Formats: []format.Format{&format.H265{ PayloadTyp: v.PayloadType, @@ -46,17 +44,32 @@ func (s *RTSPSubscriber) OnEvent(event any) { PPS: v.ParamaterSets[2], }}, } - s.videoTrack = video - s.tracks = append(s.tracks, video) + case codec.CodecID_AV1: + var idx, profile, tail int + idx = int(v.ParamaterSets[1][0]) + profile = int(v.ParamaterSets[1][1]) + tail = int(v.ParamaterSets[1][2]) + s.videoTrack = &description.Media{ + Type: description.MediaTypeVideo, + Formats: []format.Format{&format.AV1{ + PayloadTyp: v.PayloadType, + LevelIdx: &idx, + Profile: &profile, + Tier: &tail, + }}, + } + } + if s.videoTrack != nil { + s.tracks = append(s.tracks, s.videoTrack) + s.AddTrack(v) } - s.AddTrack(v) case *track.Audio: if s.Audio != nil { return } switch v.CodecID { case codec.CodecID_AAC: - audio := &description.Media{ + s.audioTrack = &description.Media{ Type: description.MediaTypeAudio, Formats: []format.Format{&format.MPEG4Audio{ PayloadTyp: v.PayloadType, @@ -70,10 +83,8 @@ func (s *RTSPSubscriber) OnEvent(event any) { IndexDeltaLength: v.IndexDeltaLength, }}, } - s.audioTrack = audio - s.tracks = append(s.tracks, audio) case codec.CodecID_PCMA: - audio := &description.Media{ + s.audioTrack = &description.Media{ Type: description.MediaTypeAudio, Formats: []format.Format{&format.Generic{ PayloadTyp: v.PayloadType, @@ -81,10 +92,8 @@ func (s *RTSPSubscriber) OnEvent(event any) { RTPMa: fmt.Sprintf("PCMA/%d", v.SampleRate), }}, } - s.audioTrack = audio - s.tracks = append(s.tracks, audio) case codec.CodecID_PCMU: - audio := &description.Media{ + s.audioTrack = &description.Media{ Type: description.MediaTypeAudio, Formats: []format.Format{&format.Generic{ PayloadTyp: v.PayloadType, @@ -92,10 +101,18 @@ func (s *RTSPSubscriber) OnEvent(event any) { RTPMa: fmt.Sprintf("PCMU/%d", v.SampleRate), }}, } - s.audioTrack = audio - s.tracks = append(s.tracks, audio) + case codec.CodecID_OPUS: + s.audioTrack = &description.Media{ + Type: description.MediaTypeAudio, + Formats: []format.Format{&format.Opus{ + PayloadTyp: v.PayloadType, + }}, + } + } + if s.audioTrack != nil { + s.tracks = append(s.tracks, s.audioTrack) + s.AddTrack(v) } - s.AddTrack(v) case ISubscriber: s.session = &description.Session{ Medias: s.tracks,