package aac import ( "encoding/hex" "github.com/q191201771/lal/pkg/util/log" "io" ) var adts ADTS type ADTS struct { audioObjectType uint8 samplingFrequencyIndex uint8 channelConfig uint8 frameLengthFlag uint8 dependOnCoreCoder uint8 extensionFlag uint8 adtsHeader []byte } // @param rtmp message payload,包含前面2个字节 func (obj *ADTS) PutAACSequenceHeader(payload []byte) { soundFormat := payload[0] >> 4 // 10=AAC soundRate := (payload[0] >> 2) & 0x03 // 3=44kHz. For AAC: always 3 soundSize := (payload[0] >> 1) & 0x01 // 0=snd8Bit 1=snd16Bit soundType := payload[0] & 0x01 // For AAC: always 1 //aacPacketType := payload[1] // 0:sequence header 1:AAC raw obj.audioObjectType = (payload[2] & 0xf8) >> 3 // 5bit 编码结构类型 obj.samplingFrequencyIndex = ((payload[2] & 0x07) << 1) | (payload[3] >> 7) // 4bit 音频采样率索引值 obj.channelConfig = (payload[3] & 0x78) >> 3 // 4bit 音频输出声道 obj.frameLengthFlag = (payload[3] & 0x04) >> 2 // 1bit obj.dependOnCoreCoder = (payload[3] & 0x02) >> 1 // 1bit obj.extensionFlag = payload[3] & 0x01 // 1bit log.Debugf(hex.Dump(payload[:4])) log.Debugf("%d %d %d %d", soundFormat, soundRate, soundSize, soundType) log.Debugf("%+v", obj) } // @param rtmp message payload长度,包含前面2个字节 func (obj *ADTS) GetADTS(length uint16) []byte { // adts fixed header: // syncword 12bit (0: **** ****, 1: **** 0000) 0xfff // ID 1bit (1: 0000 *000) 0 0:MPEG-4 1:MPEG-2 // layer 2bit (1: 0000 0**0) 0 // protection_absent 1bit (1: 0000 000*) 1 // profile 2bit (2: **00 0000) // sampling_frequency_index 4bit (2: 00** **00) // private_bit 1bit (2: 0000 00*0) 0 // channel_configuration 3bit (2: 0000 000*, 3: **00 0000) // origin_copy 1bit (3: 00*0 0000) 0 // home 1bit (3: 000* 0000) 0 // // adts variable_header: // copyright_identification_bit 1bit (3: 0000 *000) 0 // copyright_identification_start 1bit (3: 0000 0*00) 0 // aac_frame_length 13bit (3: 0000 00**, 5: ***0 0000) // adts_buffer_fullness 11bit (5: 000* ****, 6: **** **00) 0x7ff // number_of_raw_data_blocks_in_frame 2bit (6: 0000 00**) 0 if obj.adtsHeader == nil { obj.adtsHeader = make([]byte, 7) } obj.adtsHeader[0] = 0xff obj.adtsHeader[1] = 0xf1 obj.adtsHeader[2] = ((obj.audioObjectType - 1) << 6) & 0xc0 obj.adtsHeader[2] |= (obj.samplingFrequencyIndex << 2) & 0x3c obj.adtsHeader[2] |= (obj.channelConfig >> 2) & 0x01 obj.adtsHeader[3] = (obj.channelConfig << 6) & 0xc0 // 减去前面2个字节,加上adts的7个字节 length = length - 2 + 7 obj.adtsHeader[3] += uint8(length >> 11) // TODO chef: 为什么这样做,应该只是使用2个字节,取5个再相加是否会超出? obj.adtsHeader[4] = uint8((length & 0x7ff) >> 3) obj.adtsHeader[5] = uint8((length & 0x07) << 5) obj.adtsHeader[5] |= 0x1f obj.adtsHeader[6] = 0xfc return obj.adtsHeader } // @param rtmp message payload部分 func CaptureAAC(w io.Writer, payload []byte) { if payload[1] == 0 { adts.PutAACSequenceHeader(payload) return } _, _ = w.Write(adts.GetADTS(uint16(len(payload)))) _, _ = w.Write(payload[2:]) }