带音视频交互的flash项目中,音频编码只能选择speex格式。
这篇文章分为三部分。分别为flex中提供的音频接口、RTMP中的speex数据、如何转换为RTP流。
一、flex中提供的音频接口
用flex编写客户端,它提供的接口是封装过的,与speex标准编解码器之间的调用实际上相当于一个黑盒,它们之间的差异需要我们分析。
麦克风音频的接口由类Mircophone提供,大多都有中文注释,我就不一一赘述了,只挑出其中一些做自己的讲解。
codec | 编码格式,只支持Nellymoser、speex两种格式, Nellymoser多用于游戏开发,而且商业使用限制较多 |
rate | 设置采样频率,注意是麦克风采样率,而非编码采样率 |
framesPerPacket | 一个音频包中包含的音频帧数量(后文会有更详细的说明) |
encodeQuality | 编码质量,在同等编码采样率下,质量越高,效果越好, 但每帧所包含的数据越多。当该值也确定下来时, 每帧数据的字节大小也就确定了 |
enableVAD | 是否开启Voice Activation Detection。它的作用自己google。 当开启时,静音状态下speex编码器将持续编码10字节大小的音频帧 |
speex编码有三种模式
模式 | 编码采样率 | 一帧数据 所表示的时间 |
编码一帧需要的 sample数量 |
narrow band(窄带) | 8khz | 20ms | 160 |
wide band(宽带) | 16khz | 20ms | 320 |
ultra-wide band(超宽带) | 32khz | 20ms | 640 |
二、RTMP中的speex数据
每个音频包(相当于FLV中的audiotag)中,第一个字节的前四位表示编码格式,等于11说明为speex编码。后4个字节分别表示编码采样率、单声道or立体声、每个sample大小8位or16位。但采用speex编码时,它们是固定不变的,协议中的为无效数据。编码采样率恒为16khz,单声道,16bit/sample。
剩余的数据为音频帧数据,可以为多帧的集合,取决于前文提到过的framesPerPacket。在flex中的默认值为2,故每个音频包中有两帧数据。注意,当前文所说的VAD功能开启时,两帧数据可以是两帧实际数据,也可以是两帧10字节数据,还可以各占一帧。
三、如何转换为RTP流
完成上面两步,这部分的工作就不难了。将音频帧数据打上RTP头就行了。具体参加rfc5574(rtp_payload_format_for_the_speex_codec)。
唯一值得注意的一点是,在RTMP协议中,音频数据的间隔是用时间做单位的,而RTP中的时间戳(timestamp),是sample数量。故当RTMP中两包音频包相差20MS时,RTP的时间戳就应该加上320(加320是因为恒采用16khz编码采样率)。