网络摄像机VC++二次开发编程

   网购一网络摄像机,准备用于无人车,文档只有例程没有详细的SDK使用,看了一下例程,先搞明白了实时预览的代码。摄像机支持标准协议,这种网络摄像机使用都差不多。

   例程是支撑多画面多设备的,使用对话框中嵌入formview子对话框的方式实现,先说SDK引入:

VS 建立一个基于对话框的项目,选择在静态库中使用MFC,在生产菜单-->配置管理器中将平台改为x64;修改项目属性C/C++中代码生成为多线程调试(/MTd);然后将下载的SDK包Include以及子文件夹路径添加到附加包含目录;将SDK包Lib 路径添加到附加库目录;在链接器的输入中附加依赖项XNetSDK.lib;将字符集改为使用多字节字符集。

在stdafx.h头文件中加入库头文件以及设备信息结构:

#include "XNetSDK.h"
#include "XNetSDKSyn.h"
#include "XPlaySDK.h"
typedef struct DeviceInfo
{
    char szIPAddress[64];        //Device ip
    int nDevicePort;            //Device port
    char szUserName[64];        //Device user name
    char szPassword[64];        //Device password
    XSDK_HANDLE hLoginID;        //Login handle
    int nChannelNum;            //Device channel number
}DeviceInfo;

创建一建一个fromview格式对话框,例如ID为IDD_DIALOG_VIDWO_WND;创建对话框类(如CVideoWnd);加入实时播放函数及关闭函数(如需要其他功能再引入其他函数,这里只实现单画面实时预览):

	XSDK_HANDLE OnRealPlay(XSDK_HANDLE hLogin, int nChannel);
	afx_msg void OnCloseVideo();

函数定义及回调函数定义:

int RealPlayMediaCallBack(XSDK_HANDLE hMedia, int nDataType, int nDataLen, int nParam2, int nParam3, const char* szString, void* pData, int64 pDataInfo, int nSeq, void* pUserData, void* pMsg)
{
	CVideoWnd* pThis = (CVideoWnd*)pUserData;
	if (EUIMSG_AUDIO_DATA == nDataType)
	{
		XSDK_HANDLE _tPlayer = pThis->OnGetTalkHandle();

		//将采集到的音频发送到设备端
		if (_tPlayer > 0 )
		{
			XSDK_SendTalkData(_tPlayer, (const char*)pData, nDataLen);
		}
	}
	return 0;
}

XSDK_HANDLE CVideoWnd::OnRealPlay(XSDK_HANDLE hLogin, int nChannel)
{
	OnCloseVideo();

	if (hLogin > 0)
	{
		SXMediaRealPlayReq param = { 0 };
		param.nChannel = nChannel;						// 通道号(必填)
		param.nStreamType = _nStreamType;				// 码流类型(必填)
		param.result.pUserData = NULL;					// 用户参数(选填)
		param.nRequestType = EXSDK_DATA_FORMATE_FRAME;	// 源数据输出(选填),详见nRequestType说明
		param.hShowWindows = this->m_hWnd;				// 显示窗口(选填)(暂时支持Window)
		param.nDecodeType = DECODE_RESULT_NULL;			// 解码结果(选填),详见nDecodeType说明
		param.result = RealPlayMediaCallBack;			// 结果回调(必填)

		_hPlayer = XSDK_MediaRealPlay(hLogin, ¶m);

		if (_hPlayer > 0)
		{
			_hLoginHandle = hLogin;
			_nCurChannel = nChannel;
			_nCurPlayState = State_Is_Playing;
		}
	}

	return _hPlayer;
}

void CVideoWnd::OnCloseVideo()
{

	if (_hPlayer > 0)
	{
		XSDK_MediaStop(_hPlayer);
	}

	_hPlayer = 0;

	_nCurPlayState = State_Not_Play;

	Invalidate();
}

主对话框中加入加入SDK初始化函数、连接设备函数、实时播放函数及关闭函数:

public:
	//XNetSDK Function
	void InitSDK();
	//Device sdk handle
	XSDK_HANDLE OnLoginDevice(SXSDKLoginParam* pDevice);
	void OnLogoutDevice(XSDK_HANDLE hLogin);
	int OnRealPlay(XSDK_HANDLE hLogin, int nChannel);
	void OnCloseVideoAll();

函数实现:

int CALLBACK Main_MessageCallBack(XSDK_HANDLE hDevice, int nMsgId, int nParam1, int nParam2, int nParam3, const char* szString, void* pObject, int64 lParam, int nSeq, void* pUserData, void* pMsg)
{	
	return 1;
}
void CtestvideoDlg::InitSDK()
{
	SXSDKInitParam initParam = { 0 };
	initParam.mainMsgCallBack = Main_MessageCallBack;
	XSDK_Init(&initParam);
}

XSDK_HANDLE CtestvideoDlg::OnLoginDevice(SXSDKLoginParam* pDevice)
{
	XSDK_HANDLE hLoginID = 0;
	if (pDevice)
	{
		hLoginID = XSDK_DevLoginSyn(pDevice, 5000);

		if (hLoginID <= 0)
		{
			const char* szLoginError = XSDK_StrError(hLoginID);
			CString ss;
			ss.Format(_T("%s%s") "Login fail", szLoginError);
			AfxMessageBox(ss, MB_ICONERROR);
		}
	}
	
	return hLoginID;
}

void CtestvideoDlg::OnLogoutDevice(XSDK_HANDLE hLogin)
{
	if (hLogin > 0)
	{
		XSDK_DevLogout(hLogin);
	}
}


int CtestvideoDlg::OnRealPlay(XSDK_HANDLE hLogin, int nChannel)
{

	XSDK_HANDLE hPlayer = 0;

	int nWindIndex = 0;

	if (nWindIndex < 0)
	{
		nWindIndex = 0;
	}

	hPlayer = _cVideoWnd[nWindIndex].OnRealPlay(hLogin, nChannel);

	return hPlayer;

}

void CtestvideoDlg::OnCloseVideoAll()
{
	for(int i = 0;i < MAX_WIND_NUM;i++)
	{
		_cVideoWnd[i].OnCloseVideo();
	}
}

初始化主对话框中加入

	_cVideoWnd.Create(CVideoWnd::IDD, this);//创建视频子对话框窗口
	_cVideoWnd.ShowWindow(SW_HIDE);
    CRect _rWindArea;			//Play Window area
	_rWindArea.top=5;
	_rWindArea.bottom=485;
	_rWindArea.left=5;
	_rWindArea.right=645;
	_cVideoWnd.MoveWindow(_rWindArea);
	_cVideoWnd.ShowWindow(SW_SHOW);
    InitSDK();

然后使用IP地址及用户名密码可连接摄像机播放视频:

	SXSDKLoginParam* pDevice = new SXSDKLoginParam;
	pDevice->nCnnType=EDEV_CNN_TYPE_IP_DNS;
	pDevice->nDevPort=34567;
	strcpy(pDevice->sDevId,"192.168.*.*");
	strcpy(pDevice->sPassword,"***");
	strcpy(pDevice->sUserName,"****");
	XSDK_HANDLE hLoginID;
	hLoginID=OnLoginDevice(pDevice);
	OnRealPlay(hLoginID, 0); 

上述代码为子视频窗口方式,适合多画面播放,如果需要多画面创建多个子窗口就行,如果不需要多画面,也可以直接在如Picture控件中播放,如加入控件ID:IDC_PIC,主对话框代码只需要加入回调函数及改写OnRealPlay函数如下:

int RealPlayMediaCallBack(XSDK_HANDLE hMedia, int nDataType, int nDataLen, int nParam2, int nParam3, const char* szString, void* pData, int64 pDataInfo, int nSeq, void* pUserData, void* pMsg)
{
	CVideoWnd* pThis = (CVideoWnd*)pUserData;
	if (EUIMSG_AUDIO_DATA == nDataType)
	{
		XSDK_HANDLE _tPlayer = pThis->OnGetTalkHandle();

		//将采集到的音频发送到设备端
		if (_tPlayer > 0 )
		{
			XSDK_SendTalkData(_tPlayer, (const char*)pData, nDataLen);
		}
	}
	return 0;
}
int CtestvideoDlg::OnRealPlay(XSDK_HANDLE hLogin, int nChannel)
{

		OnCloseVideo();
		_nStreamType=0;
		HWND PichWnd=::GetDlgItem(this->m_hWnd,IDC_PIC);
	if (hLogin > 0)
	{
		SXMediaRealPlayReq param = { 0 };
		param.nChannel = nChannel;						// 通道号(必填)
		param.nStreamType = _nStreamType;				// 码流类型(必填)
		param.result.pUserData = NULL;					// 用户参数(选填)
		param.nRequestType = EXSDK_DATA_FORMATE_FRAME;	// 源数据输出(选填),详见nRequestType说明
		param.hShowWindows = PichWnd;				// 显示窗口(选填)(暂时支持Window)
		param.nDecodeType = DECODE_RESULT_NULL;			// 解码结果(选填),详见nDecodeType说明
		param.result = RealPlayMediaCallBack;			// 结果回调(必填)

		_hPlayer = XSDK_MediaRealPlay(hLogin, ¶m);

		if (_hPlayer > 0)
		{
			_hLoginHandle = hLogin;
			_nCurChannel = nChannel;
			_nCurPlayState = State_Is_Playing;
		}
	}

	return _hPlayer;


}

连接及播代码与使用子窗体一样。

代码运行环境不一样,可能需要ucrtbased.dll及vcruntime140d.dll,网上下载后拷入运行文件夹就行,注意动态库文件版本,有的会报错。

SDK下载链接XNetSDK_V1.0.4.0_2022-09-29

你可能感兴趣的:(c++,visual,studio,实时音视频)