Files
monibuca/plugin/rtmp/pkg/audio.go
2025-10-20 14:28:45 +08:00

98 lines
2.2 KiB
Go

package rtmp
import (
"github.com/deepch/vdk/codec/aacparser"
. "m7s.live/v5/pkg"
"m7s.live/v5/pkg/codec"
"m7s.live/v5/pkg/util"
)
type AudioFrame RTMPData
func (avcc *AudioFrame) CheckCodecChange() (err error) {
old := avcc.ICodecCtx
reader := avcc.NewReader()
var b byte
b, err = reader.ReadByte()
if err != nil {
return
}
switch b & 0b1111_0000 >> 4 {
case 7:
if old == nil {
var pcma codec.PCMACtx
pcma.SampleRate = 8000
pcma.Channels = 1
pcma.SampleSize = 8
avcc.ICodecCtx = &pcma
} else {
avcc.ICodecCtx = old
}
case 8:
if old == nil {
var ctx codec.PCMUCtx
ctx.SampleRate = 8000
ctx.Channels = 1
ctx.SampleSize = 8
avcc.ICodecCtx = &ctx
} else {
avcc.ICodecCtx = old
}
case 10:
b, err = reader.ReadByte()
if err != nil {
return
}
if b == 0 {
if old == nil || !avcc.Memory.Equal(&old.(*AACCtx).SequenceFrame.Memory) {
var c AACCtx
c.AACCtx = &codec.AACCtx{}
c.SequenceFrame.CopyFrom(&avcc.Memory)
c.SequenceFrame.BaseSample = &BaseSample{}
c.CodecData, err = aacparser.NewCodecDataFromMPEG4AudioConfigBytes(c.SequenceFrame.Buffers[0][2:])
avcc.ICodecCtx = &c
} else {
avcc.ICodecCtx = old
err = ErrSkip
}
} else {
avcc.ICodecCtx = old
}
}
return
}
func (avcc *AudioFrame) Demux() (err error) {
reader := avcc.NewReader()
result := avcc.GetAudioData()
if err = reader.Skip(util.Conditional(avcc.FourCC().Is(codec.FourCC_MP4A), 2, 1)); err == nil {
reader.Range(result.PushOne)
}
return
}
func (avcc *AudioFrame) Mux(fromBase *Sample) (err error) {
audioData := fromBase.Raw.(*AudioData)
avcc.InitRecycleIndexes(1)
switch c := fromBase.GetBase().(type) {
case *codec.AACCtx:
if avcc.ICodecCtx == nil || avcc.ICodecCtx.GetBase() != c {
ctx := &AACCtx{
AACCtx: c,
}
ctx.SequenceFrame.PushOne(append([]byte{0xAF, 0x00}, c.ConfigBytes...))
ctx.SequenceFrame.BaseSample = &BaseSample{}
avcc.ICodecCtx = ctx
}
head := avcc.NextN(2)
head[0], head[1] = 0xAF, 0x01
avcc.Push(audioData.Buffers...)
default:
avcc.ICodecCtx = c
head := avcc.NextN(1)
head[0] = byte(ParseAudioCodec(c.FourCC()))<<4 | (1 << 1)
avcc.Push(audioData.Buffers...)
}
return
}