HYP2P是好游科技开发的p2p sdk,利用nat穿透的原理实现p2p打洞,主要用于实时音视频的传输。使用时可以配置成tcp模式或udp模式,tcp模式会自动帮您解决丢包、乱序、重传问题。中转模式则是基于tcp实现的。您可以灵活的自定义通信双方的协议,HYP2P不会解析您的业务数据。
下面通过两个程序配合演示p2p传输实时视频流,一个作为播放端的A,另一个是提供rtsp视频服务的B,A和B分别运行于不同的内网机器上。程序启动时A和B都是连接p2p服务器,打洞成功后,A直接从B获取rtsp视频流,并由vlc播放。
rtsp协议本身支持用udp或tcp传输实际的视频流,由于HYP2P的底层是由udp实现的,因此为了简单,我们这里配置vlc播放器使用tcp模式: 运行VLC media player后 ,选择工具—偏好设置—输入/编解码器。在最下面的live555流传输中选择 RTP over RTSP (TCP), 如下图:

下面先看程序A的代码,以下示例代码在windows下用vc2017或以上编译并执行。
#include "stdafx.h"
#include "p2papi.h"
int g_nlocalport=0;
int DEVICE_ID = 1000;
int g_nP2PSetUp = 0;
class CP2PHoleSink : public IP2PSessionSink
{
public:
CP2PHoleSink()
{
}
~CP2PHoleSink()
{
}
virtual void onServerConnected(int session, int state)
{
p2p_login_server(session, DEVICE_ID);
}
virtual void onLoginServer(int session, int state)
{
//13是要连接的设备ID
p2p_connect_peer(session,13);
}
virtual void onHoleState(int session, int state)
{
g_nP2PSetUp =state;
}
virtual void onRecvServerData(int cmd, int subcmd, const unsigned char * pDataBuffer, int wDataSize)
{
}
virtual void onRecvP2PData(int session,int channel, const unsigned char * pDataBuffer, int wDataSize)
{
}
virtual void onChannelState(int session,int state)
{
}
virtual bool OnSocketCommand(int wMain, int sub, const void* pData, int nLen)
{
return true;
}
virtual void onProxyStarted(int session, int port)
{
}
};
int main(int argc, char* argv[])
{
int frame_index = 0;
int64_t start_time = 0;
if (argc >= 2)
DEVICE_ID = atoi(argv[1]);
printf("my deviceid = %d\n", DEVICE_ID);
p2p_engine_init("43.142.138.68",20000,"d:/p2p.log");//"192.168.3.166"
int sessionID = p2p_get_free_session();
CP2PHoleSink sink;
p2p_set_sink(sessionID,&sink);
g_nlocalport = 49999;
p2p_start_proxy(sessionID, g_nlocalport,1);
int64_t p2puid = DEVICE_ID | 0x1000000000000000;
p2p_connect_server(sessionID, p2puid, "");
printf("local server port=%d\n", g_nlocalport);
while (1)
{
SleepEx(10,TRUE);
}
p2p_stop_proxy(sessionID);
p2p_engine_destroy();
return 0;
}
与上一篇发送hello wold字符串的示例相比只是多了下面两行代码
g_nlocalport = 49999;
p2p_start_proxy(sessionID, g_nlocalport,1);
表示视频流将被获取到本机的49999端口上,vlc只需要将播放地址设置为:rtsp://127.0.0.1:49999/video/test.264,既可播放B程序提供的视频流。
接着再看程序B的代码,以下示例代码在windows下用vc2017或以上编译并执行。
#include "stdafx.h"
#include "p2papi.h"
#include "livemedia.h"
int DEVICE_ID = 13;
int g_nP2PSetUp = 0;
class CP2PHoleSink : public IP2PSessionSink
{
public:
CP2PHoleSink()
{
}
~CP2PHoleSink()
{
}
virtual void onServerConnected(int session, int state)
{
p2p_login_server(session, DEVICE_ID);
}
virtual void onLoginServer(int session, int state)
{
}
virtual void onHoleState(int session, int state)
{
g_nP2PSetUp=state;
}
virtual void onRecvServerData(int cmd, int subcmd, const unsigned char * pDataBuffer, int wDataSize)
{
}
virtual void onRecvP2PData(int session,int channel, const unsigned char * pDataBuffer, int wDataSize)
{
}
virtual void onChannelState(int session,int state)
{
}
virtual bool OnSocketCommand(int wMain, int sub, const void* pData, int nLen)
{
return true;
}
virtual void onProxyStarted(int session, int port)
{
}
};
int main(int argc, char* argv[])
{
int frame_index = 0;
int64_t start_time = 0;
if (argc >= 2)
DEVICE_ID = atoi(argv[1]);
p2p_engine_init("43.142.138.68",20000,"d:\p2pserver.log");//"192.168.3.166"
DWORD last_update_time = GetTickCount();
DWORD last_framenum_update = last_update_time;
DWORD nFrameNum = 0;
int initVal = 0;
printf("my deviceid = %d\n", DEVICE_ID );
int sessionID = p2p_get_free_session();
CP2PHoleSink sink;
p2p_set_sink(sessionID,&sink);
//设备授权ID和密钥:4294967390,49uozeazd9
//此授权ID与p2p_login_server中的设备ID不同
p2p_connect_server(sessionID, 4294967390, "49uozeazd9");
int serviceport = start_rtsp_server();
p2p_set_device_port(sessionID, serviceport);
while (initVal == 0)
{
rtsp_server_update();
SleepEx(10,TRUE);
}
p2p_stop_proxy(sessionID);
stop_rtsp_server();
p2p_engine_destroy();
return 0;
}
与上一篇发送hello wold字符串的示例相比只是多了下面一行代码
//serviceport参数是提供视频流的端口号
p2p_set_device_port(sessionID, serviceport);
此示例程序B中 livemedia.h 是实现rtsp功能库的头文件,里面定义了三个函数:start_rtsp_server,rtsp_server_update, stop_rtsp_server。
这三个函数本身与p2p功能不相关,只是实现rtsp视频流服务器的功能。
下面是vcl播放p2p视频的截屏:

以上通过两个控制台程序展示了使用 p2p传输rtsp视频的例子, 如有任何凝问,加我qq:390090739
测试时必须先运行B程序,再运行A程序,然后运行vcl media player,打开vcl后,选择 媒体—打开网络串流—网络,输入地址rtsp://127.0.0.1:49999/video/test.264,然后点“播放”按扭。