metaRTC p2p自建信令系统

 metaRTC实现了sfu 和 p2p两种模式,支持srs和zlm 两种推送已经p2p server 模式,如果要实现自己的信令系统其实也比较简单, 最近实现了metaRTC的基于mqtt的信令,同时可以进行p2p和服务器转发,方便自己的设备和系统融合,现就信令系统的流程以及涉及的函数进行一个梳理:如下,按此流程可以实现自己的信令系统(信令|为好奇者提供的WebRTC (webrtcforthecurious.com))

metaRTC p2p自建信令系统_第1张图片

 

metaRTC 修改信令的涉及到的地方
IPC应用
1、yangipc/YangIpc.c 
创建IPC
这里可以设置自定义的ice server 信息

strcpy(session->avinfo.rtc.iceServerIP,"182.92.163.143");
并通过yang_ipc_listen 函数实现开始sdp 交互 
void yang_create_ipc(YangIpc* ipc){

	if(ipc==NULL) return;

	YangIpcSession* session=&ipc->session;
	YangIni ini;
	yang_create_ini(&ini,(char*)"yang_config.ini");
	ini.initAvinfo(ini.filename,&session->avinfo);
	yang_destroy_ini(&ini);

	session->avinfo.video.videoEncoderFormat=YangI420;

	session->avinfo.enc.createMeta=0;

	yang_ipc_initAvinfo(session);

	yang_setLogLevel(session->avinfo.sys.logLevel);
	yang_setLogFile(session->avinfo.sys.hasLogFile);

	session->avinfo.sys.httpPort=1988;
	session->avinfo.sys.mediaServer=Yang_Server_P2p;//Yang_Server_Srs/Yang_Server_Zlm/Yang_Server_P2p
	session->avinfo.sys.rtcLocalPort=10000+yang_random()%15000;
	memset(session->avinfo.sys.localIp,0,sizeof(session->avinfo.sys.localIp));
	yang_getLocalInfo(session->avinfo.sys.localIp);
	session->hasAudio=yangtrue;

	//using h264 h265
	session->avinfo.video.videoEncoderType=Yang_VED_264;//Yang_VED_265;


	// session->streams.m_streamState=this;
	session->avinfo.audio.hasAec=1;

	//session->channeldataRecv.context=this;
	//session->channeldataRecv.receiveData=g_ipc_receiveData;

	session->avinfo.rtc.usingDatachannel=1;

	strcpy(session->avinfo.rtc.iceServerIP,"182.92.163.143");
	session->avinfo.rtc.iceStunPort=3478;
	session->avinfo.rtc.hasIceServer=0;

	session->videoBuffer = (YangVideoEncoderBuffer2*)calloc(sizeof(YangVideoEncoderBuffer2),1);//new YangVideoEncoderBuffer(2);
	yang_create_videoEncoderBuffer2(session->videoBuffer,2);


	yang_ipc_initRtc(session);

	ipc->start=yang_ipc_listen;
	ipc->init=yang_ipc_init;
	ipc->checkAlive=yang_ipc_checkAlive;


}
2、yangipc/YangIpc.c
此函数 实现信令交互开始流程,通过yang_start_p2pserver实现信令监听线程,如果有连接后就是实现http协议的offer获取
并在g_ipc_receive函数里面处理remotesdp (offer),可以改成自己的信令处理,获取到offer ,直接调用g_ipc_receive函数,不用原来提供的p2pserver
void yang_ipc_listen(YangIpcSession* session){

	yang_create_p2pserver(&session->p2pServer,session->avinfo.sys.httpPort);
	session->p2pServer.receive=g_ipc_receive;
	session->p2pServer.user=session;
	yang_start_p2pserver(&session->p2pServer);

}
void g_ipc_receive(char *data, int32_t nb_data,char* response,char* remoteIp, void *user) {
	if (user == NULL)	return;
	YangIpcSession *session = (YangIpcSession*) user;
	yang_ipc_startRtc(session,remoteIp, data,response);
}
3、yangipc/YangIpcRtc.c
此函数接收远端remotesdp (offer) ,然后回传本地sdp localsdp (answer)原来采用的是http的模式实现的,函数回调指针实现函数重载
此函数如果需要实现自己的信令系统需要替换掉answer 回传的相关函数	ret = sh->createHttpAnswer(&sh->peer,answer);
int32_t yang_ipc_rtcrecv_addPeer(YangIpcRtcSession* session,char* sdp,char* answer,char* remoteIp,int32_t localPort,int* phasplay)

int32_t yang_ipc_rtcrecv_addPeer(YangIpcRtcSession* session,char* sdp,char* answer,char* remoteIp,int32_t localPort,int* phasplay){
	int32_t ret = 0;
	YangPeerConnection* sh=(YangPeerConnection*)calloc(sizeof(YangPeerConnection),1);
	memset(&sh->peer.streamconfig,0,sizeof(sh->peer.streamconfig));
	sh->peer.streamconfig.uid=session->uidSeq++;
	sh->peer.streamconfig.localPort=localPort;
	sh->peer.streamconfig.isServer=1;
	sh->peer.streamconfig.streamOptType=Yang_Stream_Both;
	strcpy(sh->peer.streamconfig.remoteIp,remoteIp);

	sh->peer.streamconfig.sslCallback.context=session;
	sh->peer.streamconfig.sslCallback.sslAlert=g_ipc_rtcrecv_sslAlert;
	sh->peer.streamconfig.recvCallback.context=session;
	sh->peer.streamconfig.recvCallback.receiveAudio=g_ipc_rtcrecv_receiveAudio;
	sh->peer.streamconfig.recvCallback.receiveVideo=g_ipc_rtcrecv_receiveVideo;
	sh->peer.streamconfig.recvCallback.receiveMsg=g_ipc_rtcrecv_receiveMsg;
	memcpy(&sh->peer.streamconfig.rtcCallback,&session->rtcCallback,sizeof(YangRtcCallback));
	sh->peer.avinfo=session->avinfo;
	yang_create_peerConnection(sh);

	sh->init(&sh->peer);
	if (sh->isConnected(&sh->peer))		return Yang_Ok;
	if(session->avinfo->rtc.hasIceServer) sh->requestStunServer(&sh->peer);
	ret = sh->setRemoteDescription(&sh->peer,sdp);

	if (ret)		return ret;
	//取得answer传回对端
	ret = sh->createHttpAnswer(&sh->peer,answer);

	session->pushs.insert(&session->pushs.vec,sh);
	if(sh->peer.streamconfig.streamOptType==Yang_Stream_Both||sh->peer.streamconfig.streamOptType==Yang_Stream_Play){
		//m_playCount++;
		//yang_post_message(YangM_P2p_Play_Start,0,NULL);

	}
	//	if(m_context) m_context->streams.connectNotify(sh->peer.streamconfig.uid,sh->peer.streamconfig.streamOptType, true);
	if(session->pushs.vec.vsize==1){
		//yang_reindex(session->in_audioBuffer);
		yang_reindex2(session->in_videoBuffer);
	}
	//if(m_p2pRtcI) m_p2pRtcI->sendKeyframe();
	*phasplay=sh->peer.streamconfig.streamOptType==Yang_Stream_Both?1:0;

	return Yang_Ok;
}

metaRTC p2p自建信令系统_第2张图片 

 

 基于服务器转发的flutter 跨平台应用,

					
                   采用 go pion库实现webrtc rtp数据包的转发
                    n, _, readErr := track.Read(b)
    					if readErr != nil {
						log.Debug(readErr)
						pps.bVideoStop = true
						continue
						//break
					}
					stream.SendStreamVideo(b[:n])

metaRTC p2p自建信令系统_第3张图片

网页从服务器拉流

metaRTC p2p自建信令系统_第4张图片

metaRTC p2p自建信令系统_第5张图片

 

 

 

 

你可能感兴趣的:(笔记,metaRTC,p2p,网络协议,网络)