• metaRTC p2p自建信令系统


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

    76568a7bdf9d48478357987f2d3a28de.png

     

    1. metaRTC 修改信令的涉及到的地方
    2. IPC应用
    3. 1、yangipc/YangIpc.c
    4. 创建IPC
    5. 这里可以设置自定义的ice server 信息
    6. strcpy(session->avinfo.rtc.iceServerIP,"182.92.163.143");
    7. 并通过yang_ipc_listen 函数实现开始sdp 交互
    8. void yang_create_ipc(YangIpc* ipc){
    9. if(ipc==NULL) return;
    10. YangIpcSession* session=&ipc->session;
    11. YangIni ini;
    12. yang_create_ini(&ini,(char*)"yang_config.ini");
    13. ini.initAvinfo(ini.filename,&session->avinfo);
    14. yang_destroy_ini(&ini);
    15. session->avinfo.video.videoEncoderFormat=YangI420;
    16. session->avinfo.enc.createMeta=0;
    17. yang_ipc_initAvinfo(session);
    18. yang_setLogLevel(session->avinfo.sys.logLevel);
    19. yang_setLogFile(session->avinfo.sys.hasLogFile);
    20. session->avinfo.sys.httpPort=1988;
    21. session->avinfo.sys.mediaServer=Yang_Server_P2p;//Yang_Server_Srs/Yang_Server_Zlm/Yang_Server_P2p
    22. session->avinfo.sys.rtcLocalPort=10000+yang_random()%15000;
    23. memset(session->avinfo.sys.localIp,0,sizeof(session->avinfo.sys.localIp));
    24. yang_getLocalInfo(session->avinfo.sys.localIp);
    25. session->hasAudio=yangtrue;
    26. //using h264 h265
    27. session->avinfo.video.videoEncoderType=Yang_VED_264;//Yang_VED_265;
    28. // session->streams.m_streamState=this;
    29. session->avinfo.audio.hasAec=1;
    30. //session->channeldataRecv.context=this;
    31. //session->channeldataRecv.receiveData=g_ipc_receiveData;
    32. session->avinfo.rtc.usingDatachannel=1;
    33. strcpy(session->avinfo.rtc.iceServerIP,"182.92.163.143");
    34. session->avinfo.rtc.iceStunPort=3478;
    35. session->avinfo.rtc.hasIceServer=0;
    36. session->videoBuffer = (YangVideoEncoderBuffer2*)calloc(sizeof(YangVideoEncoderBuffer2),1);//new YangVideoEncoderBuffer(2);
    37. yang_create_videoEncoderBuffer2(session->videoBuffer,2);
    38. yang_ipc_initRtc(session);
    39. ipc->start=yang_ipc_listen;
    40. ipc->init=yang_ipc_init;
    41. ipc->checkAlive=yang_ipc_checkAlive;
    42. }
    43. 2、yangipc/YangIpc.c
    44. 此函数 实现信令交互开始流程,通过yang_start_p2pserver实现信令监听线程,如果有连接后就是实现http协议的offer获取
    45. 并在g_ipc_receive函数里面处理remotesdp (offer),可以改成自己的信令处理,获取到offer ,直接调用g_ipc_receive函数,不用原来提供的p2pserver
    46. void yang_ipc_listen(YangIpcSession* session){
    47. yang_create_p2pserver(&session->p2pServer,session->avinfo.sys.httpPort);
    48. session->p2pServer.receive=g_ipc_receive;
    49. session->p2pServer.user=session;
    50. yang_start_p2pserver(&session->p2pServer);
    51. }
    52. void g_ipc_receive(char *data, int32_t nb_data,char* response,char* remoteIp, void *user) {
    53. if (user == NULL) return;
    54. YangIpcSession *session = (YangIpcSession*) user;
    55. yang_ipc_startRtc(session,remoteIp, data,response);
    56. }
    57. 3、yangipc/YangIpcRtc.c
    58. 此函数接收远端remotesdp (offer) ,然后回传本地sdp localsdp (answer)原来采用的是http的模式实现的,函数回调指针实现函数重载
    59. 此函数如果需要实现自己的信令系统需要替换掉answer 回传的相关函数 ret = sh->createHttpAnswer(&sh->peer,answer);
    60. int32_t yang_ipc_rtcrecv_addPeer(YangIpcRtcSession* session,char* sdp,char* answer,char* remoteIp,int32_t localPort,int* phasplay)
    61. int32_t yang_ipc_rtcrecv_addPeer(YangIpcRtcSession* session,char* sdp,char* answer,char* remoteIp,int32_t localPort,int* phasplay){
    62. int32_t ret = 0;
    63. YangPeerConnection* sh=(YangPeerConnection*)calloc(sizeof(YangPeerConnection),1);
    64. memset(&sh->peer.streamconfig,0,sizeof(sh->peer.streamconfig));
    65. sh->peer.streamconfig.uid=session->uidSeq++;
    66. sh->peer.streamconfig.localPort=localPort;
    67. sh->peer.streamconfig.isServer=1;
    68. sh->peer.streamconfig.streamOptType=Yang_Stream_Both;
    69. strcpy(sh->peer.streamconfig.remoteIp,remoteIp);
    70. sh->peer.streamconfig.sslCallback.context=session;
    71. sh->peer.streamconfig.sslCallback.sslAlert=g_ipc_rtcrecv_sslAlert;
    72. sh->peer.streamconfig.recvCallback.context=session;
    73. sh->peer.streamconfig.recvCallback.receiveAudio=g_ipc_rtcrecv_receiveAudio;
    74. sh->peer.streamconfig.recvCallback.receiveVideo=g_ipc_rtcrecv_receiveVideo;
    75. sh->peer.streamconfig.recvCallback.receiveMsg=g_ipc_rtcrecv_receiveMsg;
    76. memcpy(&sh->peer.streamconfig.rtcCallback,&session->rtcCallback,sizeof(YangRtcCallback));
    77. sh->peer.avinfo=session->avinfo;
    78. yang_create_peerConnection(sh);
    79. sh->init(&sh->peer);
    80. if (sh->isConnected(&sh->peer)) return Yang_Ok;
    81. if(session->avinfo->rtc.hasIceServer) sh->requestStunServer(&sh->peer);
    82. ret = sh->setRemoteDescription(&sh->peer,sdp);
    83. if (ret) return ret;
    84. //取得answer传回对端
    85. ret = sh->createHttpAnswer(&sh->peer,answer);
    86. session->pushs.insert(&session->pushs.vec,sh);
    87. if(sh->peer.streamconfig.streamOptType==Yang_Stream_Both||sh->peer.streamconfig.streamOptType==Yang_Stream_Play){
    88. //m_playCount++;
    89. //yang_post_message(YangM_P2p_Play_Start,0,NULL);
    90. }
    91. // if(m_context) m_context->streams.connectNotify(sh->peer.streamconfig.uid,sh->peer.streamconfig.streamOptType, true);
    92. if(session->pushs.vec.vsize==1){
    93. //yang_reindex(session->in_audioBuffer);
    94. yang_reindex2(session->in_videoBuffer);
    95. }
    96. //if(m_p2pRtcI) m_p2pRtcI->sendKeyframe();
    97. *phasplay=sh->peer.streamconfig.streamOptType==Yang_Stream_Both?1:0;
    98. return Yang_Ok;
    99. }

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

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

    12246ad9aa214f46a89793118d581916.png

    网页从服务器拉流

    d91d3f4d6a7b42b3b329fb389298e29a.png

     

     

     

  • 相关阅读:
    RabbitMQ--Docker安装Rabbit单机与集群
    python之模拟登录与表单交互
    【Pycharm 安装Django报错显示:ERROR: Failed building wheel for backports.zoneinfo】
    数据结构C语言之线性表
    Python编程语言学习笔记
    Python基础入门系列详解20篇
    代码随想录算法训练营第四天|24、19、面试题 02.07、142、92(寄了)
    4.5 使用Go Modules自定义模块
    平时学习得到的
    Python open with as---文件处理
  • 原文地址:https://blog.csdn.net/superxxd/article/details/126085545