mirror of
https://github.com/langhuihui/monibuca.git
synced 2025-12-24 13:48:04 +08:00
97 lines
2.1 KiB
Go
97 lines
2.1 KiB
Go
package rtmp
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/deepch/vdk/codec/aacparser"
|
|
. "m7s.live/v5/pkg"
|
|
"m7s.live/v5/pkg/codec"
|
|
"m7s.live/v5/pkg/util"
|
|
)
|
|
|
|
type RTMPAudio struct {
|
|
RTMPData
|
|
}
|
|
|
|
func (avcc *RTMPAudio) Parse(t *AVTrack) (err error) {
|
|
reader := avcc.NewReader()
|
|
var b byte
|
|
b, err = reader.ReadByte()
|
|
if err != nil {
|
|
return
|
|
}
|
|
switch b & 0b1111_0000 >> 4 {
|
|
case 7:
|
|
if t.ICodecCtx == nil {
|
|
var ctx codec.PCMACtx
|
|
ctx.SampleRate = 8000
|
|
ctx.Channels = 1
|
|
ctx.SampleSize = 8
|
|
t.ICodecCtx = &ctx
|
|
}
|
|
case 8:
|
|
if t.ICodecCtx == nil {
|
|
var ctx codec.PCMUCtx
|
|
ctx.SampleRate = 8000
|
|
ctx.Channels = 1
|
|
ctx.SampleSize = 8
|
|
t.ICodecCtx = &ctx
|
|
}
|
|
case 10:
|
|
b, err = reader.ReadByte()
|
|
if err != nil {
|
|
return
|
|
}
|
|
if b == 0 {
|
|
var ctx codec.AACCtx
|
|
var cloneFrame RTMPAudio
|
|
cloneFrame.CopyFrom(&avcc.Memory)
|
|
ctx.CodecData, err = aacparser.NewCodecDataFromMPEG4AudioConfigBytes(cloneFrame.Buffers[0][2:])
|
|
t.SequenceFrame = &cloneFrame
|
|
t.ICodecCtx = &ctx
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func (avcc *RTMPAudio) ConvertCtx(from codec.ICodecCtx) (to codec.ICodecCtx, seq IAVFrame, err error) {
|
|
to = from.GetBase()
|
|
switch v := to.(type) {
|
|
case *codec.AACCtx:
|
|
var seqFrame RTMPAudio
|
|
seqFrame.AppendOne(append([]byte{0xAF, 0x00}, v.ConfigBytes...))
|
|
seq = &seqFrame
|
|
}
|
|
return
|
|
}
|
|
|
|
func (avcc *RTMPAudio) Demux(codecCtx codec.ICodecCtx) (raw any, err error) {
|
|
reader := avcc.NewReader()
|
|
var result util.Memory
|
|
if _, ok := codecCtx.(*codec.AACCtx); ok {
|
|
err = reader.Skip(2)
|
|
reader.Range(result.AppendOne)
|
|
return result, err
|
|
} else {
|
|
err = reader.Skip(1)
|
|
reader.Range(result.AppendOne)
|
|
return result, err
|
|
}
|
|
}
|
|
|
|
func (avcc *RTMPAudio) Mux(codecCtx codec.ICodecCtx, from *AVFrame) {
|
|
avcc.Timestamp = uint32(from.Timestamp / time.Millisecond)
|
|
audioData := from.Raw.(AudioData)
|
|
avcc.InitRecycleIndexes(1)
|
|
switch c := codecCtx.FourCC(); c {
|
|
case codec.FourCC_MP4A:
|
|
head := avcc.NextN(2)
|
|
head[0], head[1] = 0xAF, 0x01
|
|
avcc.Append(audioData.Buffers...)
|
|
case codec.FourCC_ALAW, codec.FourCC_ULAW:
|
|
head := avcc.NextN(1)
|
|
head[0] = byte(ParseAudioCodec(c))<<4 | (1 << 1)
|
|
avcc.Append(audioData.Buffers...)
|
|
}
|
|
}
|