现在的位置: 首页 > 综合 > 正文

webrtc工程DEMO建立

2013年04月16日 ⁄ 综合 ⁄ 共 4959字 ⁄ 字号 评论关闭

webrtc的历史比较简单如下:

2010年Google以6820万美元收购VoIP软件开发商Global
IP Solutions
的GIPS引擎[4][5][6][7],并改为名为“WebRTC”。WebRTC
使用GIPS引擎,实现了基于网页的视频会议,并支持722,PCM,ILBC,ISAC等编码,同时使用谷歌自家的VP8视频编解码;同时支持RTP/SRTP传输等。

2012年谷歌已经把这款软件集成到Chrome浏览器中。同时 FreeSWITCH 项目宣称[8]支持
iSAC audio codec

WEBRTC工程吸引人的地方只要一下几方面:

(1)杰出出的音频处理算法,这给许多做语音处理、压缩相关的人员提供许多便利的地方。

(2)完整的音视频解决方案,提供AE/VE完整的实现方案,稍微改变一下就可以应用在视频监控、P2P或者视频会议中,以及实现跨平台性。目前WEBRTC支持WINDOWS/MAX/LINUX/IOS/ANDROID。

(3)WEBRTC已经成为一项标准,将来会在chrome/firefox中使用,可以实现无插件化的音视频用用,这点事一个突破型的应用。


webrtc的工程需要使用GOOGLE自己的一套工具进行下载和配置,生成相应的工程。这个比较简单网上资料比较多,不多做介绍。

webrtc在win平台下默认生成的都是静态库,这里简单的DEMO的代码贴一下:

    // setup video engine
    char cCameraName[MAX_CAMERA_NAME_LENGTH];
    memset(cCameraName, 0 , MAX_CAMERA_NAME_LENGTH);
    int iRet = RET_SUCCESS;
    CaptureCapability stCurSelectCapbility;

    char cCameraID[MAX_CAMERA_ID_LENGTH];
    memset(cCameraID, 0 , MAX_CAMERA_ID_LENGTH);
    int iCapdeviceCount = 0;
    
    iCapdeviceCount = m_VieCapture->NumberOfCaptureDevices();
    ASSERT(iCapdeviceCount > 0);

    for(int i = 0; i < iCapdeviceCount; i++)
    {
        iRet = m_VieCapture->GetCaptureDevice(i, cCameraName, MAX_CAMERA_NAME_LENGTH, cCameraID, MAX_CAMERA_ID_LENGTH);
        ASSERT(iRet == RET_SUCCESS);
        int iCapbilityCount = 0;
        iCapbilityCount = m_VieCapture->NumberOfCapabilities(cCameraID, MAX_CAMERA_ID_LENGTH);
        ASSERT(iCapbilityCount > 0);
        iRet = m_VieCapture->GetCaptureCapability(cCameraID, MAX_CAMERA_ID_LENGTH, iCapbilityCount - 1, stCurSelectCapbility);
        ASSERT(iRet == RET_SUCCESS);
    }
    int iCaptureId;
    iRet = m_VieCapture->AllocateCaptureDevice(cCameraID, MAX_CAMERA_ID_LENGTH, iCaptureId);
    ASSERT(iRet == RET_SUCCESS);

    iRet = ViECreateWindow(m_CapRenderHwnd, 500,200, 500, 500,_T("Local Render"));
    ASSERT(iRet == RET_SUCCESS);
    
    iRet = ViECreateWindow(m_DecRenderHwnd, 500, 700, 500,500, _T("Remote Render"));
    ASSERT(iRet == RET_SUCCESS);
 
    iRet = m_VieRender->AddRenderer(iCaptureId,(void*)m_CapRenderHwnd, 0, 0.0,0.0,1.0,1.0);
    ASSERT(iRet == RET_SUCCESS);
    
    iRet = m_VieCapture->StartCapture(iCaptureId, stCurSelectCapbility);
    ASSERT(iRet == RET_SUCCESS);

    iRet = m_VieRender->StartRender(iCaptureId);

	VideoCodec videoCodec;
	  
	int numOfVieCodecs = m_VieCodec->NumberOfCodecs();  
    bool bFindVideoCode = false;

    ASSERT(numOfVieCodecs > 0);
	for(int i=0; i<numOfVieCodecs;++i)  
	{  
		if(m_VieCodec->GetCodec(i,videoCodec)!=-1)  
		{  
			if(videoCodec.codecType == kVideoCodecVP8)  
            {
                bFindVideoCode = true;
				break;
            }
		}  
	} 
    ASSERT(bFindVideoCode);

    iRet = m_VieBase->CreateChannel(m_ChannelId);
    ASSERT(iRet == RET_SUCCESS);

    iRet = m_VieRender->AddRenderer(m_ChannelId,(void*)m_DecRenderHwnd, 0, 0.0,0.0,1.0,1.0);
    ASSERT(iRet == RET_SUCCESS);
    iRet = m_VieRender->StartRender(m_ChannelId);
    ASSERT(iRet == RET_SUCCESS);

    iRet = m_VieCodec->SetSendCodec(m_ChannelId, videoCodec);
    ASSERT(iRet == RET_SUCCESS);
    iRet = m_VieCodec->SetReceiveCodec(m_ChannelId, videoCodec);
    ASSERT(iRet == RET_SUCCESS);

    iRet = m_VieCapture->ConnectCaptureDevice(iCaptureId, m_ChannelId);
    ASSERT(iRet == RET_SUCCESS);

    iRet = m_VieRTP_RTCP->SetRTCPStatus(m_ChannelId, webrtc::kRtcpCompound_RFC4585);
    ASSERT(iRet == RET_SUCCESS);


    iRet = m_VieRTP_RTCP->SetKeyFrameRequestMethod(m_ChannelId, webrtc::kViEKeyFrameRequestPliRtcp);
    ASSERT(iRet == RET_SUCCESS);

    iRet = m_VieRTP_RTCP->SetTMMBRStatus(m_ChannelId, true);
    ASSERT(iRet == RET_SUCCESS);

    iRet = m_VieNetwork->SetSendDestination(m_ChannelId, "127.0.0.1", 11111, 11112);
    ASSERT(iRet == RET_SUCCESS);
    iRet = m_VieNetwork->SetLocalReceiver(m_ChannelId, 11111, 11112, "127.0.0.1");

    iRet = m_VieBase->StartSend(m_ChannelId);
    ASSERT(iRet == RET_SUCCESS);

    iRet = m_VieBase->StartReceive(m_ChannelId);
    ASSERT(iRet == RET_SUCCESS);


    //setup voice engine
    CodecInst voiceCodec;  

    int numOfVoeCodecs = m_VoeCodec->NumOfCodecs();  
    bool bFindAudioCode = false;
    for(int i=0; i<numOfVoeCodecs;++i)  
    {  
        if(m_VoeCodec->GetCodec(i,voiceCodec)!=-1)  
        {  
            if(strncmp(voiceCodec.plname,"ISAC",4)==0)  
            {
                bFindAudioCode = true;
                break;  
            }
        }  
    }  
    ASSERT(bFindAudioCode);
    // define iSAC codec parameters  
    strcpy(voiceCodec.plname, "ISAC");  
    voiceCodec.plfreq   = 16000;    // iSAC宽带模式  
    voiceCodec.pltype   = 103;      // 默认动态负载类型  
    voiceCodec.pacsize  = 480;      // 480kbps,即使用30ms的packet size  
    voiceCodec.channels     = 1;        // 单声道  
    voiceCodec.rate     = -1;       // 信道自适应模式,单位bps 

    int iMaxAEChannelNum = m_VoeBase->MaxNumOfChannels();
    m_AudioChannel = m_VoeBase->CreateChannel();
    ASSERT((m_AudioChannel < iMaxAEChannelNum) && (m_AudioChannel >= 0));
    
    iRet = m_VoeCodec->SetSendCodec(m_AudioChannel, voiceCodec);
    ASSERT(iRet == RET_SUCCESS);

    iRet = m_VoeRTCP->SetRTCPStatus(m_AudioChannel, true);
    ASSERT(iRet == RET_SUCCESS);
    
    iRet = m_VoeNetwork->SetSourceFilter(m_AudioChannel, 11113, 11114, "127.0.0.1");
    ASSERT(iRet == RET_SUCCESS);
    
    iRet = m_VoeBase->SetSendDestination(m_AudioChannel, 11113, "127.0.0.1", -1, 11114);
    ASSERT(iRet == RET_SUCCESS);

    iRet = m_VoeBase->SetLocalReceiver(m_AudioChannel, 11113, 11114, "127.0.0.1");
    ASSERT(iRet == RET_SUCCESS);

    iRet = m_VoeBase->StartPlayout(m_AudioChannel);
    ASSERT(iRet == RET_SUCCESS);

    iRet = m_VoeBase->StartReceive(m_AudioChannel);
    ASSERT(iRet == RET_SUCCESS);

    iRet = m_VoeBase->StartSend(m_AudioChannel);
    ASSERT(iRet == RET_SUCCESS);

    NsModes mode(kNsDefault);//
    iRet = m_VoeApmPtr->SetRxNsStatus(m_AudioChannel, true, mode);
    ASSERT(iRet == RET_SUCCESS);

    AgcModes agcmode(kAgcDefault);
    iRet = m_VoeApmPtr->SetRxAgcStatus(m_AudioChannel, true, agcmode);
    ASSERT(iRet == RET_SUCCESS);

    iRet = m_VoeApmPtr->SetEcStatus(true, kEcAec);
    ASSERT(iRet == RET_SUCCESS);

抱歉!评论已关闭.