更新依赖库aler9 到2.1.0

This commit is contained in:
dexter
2023-02-03 21:36:33 +08:00
parent 5ddbd7a852
commit 70321ccd1f
7 changed files with 156 additions and 186 deletions

View File

@@ -1,14 +1,10 @@
package rtsp
import (
"encoding/base64"
"encoding/hex"
"errors"
"fmt"
"strconv"
"strings"
"github.com/aler9/gortsplib"
"github.com/aler9/gortsplib/v2/pkg/codecs/mpeg4audio"
"github.com/aler9/gortsplib/v2/pkg/format"
"github.com/aler9/gortsplib/v2/pkg/media"
"github.com/pion/rtp"
"go.uber.org/zap"
. "m7s.live/engine/v4"
"m7s.live/engine/v4/common"
@@ -17,131 +13,65 @@ import (
type RTSPPublisher struct {
Publisher
Tracks []common.AVTrack `json:"-"`
Tracks map[*media.Media]common.AVTrack `json:"-"`
RTSPIO
}
func (p *RTSPPublisher) SetTracks() error {
p.Tracks = make([]common.AVTrack, len(p.tracks))
p.Tracks = make(map[*media.Media]common.AVTrack, len(p.tracks))
defer func() {
for i, track := range p.Tracks {
if track == nil {
p.Info("unknown track", zap.String("codec", p.tracks[i].String()))
continue
}
p.Info("set track", zap.Int("trackId", i), zap.String("name", track.GetBase().Name))
for _, track := range p.Tracks {
p.Info("set track", zap.String("name", track.GetBase().Name))
}
}()
for trackId, track := range p.tracks {
md := track.MediaDescription()
v, ok := md.Attribute("rtpmap")
if !ok {
return errors.New("rtpmap attribute not found")
}
v = strings.TrimSpace(v)
vals := strings.Split(v, " ")
if len(vals) != 2 {
continue
}
fmtp := make(map[string]string)
if v, ok = md.Attribute("fmtp"); ok {
if tmp := strings.SplitN(v, " ", 2); len(tmp) == 2 {
for _, kv := range strings.Split(tmp[1], ";") {
kv = strings.Trim(kv, " ")
if len(kv) == 0 {
continue
}
tmp := strings.SplitN(kv, "=", 2)
if len(tmp) == 2 {
fmtp[strings.TrimSpace(tmp[0])] = tmp[1]
}
for _, track := range p.tracks {
for _, forma := range track.Formats {
switch f := forma.(type) {
case *format.H264:
vt := NewH264(p.Stream, f.PayloadType())
p.Tracks[track] = vt
if len(f.SPS) > 0 {
vt.WriteSliceBytes(f.SPS)
}
}
}
timeScale := 0
keyval := strings.Split(vals[1], "/")
if i, err := strconv.Atoi(keyval[1]); err == nil {
timeScale = i
}
if len(keyval) >= 2 {
switch strings.ToLower(keyval[0]) {
case "h264":
vt := NewH264(p.Stream)
if payloadType, err := strconv.Atoi(vals[0]); err == nil {
vt.PayloadType = byte(payloadType)
if len(f.PPS) > 0 {
vt.WriteSliceBytes(f.PPS)
}
p.Tracks[trackId] = vt
t := track.(*gortsplib.TrackH264)
if len(t.SPS) > 0 {
vt.WriteSliceBytes(t.SPS)
case *format.H265:
vt := NewH265(p.Stream, f.PayloadType())
p.Tracks[track] = vt
if len(f.VPS) > 0 {
vt.WriteSliceBytes(f.VPS)
}
if len(t.PPS) > 0 {
vt.WriteSliceBytes(t.PPS)
if len(f.SPS) > 0 {
vt.WriteSliceBytes(f.SPS)
}
case "h265", "hevc":
vt := NewH265(p.Stream)
if payloadType, err := strconv.Atoi(vals[0]); err == nil {
vt.PayloadType = byte(payloadType)
if len(f.PPS) > 0 {
vt.WriteSliceBytes(f.PPS)
}
p.Tracks[trackId] = vt
if v, ok := fmtp["sprop-vps"]; ok {
vps, _ := base64.StdEncoding.DecodeString(v)
vt.WriteSliceBytes(vps)
}
if v, ok := fmtp["sprop-sps"]; ok {
sps, _ := base64.StdEncoding.DecodeString(v)
vt.WriteSliceBytes(sps)
}
if v, ok := fmtp["sprop-pps"]; ok {
pps, _ := base64.StdEncoding.DecodeString(v)
vt.WriteSliceBytes(pps)
}
case "pcma":
at := NewG711(p.Stream, true)
if payloadType, err := strconv.Atoi(vals[0]); err == nil {
at.PayloadType = byte(payloadType)
}
p.Tracks[trackId] = at
at.SampleRate = uint32(timeScale)
if len(keyval) >= 3 {
x, _ := strconv.Atoi(keyval[2])
at.Channels = byte(x)
} else {
at.Channels = 1
case *format.MPEG4Audio:
at := NewAAC(p.Stream, f.PayloadType())
p.Tracks[track] = at
at.SizeLength = f.SizeLength
if f.Config.Type == mpeg4audio.ObjectTypeAACLC {
at.Mode = 1
}
at.SampleRate = uint32(f.Config.SampleRate)
at.Channels = uint8(f.Config.ChannelCount)
asc, _ := f.Config.Marshal()
// 复用AVCC写入逻辑解析出AAC的配置信息
at.WriteSequenceHead(append([]byte{0xAF, 0x00}, asc...))
case *format.G711:
at := NewG711(p.Stream, !f.MULaw, f.PayloadType(), uint32(f.ClockRate()))
p.Tracks[track] = at
at.AVCCHead = []byte{(byte(at.CodecID) << 4) | (1 << 1)}
case "pcmu":
at := NewG711(p.Stream, false)
if payloadType, err := strconv.Atoi(vals[0]); err == nil {
at.PayloadType = byte(payloadType)
}
p.Tracks[trackId] = at
at.SampleRate = uint32(timeScale)
if len(keyval) >= 3 {
x, _ := strconv.Atoi(keyval[2])
at.Channels = byte(x)
} else {
at.Channels = 1
}
at.AVCCHead = []byte{(byte(at.CodecID) << 4) | (1 << 1)}
case "mpeg4-generic":
at := NewAAC(p.Stream)
if payloadType, err := strconv.Atoi(vals[0]); err == nil {
at.PayloadType = byte(payloadType)
}
p.Tracks[trackId] = at
if config, ok := fmtp["config"]; ok {
asc, _ := hex.DecodeString(config)
// 复用AVCC写入逻辑解析出AAC的配置信息
at.WriteSequenceHead(append([]byte{0xAF, 0x00}, asc...))
} else {
RTSPPlugin.Warn("aac no config")
}
default:
return fmt.Errorf("unsupport codec:%s", keyval[0])
}
}
}
return nil
}
func (p *RTSPPublisher) OnPacket(m *media.Media, f format.Format, pack *rtp.Packet) {
if t, ok := p.Tracks[m]; ok {
t.WriteRTPPack(pack)
}
}