#include "stdafx.h" #include #include #include #include "HCNetSDK.h" #include "plaympeg4.h" #include "FishEyeWindow.h" CFishEyeWindow::CFishEyeWindow() { } void CFishEyeWindow::Start(HWND hWnd,const char * ip) { m_hParent = hWnd; szAddress = ip; m_Thread = std::thread(&CFishEyeWindow::Run, this); } void CALLBACK g_ExceptionCallBack(DWORD dwType, LONG lUserID, LONG lHandle, void* pUser) { char tempbuf[256] = { 0 }; switch (dwType) { case EXCEPTION_RECONNECT: //预览时重连 printf("----------reconnect--------%d\n", time(NULL)); break; default: break; } } LONG lPort = -1; void CALLBACK g_RealDataCallBack_V30(LONG lRealHandle, DWORD dwDataType, BYTE* pBuffer, DWORD dwBufSize, void* dwUser) { HWND hWnd = (HWND)dwUser; switch (dwDataType) { case NET_DVR_SYSHEAD: //系统头 if (lPort >= 0) { break; //该通道取流之前已经获取到句柄,后续接口不需要再调用 } if (!PlayM4_GetPort(&lPort)) //获取播放库未使用的通道号 { break; } //m_iPort = lPort; //第一次回调的是系统头,将获取的播放库port号赋值给全局port,下次回调数据时即使用此port号播放 if (dwBufSize > 0) { if (!PlayM4_SetStreamOpenMode(lPort, STREAME_REALTIME)) //设置实时流播放模式 { break; } if (!PlayM4_OpenStream(lPort, pBuffer, dwBufSize, 1024 * 1024)) //打开流接口 { break; } if (!PlayM4_Play(lPort, hWnd)) //播放开始 { break; } } break; case NET_DVR_STREAMDATA: //码流数据 if (dwBufSize > 0 && lPort != -1) { if (!PlayM4_InputData(lPort, pBuffer, dwBufSize)) { break; } } break; default: //其他数据 if (dwBufSize > 0 && lPort != -1) { if (!PlayM4_InputData(lPort, pBuffer, dwBufSize)) { break; } } break; } } void CFishEyeWindow::Run() { m_bRun = true; WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = CFishEyeWindow::WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = GetModuleHandle(nullptr); wcex.hIcon = 0; wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wcex.lpszMenuName = NULL; char cName[MAX_PATH] = { 0 }; GetModuleFileNameA(wcex.hInstance, cName, sizeof(cName)); const char* szApp = "FisishEye"; wcex.lpszClassName = szApp; wcex.hIconSm = 0; RegisterClassEx(&wcex); m_hWnd = CreateWindow(szApp, nullptr, WS_POPUP| WS_CHILD, 1920, 0, 480, 480, m_hParent, NULL, wcex.hInstance, 0); SetWindowLongPtr(m_hWnd, GWLP_USERDATA, (LONG_PTR)this); ShowWindow(m_hWnd, SW_SHOW); UpdateWindow(m_hWnd); //--------------------------------------- // 初始化 NET_DVR_Init(); //设置连接时间与重连时间 NET_DVR_SetConnectTime(2000, 1); NET_DVR_SetReconnect(10000, true); //--------------------------------------- //设置异常消息回调函数 NET_DVR_SetExceptionCallBack_V30(0, NULL, g_ExceptionCallBack, NULL); NET_DVR_USER_LOGIN_INFO struLoginInfo = { 0 }; struLoginInfo.bUseAsynLogin = 0; //同步登录方式 strcpy_s(struLoginInfo.sDeviceAddress, szAddress.c_str()); //设备IP地址 struLoginInfo.wPort = 8000; //设备服务端口 strcpy_s(struLoginInfo.sUserName, "admin"); //设备登录用户名 strcpy_s(struLoginInfo.sPassword, "Aa123456"); //设备登录密码 //设备信息, 输出参数 NET_DVR_DEVICEINFO_V40 struDeviceInfoV40 = { 0 }; lUserID = NET_DVR_Login_V40(&struLoginInfo, &struDeviceInfoV40); if (lUserID < 0) { printf("Login failed, error code: %d\n", NET_DVR_GetLastError()); NET_DVR_Cleanup(); return; } NET_DVR_PREVIEWINFO struPlayInfo = { 0 }; struPlayInfo.hPlayWnd = NULL; //需要SDK解码时句柄设为有效值,仅取流不解码时可设为空 struPlayInfo.lChannel = 1; //预览通道号 struPlayInfo.dwStreamType = 0; //0-主码流,1-子码流,2-码流3,3-码流4,以此类推 struPlayInfo.dwLinkMode = 1; //0- TCP方式,1- UDP方式,2- 多播方式,3- RTP方式,4-RTP/RTSP,5-RSTP/HTTP struPlayInfo.bBlocked = 1; //0- 非阻塞取流,1- 阻塞取流 lRealPlayHandle = NET_DVR_RealPlay_V40(lUserID, &struPlayInfo, g_RealDataCallBack_V30, m_hWnd); if (lRealPlayHandle < 0) { printf("NET_DVR_RealPlay_V40 error, %d\n", NET_DVR_GetLastError()); NET_DVR_Logout(lUserID); NET_DVR_Cleanup(); return; } MSG msg; while (GetMessage(&msg, nullptr, 0, 0)) { if (msg.message == WM_DESTROY) break; TranslateMessage(&msg); DispatchMessage(&msg); } } LRESULT CFishEyeWindow::WndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam) { switch (wMsg) { case WM_CREATE: break; case WM_DESTROY: PostQuitMessage(0); break; } return DefWindowProc(hWnd, wMsg, wParam, lParam); }