publisher.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. package rtsp
  2. import (
  3. "strings"
  4. "github.com/bluenviron/gortsplib/v4/pkg/description"
  5. "github.com/bluenviron/gortsplib/v4/pkg/format"
  6. "github.com/bluenviron/mediacommon/pkg/codecs/mpeg4audio"
  7. "github.com/pion/rtp"
  8. "go.uber.org/zap"
  9. . "m7s.live/engine/v4"
  10. "m7s.live/engine/v4/common"
  11. . "m7s.live/engine/v4/track"
  12. )
  13. type RTSPPublisher struct {
  14. Publisher
  15. Tracks map[*description.Media]common.AVTrack `json:"-" yaml:"-"`
  16. RTSPIO
  17. }
  18. func (p *RTSPPublisher) SetTracks() error {
  19. p.Tracks = make(map[*description.Media]common.AVTrack, len(p.session.Medias))
  20. defer func() {
  21. for _, track := range p.Tracks {
  22. p.Info("set track", zap.String("name", track.GetName()))
  23. }
  24. }()
  25. for _, track := range p.session.Medias {
  26. for _, forma := range track.Formats {
  27. switch f := forma.(type) {
  28. case *format.H264:
  29. vt := p.VideoTrack
  30. if vt == nil {
  31. vt = NewH264(p.Stream, f.PayloadType())
  32. p.VideoTrack = vt
  33. }
  34. p.Tracks[track] = p.VideoTrack
  35. if len(f.SPS) > 0 {
  36. vt.WriteSliceBytes(f.SPS)
  37. }
  38. if len(f.PPS) > 0 {
  39. vt.WriteSliceBytes(f.PPS)
  40. }
  41. case *format.H265:
  42. vt := p.VideoTrack
  43. if vt == nil {
  44. vt = NewH265(p.Stream, f.PayloadType())
  45. p.VideoTrack = vt
  46. }
  47. p.Tracks[track] = p.VideoTrack
  48. if len(f.VPS) > 0 {
  49. vt.WriteSliceBytes(f.VPS)
  50. }
  51. if len(f.SPS) > 0 {
  52. vt.WriteSliceBytes(f.SPS)
  53. }
  54. if len(f.PPS) > 0 {
  55. vt.WriteSliceBytes(f.PPS)
  56. }
  57. case *format.AV1:
  58. vt := p.VideoTrack
  59. if vt == nil {
  60. vt = NewAV1(p.Stream, f.PayloadType())
  61. p.VideoTrack = vt
  62. }
  63. p.Tracks[track] = p.VideoTrack
  64. case *format.MPEG4Audio:
  65. at := p.AudioTrack
  66. if at == nil {
  67. at := NewAAC(p.Stream, f.PayloadType(), uint32(f.Config.SampleRate))
  68. at.IndexDeltaLength = f.IndexDeltaLength
  69. at.IndexLength = f.IndexLength
  70. at.SizeLength = f.SizeLength
  71. if f.Config.Type == mpeg4audio.ObjectTypeAACLC {
  72. at.Mode = 1
  73. }
  74. at.Channels = uint8(f.Config.ChannelCount)
  75. asc, _ := f.Config.Marshal()
  76. // 复用AVCC写入逻辑,解析出AAC的配置信息
  77. at.WriteSequenceHead(append([]byte{0xAF, 0x00}, asc...))
  78. p.AudioTrack = at
  79. }
  80. p.Tracks[track] = p.AudioTrack
  81. case *format.G711:
  82. at := p.AudioTrack
  83. if at == nil {
  84. at := NewG711(p.Stream, !f.MULaw, f.PayloadType(), uint32(f.ClockRate()))
  85. p.AudioTrack = at
  86. }
  87. p.Tracks[track] = p.AudioTrack
  88. case *format.Opus:
  89. at := p.AudioTrack
  90. if at == nil {
  91. at := NewOpus(p.Stream, f.PayloadType(), uint32(f.ClockRate()))
  92. p.AudioTrack = at
  93. }
  94. default:
  95. rtpMap := strings.ToLower(forma.RTPMap())
  96. if strings.Contains(rtpMap, "pcm") {
  97. isMulaw := false
  98. if strings.Contains(rtpMap, "pcmu") {
  99. isMulaw = true
  100. }
  101. at := p.AudioTrack
  102. if at == nil {
  103. at := NewG711(p.Stream, !isMulaw, f.PayloadType(), uint32(f.ClockRate()))
  104. p.AudioTrack = at
  105. }
  106. p.Tracks[track] = p.AudioTrack
  107. } else {
  108. p.Warn("unknown format", zap.Any("format", f.FMTP()))
  109. }
  110. }
  111. }
  112. }
  113. if p.VideoTrack == nil {
  114. p.Config.PubVideo = false
  115. p.Info("no video track")
  116. }
  117. if p.AudioTrack == nil {
  118. p.Config.PubAudio = false
  119. p.Info("no audio track")
  120. }
  121. return nil
  122. }
  123. func (p *RTSPPublisher) OnPacket(m *description.Media, f format.Format, pack *rtp.Packet) {
  124. if t, ok := p.Tracks[m]; ok {
  125. t.WriteRTPPack(pack)
  126. }
  127. }