RTMP中的speex音訊流與RTP的對接
帶音視訊互動的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編碼取樣率)。