? ? ? ? 一直想學(xué)習(xí)實(shí)時(shí)視頻聊天的技術(shù),雖然到現(xiàn)在也沒有完全搞明白各種編碼格式酥诽,但搞清楚怎怎么編解碼H264視頻鞍泉,怎么編解碼AAC格式音頻就夠了,就能實(shí)現(xiàn)一個(gè)最基本的視頻聊天/會(huì)議系統(tǒng)肮帐。什么RTMP,HLS統(tǒng)統(tǒng)可以不管他咖驮,不過,不管的前提是你得自己封裝視音頻流训枢。由于固執(zhí)的認(rèn)為只有本地化編解碼才是效率最高的托修,所以沒有打算使用ffmpeg來(lái)編解碼,雖然ffmpeg在iOS上已經(jīng)使用硬編碼了恒界。當(dāng)然睦刃,如果在windows上開發(fā),ffmpeg會(huì)簡(jiǎn)單一些十酣,也可以使用x264和AAC的獨(dú)立庫(kù)涩拙。視音頻流準(zhǔn)確說(shuō)說(shuō)應(yīng)該是視音頻幀,中間是分割好的一段段數(shù)據(jù)耸采。
? ? ? ? 從相機(jī)采集視頻幀->調(diào)整單幀相片編碼格式->編碼成H264視頻幀->發(fā)送到服務(wù)器->服務(wù)器轉(zhuǎn)發(fā)到對(duì)端->對(duì)端接收數(shù)據(jù)->解碼并顯示
? ? ? ? 從麥克風(fēng)采集音頻->編碼成AAC->發(fā)送到服務(wù)器->服務(wù)器轉(zhuǎn)發(fā)到對(duì)端->對(duì)端接收數(shù)據(jù)->解碼并播放
????????從相機(jī)采集視頻:具體代碼不貼了兴泥,到處都是。
????????調(diào)整單幀相片編碼格式?:有些Android相機(jī)輸出的照片格式是YV12格式虾宇,而MediaCodec需要的是NV12格式搓彻,所以需要轉(zhuǎn)換,轉(zhuǎn)換代碼如下:
public byte[] YV12toYUV420PackedSemiPlanar(final byte[] input, final? byte[] output, final int width, final int height) {
? ? finalint frameSize = width * height;
? ? finalint qFrameSize = frameSize / 4;
? ? System.arraycopy(input, 0, output, 0, frameSize);// Y? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
? ? for (int i = 0; i < qFrameSize; i++) {
? ? ? ? output[alignedFrameSize + i * 2] = input[frameSize + i + qFrameSize];// Cb (U)? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
? ? ? ? output[alignedFrameSize + i * 2 + 1] = input[frameSize + i];// Cr (V)? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
? ? }
? ? return output;
}
這個(gè)地方注意嘱朽,真正用在產(chǎn)品里需要使用openGLES來(lái)轉(zhuǎn)碼旭贬,CPU轉(zhuǎn)碼效率太低。
? ? ? ? 編碼成H264視頻幀:Android編碼使用MediaCodec搪泳,iOS編碼使用VideoToolBox稀轨。具體代碼參考度娘。
????????發(fā)送到服務(wù)器:傳輸協(xié)議使用自定義協(xié)議森书,為了代碼通用性靶端,使用標(biāo)準(zhǔn)TCP socket C實(shí)現(xiàn)底層通信框架谎势,兼容Windows,Linux杨名,Android脏榆,iOS。
? ? ? ? 服務(wù)器轉(zhuǎn)發(fā)到對(duì)端:服務(wù)器是在Linux C socket實(shí)現(xiàn)台谍,理論上只要CPU须喂,內(nèi)存,網(wǎng)絡(luò)帶寬足夠趁蕊,可并發(fā)千萬(wàn)用戶同時(shí)在線坞生。
????????對(duì)端接收數(shù)據(jù):接收數(shù)據(jù)也是使用標(biāo)準(zhǔn)TCP socket C實(shí)現(xiàn)。
? ??????解碼并顯示:Android解碼使用MediaCodec掷伙,iOS解碼使用VideoToolBox是己。具體代碼參考度娘。
? ? ? ? 音頻采集傳輸和視頻一樣任柜。