github.com/cnotch/ipchub@v1.1.0/av/format/flv/audiodata.go (about) 1 // Copyright (c) 2019,CAOHONGJU All rights reserved. 2 // Use of this source code is governed by a MIT-style 3 // license that can be found in the LICENSE file. 4 5 package flv 6 7 import "errors" 8 9 // SoundFormat UB [4] 10 // Format of SoundData. The following values are defined: 11 // 0 = Linear PCM, platform endian 12 // 1 = ADPCM 13 // 2 = MP3 14 // 3 = Linear PCM, little endian 15 // 4 = Nellymoser 16 kHz mono 16 // 5 = Nellymoser 8 kHz mono 17 // 6 = Nellymoser 18 // 7 = G.711 A-law logarithmic PCM 19 // 8 = G.711 mu-law logarithmic PCM 20 // 9 = reserved 21 // 10 = AAC 22 // 11 = Speex 23 // 14 = MP3 8 kHz 24 // 15 = Device-specific sound 25 // Formats 7, 8, 14, and 15 are reserved. 26 // AAC is supported in Flash Player 9,0,115,0 and higher. 27 // Speex is supported in Flash Player 10 and higher. 28 const ( 29 SoundFormatLinearPCMPlatformEndian = 0 30 SoundFormatADPCM = 1 31 SoundFormatMP3 = 2 32 SoundFormatLinearPCMLittleEndian = 3 33 SoundFormatNellymoser16kHzMono = 4 34 SoundFormatNellymoser8kHzMono = 5 35 SoundFormatNellymoser = 6 36 SoundFormatReservedG711AlawLogarithmicPCM = 7 37 SoundFormatReservedG711MuLawLogarithmicPCM = 8 38 SoundFormatReserved = 9 39 SoundFormatAAC = 10 40 SoundFormatSpeex = 11 41 SoundFormatReservedMP3Of8kHz = 14 42 SoundFormatReservedDeviceSpecificSound = 15 43 SoundFormatReserved1 = 16 44 ) 45 46 // SoundFormatName 音频格式名称 47 func SoundFormatName(codec int32) string { 48 switch codec { 49 case SoundFormatLinearPCMPlatformEndian: 50 return "LinearPCMPlatformEndian" 51 case SoundFormatADPCM: 52 return "ADPCM" 53 case SoundFormatLinearPCMLittleEndian: 54 return "LinearPCMLittleEndian" 55 case SoundFormatNellymoser16kHzMono: 56 return "Nellymoser16kHzMono" 57 case SoundFormatNellymoser8kHzMono: 58 return "Nellymoser8kHzMono" 59 case SoundFormatNellymoser: 60 return "Nellymoser" 61 case SoundFormatAAC: 62 return "AAC" 63 case SoundFormatSpeex: 64 return "Speex" 65 default: 66 return "" 67 } 68 } 69 70 // the FLV/RTMP supported audio sample rate. 71 // Sampling rate. The following values are defined: 72 // 0 = 5.5 kHz = 5512 Hz 73 // 1 = 11 kHz = 11025 Hz 74 // 2 = 22 kHz = 22050 Hz 75 // 3 = 44 kHz = 44100 Hz 76 const ( 77 SoundRate5512 = 0 78 SoundRate11025 = 1 79 SoundRate22050 = 2 80 SoundRate44100 = 3 81 SoundRateReserved = 4 82 ) 83 84 // the FLV/RTMP supported audio sample size. 85 // Size of each audio sample. This parameter only pertains to 86 // uncompressed formats. Compressed formats always decode 87 // to 16 bits internally. 88 // 0 = 8-bit samples 89 // 1 = 16-bit samples 90 const ( 91 SoundeSize8bit = 0 92 SoundeSize16bit = 1 93 SoundeSizeReserved = 2 94 ) 95 96 // the FLV/RTMP supported audio sound type/channel. 97 // Mono or stereo sound 98 // 0 = Mono sound 99 // 1 = Stereo sound 100 const ( 101 SoundTypeMono = 0 102 SoundTypeStereo = 1 103 SoundTypeReserved = 2 104 ) 105 106 // flv format 107 // AACPacketType IF SoundFormat == 10 UI8 108 // The following values are defined: 109 // 0 = AAC sequence header 110 // 1 = AAC raw 111 const ( 112 AACPacketTypeSequenceHeader = 0 // 序列头 113 AACPacketTypeRawData = 1 // 原始数据 114 AACPacketTypeReserved = 2 115 ) 116 117 // AudioData flv Tag 中的的音频数据 118 // 119 // 对于 SoundFormat == SoundFormatAAC,Body 值: 120 // IF AACPacketType == AACPacketTypeSequenceHeader 121 // AudioSpecificConfig 参考 AAC.RawSPS 122 // ELSE 123 // Raw AAC frame data 124 type AudioData struct { 125 SoundFormat byte // 4 bits; 音频编码格式 126 SoundRate byte // 2 bits; 音频采样率 127 SoundSize byte // 1 bits; 音频采用大小 128 SoundType byte // 1 bits; 音频通道类型 129 AACPacketType byte // 8 bits; AAC 编码音频的包类型,仅但 SoundFormat 为 AAC 有效 130 Body []byte // 原始音频 131 } 132 133 var _ TagData = &AudioData{} 134 135 // Unmarshal . 136 // Note: Unmarshal not copy the data 137 func (audioData *AudioData) Unmarshal(data []byte) error { 138 if len(data) < 2 { 139 return errors.New("data.length < 2") 140 } 141 142 offset := 0 143 audioData.SoundFormat = data[offset] >> 4 144 audioData.SoundRate = (data[offset] >> 2) & 0x03 145 audioData.SoundSize = (data[offset] >> 1) & 0x01 146 audioData.SoundType = data[offset] & 0x01 147 148 offset++ 149 if audioData.SoundFormat == SoundFormatAAC { 150 audioData.AACPacketType = data[offset] 151 offset++ 152 } 153 audioData.Body = data[offset:] 154 155 return nil 156 } 157 158 // MarshalSize . 159 func (audioData *AudioData) MarshalSize() int { 160 return 2 + len(audioData.Body) 161 } 162 163 // Marshal . 164 func (audioData *AudioData) Marshal() ([]byte, error) { 165 buff := make([]byte, audioData.MarshalSize()) 166 offset := 0 167 buff[offset] = (audioData.SoundFormat << 4) | 168 ((audioData.SoundRate & 0x03) << 2) | 169 ((audioData.SoundSize & 0x01) << 1) | 170 (audioData.SoundType & 0x01) 171 172 offset++ 173 if audioData.SoundFormat == SoundFormatAAC { 174 buff[offset] = audioData.AACPacketType 175 offset++ 176 } 177 178 offset += copy(buff[offset:], audioData.Body) 179 180 return buff[:offset], nil 181 }