mirror of
https://github.com/langhuihui/monibuca.git
synced 2025-12-24 13:48:04 +08:00
- Refactor frame converter implementation - Update mp4 track to use ICodex - General refactoring and code improvements 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
100 lines
2.2 KiB
Go
100 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 {
|
|
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:
|
|
if avcc.ICodecCtx == nil {
|
|
avcc.ICodecCtx = c
|
|
}
|
|
head := avcc.NextN(1)
|
|
head[0] = byte(ParseAudioCodec(c.FourCC()))<<4 | (1 << 1)
|
|
avcc.Push(audioData.Buffers...)
|
|
}
|
|
return
|
|
}
|