最近智能硬件(IPC摄像机、智能门铃、智能猫眼、宠物机器人、陪护机器人、带屏可视音箱、带屏台灯等等)与微信/小程序视频通话的功能火起来了,视乎传统硬件终于开始走出了向WebRTC突破的一步,相信未来WebRTC在C端硬件上,将会独领一档存在。
之前我们也描述过,微信或者小程序与智能硬件的通话主要的优势就是利用了微信在手机中的霸主地位,无论是App的安装普及程度,还是实时推送的到达率,都是top级别的,用户只需要做好硬件侧和应用侧的开发,无需过多关注底层推送接口的事情。
实际,微信小程序与智能硬件之间的VoIP,而且是p2p的VoIP,可以说有且只有一条路,那就是WebRTC,微信以及小程序实际内核就是H5或者说Chromium,要支持视频通话,而且是p2p的视频通话,必须满足WebRTC的协议要求,要么还有一种方案,那就是WASM,不过不大可能,因为WASM在兼容性以及效率上,完全跟WebRTC没法比,所以,做好WebRTC就能实现智能硬件与微信小程序的p2p视频通话VoIP应用。
之前我们也说过这其中的难点,最大的技术难点不是在微信小程序这一端,因为这一端的视频通话技术已经很常见了,而且是在小程序的框框里面开发,没什么门槛;最大的技术难点是在智能硬件端:
这一块目前国内做的厂家并不多,做的好的就更少了,EasyRTC是其中的一个,我们可以看看EasyRTC的接口封装:
RTC_C_EXPORT STATUS EasyRTC_initWebRtc(VOID);
RTC_C_EXPORT STATUS EasyRTC_deinitWebRtc(VOID);
RTC_C_EXPORT STATUS EasyRTC_createRtcCertificate(PRtcCertificate *ppRtcCertificate);
RTC_C_EXPORT STATUS EasyRTC_freeRtcCertificate(PRtcCertificate pRtcCertificate);
RTC_C_EXPORT int EasyRTC_startSignalingClient(SIGNALINGCLIENT_MESSAGERECEIVED_CALLBACK SignalingClientMessageReceivedCallback, SIGNALINGCLIENT_STATECHANGED_CALLBACK SignalingClientStateChangedCallback, uint64_t customData);
RTC_C_EXPORT int EasyRTC_loginUser(char *myid, char *mysn, char *mykey, char *extradata0, int extradatalen0, char *extradata1, int extradatalen1);
RTC_C_EXPORT int EasyRTC_connectUser(char *hisid, char *hiskey, char *extradata0, int extradatalen0, char *extradata1, int extradatalen1);
RTC_C_EXPORT int EasyRTC_stopSignalingClient();
RTC_C_EXPORT int EasyRTC_startPrivSignalingServer(int myport, char *myid, char *mykey, char *extradata0, int extradatalen0, PRIVSIGNALINGSERVER_MESSAGERECEIVED_CALLBACK PrivSignalingServerMessageReceivedCallback, uint64_t customData);
RTC_C_EXPORT int EasyRTC_stopPrivSignalingServer();
RTC_C_EXPORT PRIVSIGNALINGCLIENT_HANDLE EasyRTC_connectPrivSignalingServer(char *hisip, int hisport, PRIVSIGNALINGCLIENT_MESSAGERECEIVED_CALLBACK SignalingClientMessageReceivedCallback, uint64_t customData);
RTC_C_EXPORT int EasyRTC_isConnectedPrivSignalingServer(PRIVSIGNALINGCLIENT_HANDLE privClientHandle);
RTC_C_EXPORT int EasyRTC_connectPrivUser(PRIVSIGNALINGCLIENT_HANDLE privClientHandle, char *hisid, char *hiskey, char *extradata0, int extradatalen0);
RTC_C_EXPORT int EasyRTC_disconnectPrivSignalingServer(PRIVSIGNALINGCLIENT_HANDLE privClientHandle);
RTC_C_EXPORT STATUS EasyRTC_createPeerConnection(PRtcConfiguration pRtcConfiguration, PRtcPeerConnection *ppRtcPeerConnection, uint32_t *uuids, int32_t sockfd);
RTC_C_EXPORT STATUS EasyRTC_peerConnectionOnSenderBandwidthEstimation(PRtcPeerConnection pRtcPeerConnection, UINT64 customData, RtcOnSenderBandwidthEstimation rtcOnSenderBandwidthEstimation);
RTC_C_EXPORT STATUS EasyRTC_peerConnectionOnDataChannel(PRtcPeerConnection pRtcPeerConnection, UINT64 customData, RtcOnDataChannel rtcOnDataChannel);
RTC_C_EXPORT STATUS EasyRTC_peerConnectionOnConnectionStateChange(PRtcPeerConnection pRtcPeerConnection, UINT64 customData, RtcOnConnectionStateChange rtcOnConnectionStateChange);
RTC_C_EXPORT STATUS EasyRTC_addTransceiver(PRtcPeerConnection pRtcPeerConnection, PRtcMediaStreamTrack pRtcMediaStreamTrack, PRtcRtpTransceiverInit pRtcRtpTransceiverInit, PRtcRtpTransceiver *ppRtcRtpTransceiver);
RTC_C_EXPORT STATUS EasyRTC_transceiverOnFrame(PRtcRtpTransceiver pRtcRtpTransceiver, UINT64 customData, RtcOnFrame rtcOnFrame);
RTC_C_EXPORT STATUS EasyRTC_transceiverOnBandwidthEstimation(PRtcRtpTransceiver pRtcRtpTransceiver, UINT64 customData, RtcOnBandwidthEstimation rtcOnBandwidthEstimation);
RTC_C_EXPORT STATUS EasyRTC_transceiverOnPictureLoss(PRtcRtpTransceiver pRtcRtpTransceiver, UINT64 customData, RtcOnPictureLoss rtcOnPictureLoss);
RTC_C_EXPORT STATUS EasyRTC_freeTransceiver(PRtcRtpTransceiver *pRtcRtpTransceiver);
RTC_C_EXPORT STATUS EasyRTC_createDataChannel(PRtcPeerConnection pRtcPeerConnection, PCHAR pDataChannelName, PRtcDataChannelInit pRtcDataChannelInit, PRtcDataChannel *ppRtcDataChannel);
RTC_C_EXPORT STATUS EasyRTC_dataChannelOnMessage(PRtcDataChannel pRtcDataChannel, UINT64 customData, RtcOnMessage rtcOnMessage);
RTC_C_EXPORT STATUS EasyRTC_dataChannelOnOpen(PRtcDataChannel pRtcDataChannel, UINT64 customData, RtcOnOpen rtcOnOpen);
RTC_C_EXPORT STATUS EasyRTC_dataChannelSend(PRtcDataChannel pRtcDataChannel, BOOL isBinary, PBYTE pMessage, UINT32 pMessageLen);
RTC_C_EXPORT STATUS EasyRTC_createOfferAndSubmit(PRtcPeerConnection pRtcPeerConnection);
RTC_C_EXPORT STATUS EasyRTC_createAnswerAndSubmit(PRtcPeerConnection pRtcPeerConnection, PBYTE offersdp);
RTC_C_EXPORT STATUS EasyRTC_writeFrame(PRtcRtpTransceiver pRtcRtpTransceiver, PFrame pFrame);
RTC_C_EXPORT STATUS EasyRTC_getIceCandidatePairStats(PRtcPeerConnection pRtcPeerConnection, PRtcIceCandidatePairStats pRtcIceCandidatePairStats);
RTC_C_EXPORT STATUS EasyRTC_getIceCandidateStats(PRtcPeerConnection pRtcPeerConnection, BOOL isRemote, PRtcIceCandidateStats pRtcIceCandidateStats);
RTC_C_EXPORT STATUS EasyRTC_getIceServerStats(PRtcPeerConnection pRtcPeerConnection, PRtcIceServerStats pRtcIceServerStats);
RTC_C_EXPORT STATUS EasyRTC_getTransportStats(PRtcPeerConnection pRtcPeerConnection, PRtcTransportStats pRtcTransportStats);
RTC_C_EXPORT STATUS EasyRTC_getRtpRemoteInboundStats(PRtcPeerConnection pRtcPeerConnection, PRtcRtpTransceiver pRtcRtpTransceiver, PRtcRemoteInboundRtpStreamStats pRtcRemoteInboundRtpStreamStats);
RTC_C_EXPORT STATUS EasyRTC_getRtpOutboundStats(PRtcPeerConnection pRtcPeerConnection, PRtcRtpTransceiver pRtcRtpTransceiver, PRtcOutboundRtpStreamStats pRtcOutboundRtpStreamStats);
RTC_C_EXPORT STATUS EasyRTC_getRtpInboundStats(PRtcPeerConnection pRtcPeerConnection, PRtcRtpTransceiver pRtcRtpTransceiver, PRtcInboundRtpStreamStats pRtcInboundRtpStreamStats);
RTC_C_EXPORT STATUS EasyRTC_getDataChannelStats(PRtcPeerConnection pRtcPeerConnection, PRtcDataChannelStats pRtcDataChannelStats);
RTC_C_EXPORT STATUS EasyRTC_rtcPeerConnectionGetMetrics(PRtcPeerConnection pRtcPeerConnection, PRtcRtpTransceiver pRtcRtpTransceiver, PRtcStats pRtcStats);
RTC_C_EXPORT STATUS EasyRTC_closePeerConnection(PRtcPeerConnection pRtcPeerConnection);
相当于是将WebRTC的全套流程完全做一次封装,满足各种平台的调用,能Input音视频数据,也能Output音视频数据,实现全视频通话和单语音通话的目标。
稍后附上体验效果的视频:
微信小程序WebRTC通话