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

- 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;
- }
基于服务器转发的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])

网页从服务器拉流
