【Go】FLV文件解析(三)

生命不息,编程不止。本章我们继续解析FLV文件中的音频Tag的内容。

Audio Tag Data

【Go】FLV文件解析(一)中我们讲了FLV Tag的基本结构是Tag Header加Tag Data。显然音频Tag的Tag Data就是音频数据了,其结构如下。

Tag Data的第一个字节被分成了4个部分。前4比特表示音频编码格式,共14种。

编码格式说明
0Linear PCM大端小端由编码平台决定
1ADPCM
2MP3
3Linear PCM小端格式
4Nellymoser 16-kHz mono
5Nellymoser 8-kHz mono
6Nellymoser
7G.711 A-law logarithmic PCM保留,内部使用
8G.711 mu-law logarithmic PCM保留,内部使用
9reserved
10AACFlash Player9,0115,0及以上版本
11SpeexFlash Player10及以上版本
14MP3 8-Khz保留,内部使用
15Device-specific sound保留,内部使用

中间2比特表示采样率,共4种。

类型说明
05.5-kHz
111-kHz
222-kHz
344-kHzAAC总是3

第7比特表示采样位宽,0表示8比特宽度,1表示16比特宽度。只针对非压缩编码格式有效,压缩编码格式总是解码成16bit宽度。

模拟音频信号在转换成数字信号之前要经过采样和量化。采样周期,也可以称为采样间隔,是指每隔多长时间从模拟信号采集一次振幅。采样周期的倒数就是采样频率,体现了数字采样的快慢,或称采样的疏密。这里采样频率和采样周期的关系和频率与周期的关系的一样的。比如44KHz的采样频率就表示每隔 1 44000 \frac{1}{44000} 440001秒采集一次振幅。采集到振幅以后需要量化,也就是用二进制来表示,用多少位二进制来表示振幅就是采样位宽,显然16bit能比8bit表示更大范围的振幅变化。

第8比特表示声道信息,0表示单声道,1表示双声道,也就是立体声。对于Nellymoser编码格式,它总是0,对于AAC格式总是1。

Linear PCM(3)存储的是裸PCM采样点(PCM全称Pulse Code Modulation,翻译过来就是脉冲编码调制,也就是模拟信号经过量化编码后得到的数据,属于非压缩编码,是可以直接播放的)。如果采样宽度是8bit,则采样点是无符号整数,如果采样宽度是16bit,则采样点是小端序有符号整数。如果是立体声,则左右声道数据按左-右-左-右排列。

Linear PCM(0)由于其大端小端取决于编码平台,因此不推荐使用。

Nellymoser有3种格式,Nellymoser 8-kHz和16-kHz会忽略掉上面的采样频率和声道信息,普通的Nellymoser(6)则不会忽略。8kHz和16kHz的采样率其他编码格式也不支持。

如果是AAC编码,音频信息总是设置为1,采样频率总是设置为3,因为Flash Player会忽略这两个值,而是从AAC比特流里解码采样率。

音频数据根据编码格式而不同,对于比较常用的AAC编码,音频数据格式如下。

这里音频配置是一个叫做AudioSpecificConfig的结构,在ISO 14496-3中定义。AudioSpecificConfig共占2个字节,具体结构如下。

audio object type

  • 0: Null
  • 1: AAC Main
  • 2: AAC LC (Low Complexity)
  • 3: AAC SSR (Scalable Sample Rate)
  • 4: AAC LTP (Long Term Prediction)
  • 5: SBR (Spectral Band Replication)
  • 6: AAC Scalable
  • 7: TwinVQ
  • 8: CELP (Code Excited Linear Prediction)
  • 9: HXVC (Harmonic Vector eXcitation Coding)
  • 10: Reserved
  • 11: Reserved
  • 12: TTSI (Text-To-Speech Interface)
  • 13: Main Synthesis
  • 14: Wavetable Synthesis
  • 15: General MIDI
  • 16: Algorithmic Synthesis and Audio Effects
  • 17: ER (Error Resilient) AAC LC
  • 18: Reserved
  • 19: ER AAC LTP
  • 20: ER AAC Scalable
  • 21: ER TwinVQ
  • 22: ER BSAC (Bit-Sliced Arithmetic Coding)
  • 23: ER AAC LD (Low Delay)
  • 24: ER CELP
  • 25: ER HVXC
  • 26: ER HILN (Harmonic and Individual Lines plus Noise)
  • 27: ER Parametric
  • 28: SSC (SinuSoidal Coding)
  • 29: PS (Parametric Stereo)
  • 30: MPEG Surround
  • 31: (Escape value)
  • 32: Layer-1
  • 33: Layer-2
  • 34: Layer-3
  • 35: DST (Direct Stream Transfer)
  • 36: ALS (Audio Lossless)
  • 37: SLS (Scalable LosslesS)
  • 38: SLS non-core
  • 39: ER AAC ELD (Enhanced Low Delay)
  • 40: SMR (Symbolic Music Representation) Simple
  • 41: SMR Main
  • 42: USAC (Unified Speech and Audio Coding) (no SBR)
  • 43: SAOC (Spatial Audio Object Coding)
  • 44: LD MPEG Surround
  • 45: USAC

sampling frenquence index

  • 0: 96000 Hz
  • 1: 88200 Hz
  • 2: 64000 Hz
  • 3: 48000 Hz
  • 4: 44100 Hz
  • 5: 32000 Hz
  • 6: 24000 Hz
  • 7: 22050 Hz
  • 8: 16000 Hz
  • 9: 12000 Hz
  • 10: 11025 Hz
  • 11: 8000 Hz
  • 12: 7350 Hz
  • 13: Reserved
  • 14: Reserved
  • 15: frequency is written explictly

channel configration

  • 0: Defined in AOT Specifc Config
  • 1: 1 channel: front-center
  • 2: 2 channels: front-left, front-right
  • 3: 3 channels: front-center, front-left, front-right
  • 4: 4 channels: front-center, front-left, front-right, back-center
  • 5: 5 channels: front-center, front-left, front-right, back-left, back-right
  • 6: 6 channels: front-center, front-left, front-right, back-left, back-right, LFE-channel
  • 7: 8 channels: front-center, front-left, front-right, side-left, side-right, back-left, back-right, LFE-channel
  • 8-15: Reserved

实战

第一步还是定义下需要用到的结构,这里我们只以AAC为例。

type FlvAudioTag struct {
	Header    FlvTagHeader
	SoundFmat uint8
	SoundRate uint8
	SoundSize uint8
	SoundType uint8
	Data      stream.Stream
}

type AACPacket struct {
	AACPacketType uint8
	Playload      []byte
}

type AACAudioSpecificConfig struct {
	AudioObjectType      uint8
	SamplingFrequency    uint8
	ChannelConfiguration uint8
	FrameLengthFlag      uint8
	DependsOnCoreCoder   uint8
	ExtensionFlag        uint8
}

音频Tag解码过程如下。

// 解码音频Tag
func DecodeFlvAudioTag(tag FlvTag) (a FlvAudioTag, err error) {
	a.Header = tag.Header
	var b byte
	if err = tag.Data.Byte(&b).Error(); err != nil {
		return
	}
	a.SoundFmat = b >> 4
	a.SoundRate = b >> 2 & 0x03
	a.SoundSize = b >> 1 & 0x01
	a.SoundType = b & 0x01
	a.Data, err = tag.Data.Produce(tag.Data.Remain())
	return
}

AudioSpecificConfig解码过程如下。

// 解码AAC Packet
func DecodeAACPacket(t FlvAudioTag) (p AACPacket, err error) {
	if t.SoundFmat != AAC {
		err = errors.New("not aac format")
		return
	}
	if err = t.Data.U8(&p.AACPacketType).Error(); err != nil {
		return
	}
	p.Playload = t.Data.ReadAll()
	return
}

// 解码AudioSpecificConfig
func DecodeAACAudioSpecificConfig(p AACPacket) (a AACAudioSpecificConfig, err error) {
	if len(p.Playload) != 2 {
		err = FLV_FMT_ERROR
	}
	a.AudioObjectType = p.Playload[0] >> 3
	a.SamplingFrequency = (p.Playload[0] << 1 & 0x0F) | (p.Playload[1] >> 7)
	a.ChannelConfiguration = p.Playload[1] >> 3 & 0x0F
	a.FrameLengthFlag = p.Playload[1] >> 2 & 0x01
	a.DependsOnCoreCoder = p.Playload[1] >> 1 & 0x01
	a.ExtensionFlag = p.Playload[1] & 0x01
	return
}

AAC是一种压缩编码,关于AAC的解码,有机会我会出专门的一期来讲。
下一期也是最后一期,我们继续视频Tag的解析。

附录:

MPEG-4 Audio

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值