webRTC P2P库libyangpeerconnection8编程指南

概述

libyangpeerconnection8是一个webRTC媒体传输/数据通道的一个轻量级的webRTC库,基于metaRTC8.0的传输模块构建,包含pacer/fec/netEQ/twcc/Sender Side BWE等模块,在弱网对抗/内存优化等效果上有显著提升,可用于ffmpeg/obs等webRTC插件。

下载

  • 纯C库:libyangpeerconnection8_win_c.7z
  • C++库:libyangpeerconnection8_win_cpp.7z

libyangpeerconnection8下载地址

依赖文件

头文件

  • YangRtcPacer.h
  • YangPeerConnection8.h

库文件

  • yangpeerconnection8.dll
  • yangpeerconnection8.lib

C++库示例代码

对象建立与释放

YangPeerInfo peerInfo;
memset(&peerInfo, 0, sizeof(YangPeerInfo));
yang_init_peerParam(&peerInfo);

//推流需配置参数,拉流不需要
peerInfo.pushVideo.width = width;
peerInfo.pushVideo.height = height;
peerInfo.pushVideo.fps = 30;

peerInfo.uid = 0;
peerInfo.rtc.isControlled = yangfalse;
peerInfo.rtc.rtcLocalPort = 17000;
//YangCallbackReceive* receive
//YangCallbackIce* ice
//YangCallbackRtc* rtc
//YangCallbackSslAlert* sslAlert
YangPeerConnection8* peer = yang_create_peerConnection8(&peerInfo, receive, ice, rtc, sslAlert);

peer->addAudioTrack(Yang_AED_OPUS);
peer->addVideoTrack(Yang_VED_H264);
//YangSendrecv 	YangSendonly YangRecvonly
peer->addTransceiver(YangMediaAudio, YangSendonly);
peer->addTransceiver(YangMediaVideo, YangSendonly);
peer->createDataChannel();

//pacer用于推流,拉流不需要
YangRtcPacer* pacer=yang_create_rtcPacer(&peerInfo,yangtrue,yangtrue,NULL);
pacer->attachConnection(peer);//将connection与pacer关联

//delete peer
if(peer){
  delete peer;
  peer=NULL;
}

//delete pacer
if(pacer){
  delete pacer;
  pacer=NULL;
}

交换ICE Candidate

//通过信令取得对端candidate
peer->addIceCandidate(candidate);
//回调ice candidate
YangCallbackIce ice
void YangCallbackIce::ipc_onIceCandidate(int32_t uid,char* candidateStr){
    if (context == NULL) return;
    //取得candidateStr 通过信令传到对端
}

回调示例代码

//*************************YangRtcDemo.h**************

#include 

class YangRtcDemo:public YangCallbackReceive,public YangCallbackIce,public YangCallbackRtc,public YangCallbackSslAlert{
public:
	YangRtcDemo();
	virtual ~YangRtcDemo();
    YangRtcConnectionState m_connState;
public:
	void receiveAudio(YangFrame* audioFrame);
	//frametype:YANG_Frametype_I YANG_Frametype_P
	void receiveVideo(YangFrame* videoFrame);
	void receiveMsg(YangFrame* msgFrame);

	void onIceStateChange(int32_t  uid,YangIceCandidateState iceState);
	void onConnectionStateChange(int32_t  uid,YangRtcConnectionState connectionState);
	void onIceCandidate(int32_t  uid,char* sdp);
	void onIceGatheringState(int32_t  uid,YangIceGatheringState gatherState);

	void setMediaConfig(int32_t  puid,YangAudioParam* audio,YangVideoParam* video);
	void sendRequest(int32_t  puid,uint32_t  ssrc,YangRequestType req);

	void sslCloseAlert(int32_t  uid);

}


//*************************YangRtcDemo.cpp**************

void YangRtcDemo::receiveAudio(YangFrame* audioFrame){
    //接收音频数据
}
//frametype:YANG_Frametype_I YANG_Frametype_P
void YangRtcDemo::receiveVideo(YangFrame* videoFrame){
    //接收视频数据
}
void YangRtcDemo::receiveMsg(YangFrame* msgFrame){
    //接收datachannel数据
	if (m_dataMsg) 			
		m_dataMsg->receiveMsg(m_dataMsg->user, 0, msgFrame->payload, msgFrame->nb);		
}

void YangRtcDemo::onIceStateChange(int32_t  uid,YangIceCandidateState iceState){
	switch(iceState){
	case YangIceSuccess:{
		break;
	}
	case YangIceFail:{
		yang_trace("\nYangIceFail remove uid==%d",uid);
		disconnectPeer();
		break;
	}
	default:break;

	}
}
void YangRtcDemo::onConnectionStateChange(int32_t  uid,YangRtcConnectionState connectionState){
	
	switch(connectionState){
	case Yang_Conn_State_Connecting:{
		break;
	}
	case Yang_Conn_State_Connected:{
		m_connState = connectionState;
		break;
	}
	case Yang_Conn_State_Disconnected:{
		m_connState = connectionState;
		break;
	}
	case Yang_Conn_State_Failed:{
		yang_trace("\nYang_Conn_State_Failed remove uid==%d",uid);
        m_connState = Yang_Conn_State_New;
		disconnectPeer();
		break;
	}
	case Yang_Conn_State_Closed:{
		break;
	}
	default:break;
	}
}

void YangRtcDemo::onIceCandidate(int32_t  uid,char* candidateStr){
	//取得candidate传到对端
}

void YangRtcDemo::onIceGatheringState(int32_t  uid,YangIceGatheringState gatherState){

}

void YangRtcDemo::setMediaConfig(int32_t  puid,YangAudioParam* audio,YangVideoParam* video){

}


void YangRtcDemo::sendRequest(int32_t  puid,uint32_t  ssrc,YangRequestType req){
	
	//向编码器发送关键帧请求或者码率变化状态
}

void YangRtcDemo::sslCloseAlert(int32_t  uid) {
	m_connState = Yang_Conn_State_Closed;
}

推流

frametype:YANG_Frametype_I(I帧) YANG_Frametype_P(P帧或B帧)
//I帧 startCode+sps+startCode+pps+startCode+I帧 如:00,00,00,01,67,42,c0,1f,8c,8d,40,50,1e,d0,0f,08,84,6a,00,00,00,01,68,ce,3c,80,00,00,00,01,65,b8,00,04,00,00,13,88,c5
//P帧或B帧 如:00,00,00,01,61,e0,00,40,00,be,41,38,22,93,df
//去掉start code 00,00,00,01,取61,e0,00,40,00,be,41,38,22,93,df
pacer->bufferVideoFrame(videoFrame);

//取得音视频编码后数据
pacer->bufferAudioFrame(audioFrame);

//线程推流
while (yangtrue) {
	
	if(!inited){
		inited = yangtrue;
		pacer->reset();
	}
	pacer->process();

}

拉流

//implement YangCallbackReceive
void YangIpcRtc::receiveAudio(YangFrame* audioFrame){
  //接收到音频data,length,pts
}
//frametype:YANG_Frametype_I YANG_Frametype_P
void YangIpcRtc::receiveVideo(YangFrame* videoFrame){
//接收到视频data,length,pts,frametype
}
//接收datachannel数据
void YangIpcRtc::receiveMsg(YangFrame* msgFrame){
	if (m_dataMsg) 			
		m_dataMsg->receiveMsg(m_dataMsg->user, 0, msgFrame->payload, msgFrame->nb);		
}

纯C库示例代码

对象分配与释放

YangPeerInfo peerInfo;
YangPeerConnection8* peer = (YangPeerConnection8*)calloc(1, sizeof(YangPeerConnection8));
//pacer用于推流,拉流不需要
YangRtcPacer* pacer=(YangRtcPacer*)calloc(1,sizeof(YangRtcPacer));

memset(&peerInfo, 0, sizeof(YangPeerInfo));
yang_init_peerParam(&peerInfo);

//推流时需配置参数,拉流不需要
peerInfo.pushVideo.width = width;
peerInfo.pushVideo.height = height;
peerInfo.pushVideo.fps = 30;

peerInfo.uid = 0;
peerInfo.rtc.isControlled = yangfalse;
peerInfo.rtc.rtcLocalPort = 17000;

//YangCallbackReceive* receive
//YangCallbackIce* ice
//YangCallbackRtc* rtc
//YangCallbackSslAlert* sslAlert
yang_create_peerConnection8(peer,&peerInfo, receive, ice, rtc, sslAlert);

peer->addAudioTrack(peer->session,Yang_AED_OPUS);
peer->addVideoTrack(peer->session, Yang_VED_H264);
peer->addTransceiver(peer->session, YangMediaAudio, YangSendonly);
peer->addTransceiver(peer->session, YangMediaVideo, YangSendonly);
peer->createDataChannel(peer->session);

//pacer用于推流,拉流不需要
yang_create_rtcPacer(pacer,&peerInfo,yangtrue,yangtrue,NULL);
pacer->attachConnection(pacer->session,peer);//将connection与pacer关联

//free peer
if(peer){
  yang_destroy_peerConnection8(peer);
  free peer;
  peer=NULL;
}

//free pacer
if(pacer){
  yang_destroy_rtcPacer(pacer);
  free pacer;
  pacer=NULL;
}

交换ICE Candidate

//通过信令取得对端candidate
peer->addIceCandidate(&peer->peer,candidate);
//回调函数
static void ipc_onIceCandidate(void* context, int32_t uid,char* sdp){
    if (context == NULL) return;
    //取得candidate 通过信令传到对端
}

回调函数

//********************YangCallbackReceive*******************************
static void yang_receiveAudio(void* user,YangFrame* audioFrame){
  //接收到音频data,length,pts
}
//frametype:YANG_Frametype_I YANG_Frametype_P
static void yang_receiveVideo(void* user,YangFrame* videoFrame){
//接收到视频data,length,pts,frametype
}
//接收datachannel数据
static void yang_receiveMsg(void* user,YangFrame* msgFrame){
	if (m_dataMsg) 			
		m_dataMsg->receiveMsg(m_dataMsg->user, 0, msgFrame->payload, msgFrame->nb);		
}
//********************YangCallbackIce*******************************
static void yang_onIceStateChange(void* user,int32_t  uid,YangIceCandidateState iceState){
	switch(iceState){
	case YangIceSuccess:{
		break;
	}
	case YangIceFail:{
		yang_trace("\nYangIceFail remove uid==%d",uid);
		disconnectPeer();
		break;
	}
	default:break;

	}
}
static void yang_onConnectionStateChange(void* user,int32_t  uid,YangRtcConnectionState connectionState){
	
	switch(connectionState){
	case Yang_Conn_State_Connecting:{
		break;
	}
	case Yang_Conn_State_Connected:{
		m_connState = connectionState;
		break;
	}
	case Yang_Conn_State_Disconnected:{
		m_connState = connectionState;
		break;
	}
	case Yang_Conn_State_Failed:{
		yang_trace("\nYang_Conn_State_Failed remove uid==%d",uid);
        m_connState = Yang_Conn_State_New;
		disconnectPeer();
		break;
	}
	case Yang_Conn_State_Closed:{
		break;
	}
	default:break;
	}
}

static void yang_onIceCandidate(void* user,int32_t  uid,char* candidateStr){
	//取得candidate传到对端
}

static void yang_onIceGatheringState(int32_t  uid,YangIceGatheringState gatherState){

}
//********************YangCallbackRtc*******************************
static void yang_setMediaConfig(void* user,int32_t  puid,YangAudioParam* audio,YangVideoParam* video){

}

static void yang_sendRequest(void* user,int32_t  puid,uint32_t  ssrc,YangRequestType req){
	//向编码器发送关键帧请求或者码率变化状态
}
//********************YangCallbackSslAlert*******************************
static void yang_sslCloseAlert(void* user,int32_t  uid) {
	m_connState = Yang_Conn_State_Closed;
}

推流

frametype:YANG_Frametype_I(I帧) YANG_Frametype_P(P帧或B帧)
//I帧 startCode+sps+startCode+pps+startCode+I帧 如:00,00,00,01,67,42,c0,1f,8c,8d,40,50,1e,d0,0f,08,84,6a,00,00,00,01,68,ce,3c,80,00,00,00,01,65,b8,00,04,00,00,13,88,c5
//P帧或B帧 如:00,00,00,01,61,e0,00,40,00,be,41,38,22,93,df
//去掉start code 00,00,00,01,取61,e0,00,40,00,be,41,38,22,93,df

//取得音视频编码后数据
pacer->bufferVideoFrame(videoFrame);
pacer->bufferAudioFrame(audioFrame);
//线程推流
while (yangtrue) {
	
	if(!inited){
		inited = yangtrue;
		pacer->reset();
	}
	pacer->process();

}
pacer->bufferVideoFrame(pacer->session, videoFrame);
pacer->bufferAudioFrame(pacer->session, audioFrame);
//线程推流
while (yangtrue) {
	
	if(!inited){
		inited = yangtrue;
		pacer->reset(pacer->session);
	}
	pacer->process(pacer->session);

}

拉流

//implement YangCallbackReceive
static void yang_receiveAudio(void* user,YangFrame* audioFrame){
  //接收到音频data,length,pts
}
//frametype:YANG_Frametype_I YANG_Frametype_P
static void yang_receiveVideo(void* user,YangFrame* videoFrame){
//接收到视频data,length,pts,frametype
}
//接收datachannel数据
static void yang_receiveMsg(void* user,YangFrame* msgFrame){
	if (m_dataMsg) 			
		m_dataMsg->receiveMsg(m_dataMsg->user, 0, msgFrame->payload, msgFrame->nb);		
}

你可能感兴趣的:(解决方案,metaRTC,webrtc)