WebRTC主要用来让浏览器实时获取和交换视频、音频和数据。浏览器本身不支持相互之间直接建立信道进行通信,都是通过服务器进行中转,A、B两个客户端之间信令还是要通过服务器传送,但这并不适合数据流的传输,WebRTC应运而生。
WebRTC是一个开源项目,旨在建立一个浏览器与浏览器之间的信道,这个信道开源发送任何数据,而不需要经过服务器,这里说不的不需要服务器并不是真的不需要服务器了,还是需要服务器来传送信令,只是音视频数据不需要服务器进行中转传输了。
WebRTC很大,里面包含太多东西,其中的iLBC音频编解码库很好,我想抽取出来编译成静态库在iOS平台上调用,于是,
1、抽取了ilbc文件夹加入新建的Xcode静态库编译工程;
2、除了ilbc文件夹里的文件,ilbc还依赖common_audio文件夹里的signal_processing文件夹中的文件;
3、试着编译,发现错误,加入缺少的头文件
4、错误还是有,很多方法找不到之类的,我得解决方法找不到的让其找到就行了,然后编译成功。
编译好了后得到静态库libcodecOfiLBC.a然后就是怎么用这个库了,用这个库时需要WebRTC里的头文件ilbc.h及typedefs.h,然后封装个类来调用libcodecOfiLBC.a,建个头文件CIlbcCodec.h:
// // CIlbcCodec.h // CIlbcCodec // // Created by hkshen on 15/5/25. // Copyright (c) 2015年 hkshen. All rights reserved. // #ifndef __CIlbcCodec__CIlbcCodec__ #define __CIlbcCodec__CIlbcCodec__ #include <stdio.h> class CIlbcCodec { public: unsigned char m_pDupData[960]; unsigned int m_nDupLen; public: CIlbcCodec(); virtual ~CIlbcCodec(); /** * Stop encode */ void reset_encoder_impl(); /** * Stop decode */ void reset_decoder_impl(); int cellcom_audio_ilbc_Codec_resetEncoder(); int cellcom_audio_ilbc_Codec_resetDecoder(); /** * WebRTC ilbc encode */ int cellcom_audio_ilbc_Codec_encode(unsigned char* pByteIn, unsigned int nRawLen, unsigned char* pByteOut); /** * WebRTC ilbc decode */ int cellcom_audio_ilbc_Codec_decode(unsigned char* pByteIn, unsigned int srcLen, unsigned char* pByteOut); }; #endif /* defined(__CIlbcCodec__CIlbcCodec__) */ CIlbcCodec.cpp: // // CIlbcCodec.cpp // CIlbcCodec // // Created by hkshen on 15/5/25. // Copyright (c) 2015年 hkshen. All rights reserved. // #include "CIlbcCodec.h" #include <math.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include "ilbc.h" //#include "defines.h" static iLBC_encinst_t *Enc_Inst = NULL; static iLBC_decinst_t *Dec_Inst = NULL; const short MODE = 30; //30ms const short FRAME_SAMPLES = 240; //MODE << 3;//240 const short FRAME_SIZE = 480; //FRAME_SAMPLES * sizeof(short);//480 const short NO_OF_BYTES_30MS = 50; static int encoding, decoding, encoderReset, decoderReset; // // CIlbcCodec Implementation // CIlbcCodec::CIlbcCodec() { memset(m_pDupData, 0 ,960); m_nDupLen = 0; } CIlbcCodec::~CIlbcCodec() { } void CIlbcCodec::reset_encoder_impl() { if (!encoding) { WebRtcIlbcfix_EncoderFree(Enc_Inst); Enc_Inst = NULL; encoderReset = 0; } else { encoderReset = 1; } } int CIlbcCodec::cellcom_audio_ilbc_Codec_resetEncoder() { reset_encoder_impl(); return 1; } int CIlbcCodec::cellcom_audio_ilbc_Codec_encode(unsigned char *pByteIn, unsigned int nRawLen, unsigned char *pByteOut) { int bytes_remaining = 0; int bytes_encoded = 0; int bytes = 0; int encoded_len = 0; encoding = 1; if (Enc_Inst == NULL) { WebRtcIlbcfix_EncoderCreate(&Enc_Inst); WebRtcIlbcfix_EncoderInit(Enc_Inst, MODE); } //wait //pByteIn += nRawLen; bytes_remaining = nRawLen; int truncated = bytes_remaining % FRAME_SIZE; if (truncated) { bytes_remaining -= truncated; printf("Ignoring last %d bytes, input must be divisible by %d", truncated, FRAME_SIZE); } while (bytes_remaining > 0) { //ilbc编码 bytes = WebRtcIlbcfix_Encode(Enc_Inst, (short *)pByteIn, FRAME_SAMPLES, (int16_t *)pByteOut); pByteIn += FRAME_SIZE; bytes_encoded += FRAME_SIZE; bytes_remaining -= FRAME_SIZE; pByteOut += bytes; encoded_len += bytes; if (bytes == -1) { printf("encode failed\n"); } } pByteIn -= bytes_encoded; pByteOut -= encoded_len; encoding = 0; if (encoderReset) { reset_encoder_impl(); } return encoded_len; } void CIlbcCodec::reset_decoder_impl() { if (!decoding) { WebRtcIlbcfix_DecoderFree(Dec_Inst); Dec_Inst = NULL; decoderReset = 0; } else { decoderReset = 1; } } int CIlbcCodec::cellcom_audio_ilbc_Codec_resetDecoder() { reset_encoder_impl(); return 1; } int CIlbcCodec::cellcom_audio_ilbc_Codec_decode(unsigned char *pByteIn, unsigned int srcLen, unsigned char *pByteOut) { int bytes_remaining = 0; int bytes_decoded = 0; int num_samples = 0; short speechType = 0; int decode_len = 0; decoding = 1; if (Dec_Inst == NULL) { WebRtcIlbcfix_DecoderCreate(&Dec_Inst); WebRtcIlbcfix_DecoderInit(Dec_Inst, MODE); } //wait //pByteIn += Len; bytes_remaining = srcLen; while (bytes_remaining > 0) { //ilbc解码 num_samples = WebRtcIlbcfix_Decode(Dec_Inst, (short *)pByteIn, NO_OF_BYTES_30MS, (short *)pByteOut, &speechType); m_nDupLen = 50; memcpy(m_pDupData, pByteIn, m_nDupLen); pByteIn += NO_OF_BYTES_30MS; bytes_remaining -= NO_OF_BYTES_30MS; bytes_decoded += NO_OF_BYTES_30MS; pByteOut += num_samples * sizeof(short); decode_len += num_samples * sizeof(short); } pByteIn -= bytes_decoded; pByteOut -= srcLen; decoding = 0; if (decoderReset) { reset_decoder_impl(); } return decode_len; }单独编译WebRTC的ilbc工程: 点击打开链接
