- 浏览: 150612 次
- 性别:
- 来自: 广州
最新评论
-
yinren13:
说的便捷的视频会议,我们公司的遥控器一按就能开始的视频会议tu ...
便捷视频会议 -
xujinquan19:
...
可视通讯与移植、跨平台开发 -
xujinquan19:
...
Android 平台下的即时通讯 -
xujinquan19:
...
Android 平台下的即时通讯 -
xujinquan19:
...
Android 平台下的即时通讯
// BRAnyChatSDKDemoDlg.cpp : implementation file // #include "stdafx.h" #include <WINSOCK2.H> #include "BRAnyChatSDKDemo.h" #include "BRAnyChatSDKDemoDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif #define REFRESH_TRANSTASK_STATUS_TIMER 1 ///< 刷新传输任务状态定时器 #define REFRESH_SPEAKVOLUME_TIMER 2 ///< 更新用户说话音量定时器 #define REFRESH_RECORDSTATE_TIMER 3 ///< 更新录像状态定时器 class CAboutDlg : public CDialog { public: CAboutDlg(); // Dialog Data //{{AFX_DATA(CAboutDlg) enum { IDD = IDD_ABOUTBOX }; //}}AFX_DATA // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CAboutDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: //{{AFX_MSG(CAboutDlg) //}}AFX_MSG DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { //{{AFX_DATA_INIT(CAboutDlg) //}}AFX_DATA_INIT } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CAboutDlg) //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) //{{AFX_MSG_MAP(CAboutDlg) // No message handlers //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CBRAnyChatSDKDemoDlg dialog CBRAnyChatSDKDemoDlg::CBRAnyChatSDKDemoDlg(CWnd* pParent /*=NULL*/) : CDialog(CBRAnyChatSDKDemoDlg::IDD, pParent) { //{{AFX_DATA_INIT(CBRAnyChatSDKDemoDlg) m_bEnableAGC = TRUE; m_bEnableEcho = TRUE; m_bEnableNS = TRUE; m_bEnableVAD = TRUE; m_iPort = 8906; m_iRoomId = 1; //}}AFX_DATA_INIT m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CBRAnyChatSDKDemoDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CBRAnyChatSDKDemoDlg) DDX_Control(pDX, IDC_PROGRESS_SPEAKVOLUME0, m_ctrlSpeakVolume0); DDX_Control(pDX, IDC_PROGRESS_SPEAKVOLUME1, m_ctrlSpeakVolume1); DDX_Control(pDX, IDC_PROGRESS_SPEAKVOLUME2, m_ctrlSpeakVolume2); DDX_Control(pDX, IDC_PROGRESS_SPEAKVOLUME3, m_ctrlSpeakVolume3); DDX_Control(pDX, IDC_SLIDER_OUTVOLUME, m_ctrlOutVolume); DDX_Control(pDX, IDC_SLIDER_INVOLUME, m_ctrlInVolume); DDX_Control(pDX, IDC_COMBO_VCAPTURE, m_cbVideoCapture); DDX_Control(pDX, IDC_COMBO_ACAPTURE, m_cbAudioCapture); DDX_Control(pDX, IDC_EDIT_LOG, m_ctrlEditLog); DDX_Check(pDX, IDC_CHECK_AGC, m_bEnableAGC); DDX_Check(pDX, IDC_CHECK_ECHO, m_bEnableEcho); DDX_Check(pDX, IDC_CHECK_NS, m_bEnableNS); DDX_Check(pDX, IDC_CHECK_VAD, m_bEnableVAD); DDX_Text(pDX, IDC_EDIT_PORT, m_iPort); DDX_Text(pDX, IDC_EDIT_ROOMID, m_iRoomId); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CBRAnyChatSDKDemoDlg, CDialog) //{{AFX_MSG_MAP(CBRAnyChatSDKDemoDlg) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_WM_DESTROY() ON_BN_CLICKED(IDC_BUTTON_INIT, OnButtonInit) ON_MESSAGE(WM_GV_CONNECT,OnGVClientConnect) ON_MESSAGE(WM_GV_LOGINSYSTEM,OnGVClientLogin) ON_MESSAGE(WM_GV_ENTERROOM,OnGVClientEnterRoom) ON_MESSAGE(WM_GV_ONLINEUSER,OnGVClientOnlineUser) ON_MESSAGE(WM_GV_USERATROOM,OnGVClientUserAtRoom) ON_MESSAGE(WM_GV_MICSTATECHANGE,OnGVClientMicStateChange) ON_MESSAGE(WM_GV_LINKCLOSE,OnGVClientLinkClose) ON_MESSAGE(WM_GV_CHATMODECHG,OnGVClientChatModeChange) ON_BN_CLICKED(IDC_BUTTON_ENTERROOM, OnButtonEnterRoom) ON_BN_CLICKED(IDC_BUTTON_LEAVEROOM, OnButtonLeaveRoom) ON_BN_CLICKED(IDC_BUTTON_VIDEOPROPERTY, OnButtonVideoproperty) ON_BN_CLICKED(IDC_BUTTON_REFRESHCAPTURE, OnButtonRefreshCapture) ON_CBN_SELCHANGE(IDC_COMBO_VCAPTURE, OnSelchangeComboVideoCapture) ON_NOTIFY(NM_RELEASEDCAPTURE, IDC_SLIDER_OUTVOLUME, OnSliderOutVolumeChange) ON_NOTIFY(NM_RELEASEDCAPTURE, IDC_SLIDER_INVOLUME, OnOnSliderInVolumeChange) ON_CBN_SELCHANGE(IDC_COMBO_ACAPTURE, OnSelChangeComboAudioCapture) ON_WM_TIMER() ON_BN_CLICKED(IDC_BUTTON_SENDFILE, OnButtonSendFile) ON_BN_CLICKED(IDC_CHECK_VAD, OnCheckVad) ON_BN_CLICKED(IDC_CHECK_AGC, OnCheckAgc) ON_BN_CLICKED(IDC_CHECK_ECHO, OnCheckEcho) ON_BN_CLICKED(IDC_CHECK_NS, OnCheckNs) ON_BN_CLICKED(IDC_BUTTON_TRANSBUF, OnButtonTransbuf) ON_BN_CLICKED(IDC_BUTTON_RELEASE, OnButtonRelease) ON_BN_CLICKED(IDC_BUTTON_VIDEOCTRL0, OnButtonVideoctrl0) ON_BN_CLICKED(IDC_BUTTON_VIDEOCTRL1, OnButtonVideoctrl1) ON_BN_CLICKED(IDC_BUTTON_VIDEOCTRL2, OnButtonVideoctrl2) ON_BN_CLICKED(IDC_BUTTON_VIDEOCTRL3, OnButtonVideoctrl3) ON_BN_CLICKED(IDC_BUTTON_AUDIOCTRL0, OnButtonAudioctrl0) ON_BN_CLICKED(IDC_BUTTON_AUDIOCTRL1, OnButtonAudioctrl1) ON_BN_CLICKED(IDC_BUTTON_AUDIOCTRL2, OnButtonAudioctrl2) ON_BN_CLICKED(IDC_BUTTON_AUDIOCTRL3, OnButtonAudioctrl3) ON_BN_CLICKED(IDC_BUTTON_RECORDCTRL0, OnButtonRecordctrl0) ON_BN_CLICKED(IDC_BUTTON_RECORDCTRL1, OnButtonRecordctrl1) ON_BN_CLICKED(IDC_BUTTON_RECORDCTRL2, OnButtonRecordctrl2) ON_BN_CLICKED(IDC_BUTTON_RECORDCTRL3, OnButtonRecordctrl3) ON_BN_CLICKED(IDC_BUTTON_SNAPSHOTCTRL0, OnButtonSnapshotctrl0) ON_BN_CLICKED(IDC_BUTTON_SNAPSHOTCTRL1, OnButtonSnapshotctrl1) ON_BN_CLICKED(IDC_BUTTON_SNAPSHOTCTRL2, OnButtonSnapshotctrl2) ON_BN_CLICKED(IDC_BUTTON_SNAPSHOTCTRL3, OnButtonSnapshotctrl3) ON_BN_CLICKED(IDC_BUTTON_LOGIN, OnButtonLogin) ON_BN_CLICKED(IDC_BUTTON_LOGOUT, OnButtonLogout) //}}AFX_MSG_MAP END_MESSAGE_MAP() /** * 视频数据回调函数 */ void CALLBACK VideoData_CallBack(DWORD dwUserid, LPVOID lpBuf, DWORD dwLen, BITMAPINFOHEADER bmiHeader, LPVOID lpUserValue) { CBRAnyChatSDKDemoDlg* pDemoDlg = (CBRAnyChatSDKDemoDlg*)lpUserValue; if(pDemoDlg) pDemoDlg->DrawUserVideo(dwUserid,lpBuf,dwLen,bmiHeader); } /** * 音频数据回调函数 */ void CALLBACK AudioData_CallBack(DWORD dwUserid, LPVOID lpBuf, DWORD dwLen, WAVEFORMATEX waveFormatEx, LPVOID lpUserValue) { CBRAnyChatSDKDemoDlg* pDemoDlg = (CBRAnyChatSDKDemoDlg*)lpUserValue; if(pDemoDlg) { // do something ... } } /** * 音量更改回调函数 */ void CALLBACK VolumeChange_CallBack(BRAC_AudioDevice device, DWORD dwCurrentVolume, LPVOID lpUserValue) { CBRAnyChatSDKDemoDlg* pDemoDlg = (CBRAnyChatSDKDemoDlg*)lpUserValue; if(pDemoDlg) { if(device == BRAC_AD_WAVEIN) pDemoDlg->OnWaveInVolumeChange(dwCurrentVolume); else pDemoDlg->OnWaveOutVolumeChange(dwCurrentVolume); } } // 透明通道数据回调函数定义 void CALLBACK TransBuffer_CallBack(DWORD dwUserid, LPBYTE lpBuf, DWORD dwLen, LPVOID lpUserValue) { CBRAnyChatSDKDemoDlg* pDemoDlg = (CBRAnyChatSDKDemoDlg*)lpUserValue; if(pDemoDlg) { CString strNotify; strNotify.Format("TransBuffer_CallBack:dwUserid-%d, bufSize-%d",dwUserid,dwLen); pDemoDlg->AppendLogString(strNotify); } } // 透明通道数据扩展回调函数定义 void CALLBACK TransBufferEx_CallBack(DWORD dwUserid, LPBYTE lpBuf, DWORD dwLen, DWORD wParam, DWORD lParam, DWORD dwTaskId, LPVOID lpUserValue) { CBRAnyChatSDKDemoDlg* pDemoDlg = (CBRAnyChatSDKDemoDlg*)lpUserValue; if(pDemoDlg) { BOOL bSuccess = FALSE; if(dwLen > 1000) { bSuccess = lpBuf[1000] == 'Y' ? TRUE : FALSE; } CString strNotify; strNotify.Format("TransBufferEx_CallBack:dwUserid-%d, bufSize-%d,verify:%s",dwUserid,dwLen,bSuccess ? "Success" : "Fail"); pDemoDlg->AppendLogString(strNotify); } } // 文件传输回调函数定义 void CALLBACK TransFile_CallBack(DWORD dwUserid, LPCTSTR lpFileName, LPCTSTR lpTempFilePath, DWORD dwFileLength, DWORD wParam, DWORD lParam, DWORD dwTaskId, LPVOID lpUserValue) { CBRAnyChatSDKDemoDlg* pDemoDlg = (CBRAnyChatSDKDemoDlg*)lpUserValue; if(pDemoDlg) { CString strNotify; strNotify.Format("TransFile_CallBack:dwUserid-%d, lpFileName-%s, lpTempFilePath-%s",dwUserid,lpFileName,lpTempFilePath); pDemoDlg->AppendLogString(strNotify); } } // 录像、快照任务完成回调函数定义 void CALLBACK RecordSnapShot_CallBack(DWORD dwUserid, LPCTSTR lpFileName, DWORD dwParam, BOOL bRecordType, LPVOID lpUserValue) { CBRAnyChatSDKDemoDlg* pDemoDlg = (CBRAnyChatSDKDemoDlg*)lpUserValue; if(pDemoDlg) { CString strNotify; strNotify.Format("%s CallBack:dwUserid-%d, FilePathName-%s",bRecordType?"Record":"SnapShot",(int)dwUserid,lpFileName); pDemoDlg->AppendLogString(strNotify); } } // SDK Filter 通信数据回调函数定义 void CALLBACK SDKFilterData_CallBack(LPBYTE lpBuf, DWORD dwLen, LPVOID lpUserValue) { CBRAnyChatSDKDemoDlg* pDemoDlg = (CBRAnyChatSDKDemoDlg*)lpUserValue; if(pDemoDlg) { CString strNotify; strNotify.Format("SDK Filter CallBack:%s",lpBuf); pDemoDlg->AppendLogString(strNotify); } } /** * 绘制用户视频 * 数据来源于回调函数 * @param dwUserid 用户ID号 * @param lpBuf 视频数据缓冲区 * @param dwLen 缓冲区大小 * @param bmiHeader 视频缓冲区的头信息,包含了视频的大小、颜色位数等信息 */ void CBRAnyChatSDKDemoDlg::DrawUserVideo(DWORD dwUserid, LPVOID lpBuf, DWORD dwLen, BITMAPINFOHEADER bmiHeader) { // 根据用户ID号找到合适的显示区域 DWORD dwSite = -1; for(INT i=0; i<DEMO_SHOW_USER_NUM; i++) { if(m_iUserID[i] == (INT)dwUserid) { dwSite = i; break; } } if(dwSite == -1) return; CRect dispRect = m_UserRect[dwSite]; //构建Bitmap BITMAPINFOHEADER *lpbmi = (BITMAPINFOHEADER*)malloc(sizeof(BITMAPINFOHEADER)+dwLen); ZeroMemory(lpbmi,sizeof(BITMAPINFOHEADER)+dwLen); memcpy((LPBYTE)lpbmi,&bmiHeader,sizeof(bmiHeader)); memcpy(((LPBYTE)lpbmi+sizeof(BITMAPINFOHEADER)),lpBuf,dwLen); HDC hdc = ::GetDC(m_hWnd); HDC dcMem = ::CreateCompatibleDC(hdc); HBITMAP hBitmap = CreateDIBitmap(hdc,lpbmi,CBM_INIT,(LPBYTE)lpbmi+sizeof(BITMAPINFOHEADER),(LPBITMAPINFO)lpbmi,DIB_RGB_COLORS); //绘图 HBITMAP holdbm = (HBITMAP)SelectObject(dcMem,hBitmap); ::SetStretchBltMode(hdc,COLORONCOLOR); ::StretchBlt(hdc,dispRect.left,dispRect.top,dispRect.Width(),dispRect.Height(),dcMem,0,0,bmiHeader.biWidth,bmiHeader.biHeight,SRCCOPY); SelectObject(dcMem,holdbm); ::DeleteDC(dcMem); ::DeleteObject(hBitmap); ::ReleaseDC(m_hWnd,hdc); free(lpbmi); lpbmi = NULL; } BOOL CBRAnyChatSDKDemoDlg::OnInitDialog() { CDialog::OnInitDialog(); // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon // 初始化每个视频显示位置信息 GetDlgItem(IDC_STATIC_USER0)->ShowWindow(SW_HIDE); GetDlgItem(IDC_STATIC_USER0)->GetClientRect(m_UserRect[0]); GetDlgItem(IDC_STATIC_USER0)->ClientToScreen(m_UserRect[0]); ScreenToClient(m_UserRect[0]); GetDlgItem(IDC_STATIC_USER1)->ShowWindow(SW_HIDE); GetDlgItem(IDC_STATIC_USER1)->GetClientRect(m_UserRect[1]); GetDlgItem(IDC_STATIC_USER1)->ClientToScreen(m_UserRect[1]); ScreenToClient(m_UserRect[1]); GetDlgItem(IDC_STATIC_USER2)->ShowWindow(SW_HIDE); GetDlgItem(IDC_STATIC_USER2)->GetClientRect(m_UserRect[2]); GetDlgItem(IDC_STATIC_USER2)->ClientToScreen(m_UserRect[2]); ScreenToClient(m_UserRect[2]); GetDlgItem(IDC_STATIC_USER3)->ShowWindow(SW_HIDE); GetDlgItem(IDC_STATIC_USER3)->GetClientRect(m_UserRect[3]); GetDlgItem(IDC_STATIC_USER3)->ClientToScreen(m_UserRect[3]); ScreenToClient(m_UserRect[3]); // 隐藏录像状态标志 GetDlgItem(IDC_STATIC_RECORDSTATE0)->ShowWindow(SW_HIDE); GetDlgItem(IDC_STATIC_RECORDSTATE1)->ShowWindow(SW_HIDE); GetDlgItem(IDC_STATIC_RECORDSTATE2)->ShowWindow(SW_HIDE); GetDlgItem(IDC_STATIC_RECORDSTATE3)->ShowWindow(SW_HIDE); for(INT i=0; i<DEMO_SHOW_USER_NUM; i++) { m_iUserID[i] = -1; } m_dwTransTaskId = -1; m_iPort = 8906; m_iRoomId = 1; SetDlgItemText(IDC_IPADDRESS_SERVER,"211.155.25.90"); SetDlgItemText(IDC_EDIT_USERNAME,"AnyChat3"); UpdateData(FALSE); return TRUE; // return TRUE unless you set the focus to a control } void CBRAnyChatSDKDemoDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID, lParam); } } // If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework. void CBRAnyChatSDKDemoDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } } HCURSOR CBRAnyChatSDKDemoDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; } void CBRAnyChatSDKDemoDlg::OnDestroy() { BRAC_Release(); CDialog::OnDestroy(); } void CBRAnyChatSDKDemoDlg::OnButtonInit() { // 获取SDK的版本信息 DWORD dwMainVer,dwSubVer; CHAR szCompileTime[100] = {0}; BRAC_GetSDKVersion(dwMainVer,dwSubVer,szCompileTime,sizeof(szCompileTime)); CString logstr; logstr.Format("AnyChat Core SDK Version:%d.%d(%s)",dwMainVer,dwSubVer,szCompileTime); AppendLogString(logstr); // 打开(关闭)SDK的日志记录功能 BRAC_ActiveCallLog(TRUE); // 设置SDK核心组件所在目录(注:demo程序只是设置为当前目录,项目中需要设置为实际路径) CHAR szCoreSDKPath[MAX_PATH] = {0}; GetModuleFileName(NULL,szCoreSDKPath,sizeof(szCoreSDKPath)); (strrchr(szCoreSDKPath,'\\'))[1] = 0; BRAC_SetSDKOption(BRAC_SO_CORESDK_PATH,szCoreSDKPath,strlen(szCoreSDKPath)); // 根据BRAC_InitSDK的第二个参数:dwFuncMode,来告诉SDK该如何处理相关的任务(详情请参考开发文档) DWORD dwFuncMode = BRAC_FUNC_VIDEO_AUTODISP | BRAC_FUNC_AUDIO_AUTOPLAY | BRAC_FUNC_CHKDEPENDMODULE | BRAC_FUNC_AUDIO_VOLUMECALC | BRAC_FUNC_NET_SUPPORTUPNP | BRAC_FUNC_FIREWALL_OPEN | BRAC_FUNC_AUDIO_AUTOVOLUME| BRAC_FUNC_AUDIO_VOLUMECALC | BRAC_FUNC_CONFIG_LOCALINI; BRAC_InitSDK(this->GetSafeHwnd(),dwFuncMode); BRAC_SetVideoDataCallBack(BRAC_PIX_FMT_RGB24,VideoData_CallBack,this); BRAC_SetAudioDataCallBack(AudioData_CallBack,this); BRAC_SetVolumeChangeCallBack(VolumeChange_CallBack,this); BRAC_SetTransBufferExCallBack(TransBufferEx_CallBack,this); BRAC_SetTransBufferCallBack(TransBuffer_CallBack,this); BRAC_SetTransFileCallBack(TransFile_CallBack,this); BRAC_SetRecordSnapShotCallBack(RecordSnapShot_CallBack,this); BRAC_SetSDKFilterDataCallBack(SDKFilterData_CallBack,this); // BRAC_SelectVideoCapture("USB 视频设备"); // 设置指定的视频设备,则在后面打开时,就可以打开该设备,如果不调用该方法,则会打开默认的视频设备 UpdateData(TRUE); BRAC_SetSDKOption(BRAC_SO_AUDIO_AGCCTRL,(PCHAR)&m_bEnableAGC,sizeof(m_bEnableAGC)); BRAC_SetSDKOption(BRAC_SO_AUDIO_VADCTRL,(PCHAR)&m_bEnableVAD,sizeof(m_bEnableVAD)); BRAC_SetSDKOption(BRAC_SO_AUDIO_NSCTRL,(PCHAR)&m_bEnableNS,sizeof(m_bEnableNS)); BRAC_SetSDKOption(BRAC_SO_AUDIO_ECHOCTRL,(PCHAR)&m_bEnableEcho,sizeof(m_bEnableEcho)); // 设置录像临时文件保存路径 CHAR szRecordDirectory[MAX_PATH] = {0}; ::GetModuleFileName(NULL,szRecordDirectory,MAX_PATH); (strrchr(szRecordDirectory,'\\'))[1] = 0; strcat(szRecordDirectory,"Record"); BRAC_SetSDKOption(BRAC_SO_RECORD_TMPDIR,szRecordDirectory,strlen(szRecordDirectory)); // 设置录像文件质量参数 DWORD dwVideoBitrate = 200 * 1000; // 200kbps BRAC_SetSDKOption(BRAC_SO_RECORD_VIDEOBR,(PCHAR)&dwVideoBitrate,sizeof(DWORD)); DWORD dwAudioBitrate = 96 * 1000; // 96kbps BRAC_SetSDKOption(BRAC_SO_RECORD_AUDIOBR,(PCHAR)&dwAudioBitrate,sizeof(DWORD)); // 设置快照临时文件保存路径 CHAR szSnapShotDirectory[MAX_PATH] = {0}; ::GetModuleFileName(NULL,szSnapShotDirectory,MAX_PATH); (strrchr(szSnapShotDirectory,'\\'))[1] = 0; strcat(szSnapShotDirectory,"SnapShot"); BRAC_SetSDKOption(BRAC_SO_SNAPSHOT_TMPDIR,szSnapShotDirectory,strlen(szSnapShotDirectory)); // 设置SDK临时文件路径 CHAR szTempPath[MAX_PATH] = {0}; ::GetModuleFileName(NULL,szTempPath,MAX_PATH); (strrchr(szTempPath,'\\'))[1] = 0; strcat(szTempPath,"Temp"); BRAC_SetSDKOption(BRAC_SO_CORESDK_TMPDIR,szTempPath,strlen(szTempPath)); // 设置服务器认证密码 BRAC_SetServerAuthPass("BaiRuiTech"); // 需要与服务器配置项“SDKAuthPass”相同(大小写敏感),SDK才能正常连接到服务器 DWORD dwVolume = 0; BRAC_AudioGetVolume(BRAC_AD_WAVEOUT,dwVolume); m_ctrlOutVolume.SetPos(dwVolume); dwVolume = 0; BRAC_AudioGetVolume(BRAC_AD_WAVEIN,dwVolume); m_ctrlInVolume.SetPos(dwVolume); SetTimer(REFRESH_SPEAKVOLUME_TIMER,100,NULL); SetTimer(REFRESH_RECORDSTATE_TIMER,1000,NULL); } void CBRAnyChatSDKDemoDlg::OnButtonLogin() { UpdateData(TRUE); CString strServerIp,strUserName,strPassword; GetDlgItemText(IDC_IPADDRESS_SERVER,strServerIp); GetDlgItemText(IDC_EDIT_USERNAME,strUserName); GetDlgItemText(IDC_EDIT_LOGINPASS,strPassword); if(strServerIp.IsEmpty() || m_iPort <= 0) { AfxMessageBox("Invalid server ip address or port!"); return; } if(strUserName.IsEmpty()) { AfxMessageBox("Must input username for login system!"); return; } BRAC_Connect(strServerIp.GetBuffer(0),m_iPort); BRAC_Login(strUserName.GetBuffer(0),strPassword.GetBuffer(0),0); } void CBRAnyChatSDKDemoDlg::OnButtonEnterRoom() { UpdateData(TRUE); BRAC_EnterRoom(m_iRoomId,"",0); } void CBRAnyChatSDKDemoDlg::OnButtonLeaveRoom() { BRAC_LeaveRoom(1); // 保留自己的userid,因为这儿只是leaveroom,并非logout for(INT i=1; i<DEMO_SHOW_USER_NUM; i++) { m_iUserID[i] = -1; } } void CBRAnyChatSDKDemoDlg::OnButtonLogout() { BRAC_Logout(); for(INT i=0; i<DEMO_SHOW_USER_NUM; i++) { m_iUserID[i] = -1; } } void CBRAnyChatSDKDemoDlg::OnButtonRelease() { BRAC_Release(); for(INT i=0; i<DEMO_SHOW_USER_NUM; i++) { m_iUserID[i] = -1; } m_dwTransTaskId = -1; } /** * 收到消息:客户端连接服务器 * @param wParam (BOOL)表示是否连接成功 */ LRESULT CBRAnyChatSDKDemoDlg::OnGVClientConnect(WPARAM wParam, LPARAM lParam) { BOOL bSuccess = (BOOL)wParam; AppendLogString(bSuccess ? "连接服务器成功..." : "连接服务器失败..."); return 0; } /** * 收到消息:客户端登录系统 * @param wParam (INT)表示自己的用户ID号 * @param lParam (INT)表示登录结果:0 成功,否则为出错代码,参考出错代码定义 */ LRESULT CBRAnyChatSDKDemoDlg::OnGVClientLogin(WPARAM wParam, LPARAM lParam) { CString logstr; DWORD dwUserID = wParam; if(lParam == 0) { CHAR username[30]={0}; BRAC_GetUserName(dwUserID,username,sizeof(username)); logstr.Format("登录服务器成功,自己的用户编号为:%d(%s)",wParam,username); // 将用户的ID保存在第一个位置,否则在回调函数里面可能找不到绘制的位置 m_iUserID[0] = dwUserID; } else logstr.Format("登录服务器失败,出错代码为: %d ",lParam); AppendLogString(logstr); return 0; } /** * 收到消息:客户端进入房间 * @param wParam (INT)表示所进入房间的ID号 * @param lParam (INT)表示是否进入房间:0成功进入,否则为出错代码 */ LRESULT CBRAnyChatSDKDemoDlg::OnGVClientEnterRoom(WPARAM wParam, LPARAM lParam) { CString logstr; INT roomid = (INT)wParam; if(lParam == 0) { logstr.Format("成功进入编号为:%d 的房间",roomid); BRAC_SetVideoPos(-1,m_hWnd,m_UserRect[0].left,m_UserRect[0].top,m_UserRect[0].right,m_UserRect[0].bottom); BRAC_UserCameraControl(-1,TRUE); BRAC_UserSpeakControl(-1,TRUE); } else logstr.Format("申请进入房间失败,出错代码为: %d ",lParam); AppendLogString(logstr); return 0; } /** * 显示日志信息 */ void CBRAnyChatSDKDemoDlg::AppendLogString(CString logstr) { m_strLogInfo += (logstr + "\r\n"); m_ctrlEditLog.SetWindowText(m_strLogInfo); m_ctrlEditLog.LineScroll(m_ctrlEditLog.GetLineCount()); } /** * 收到当前房间的在线用户信息 * 进入房间后触发一次 * @param wParam (INT)表示在线用户数(不包含自己) * @param lParam (INT)表示房间ID */ LRESULT CBRAnyChatSDKDemoDlg::OnGVClientOnlineUser(WPARAM wParam, LPARAM lParam) { CString logstr; INT onlinenum = (INT)wParam; logstr.Format("在编号为:%d 的房间共有 %d 位在线用户",lParam, onlinenum); AppendLogString(logstr); DWORD dwUserNum = 0; BRAC_GetOnlineUser(NULL,dwUserNum); ///< 首先获取房间内在线人数 if(!dwUserNum) return 0; LPDWORD lpdwUserList = (LPDWORD)malloc(sizeof(DWORD)*dwUserNum); BRAC_GetOnlineUser(lpdwUserList,dwUserNum); ///< 真正获取在线用户列表 for(INT i=0; i< (INT)dwUserNum; i++) { DWORD userid = lpdwUserList[i]; // 给用户找一个空的位置显示面板(第0号位置留给自己) INT site = -1; for(INT i=1; i<DEMO_SHOW_USER_NUM; i++) { if(m_iUserID[i] == -1) { site = i; break; } } if(site != -1) { BRAC_SetVideoPos(userid,m_hWnd,m_UserRect[site].left,m_UserRect[site].top,m_UserRect[site].right,m_UserRect[site].bottom); BRAC_UserCameraControl(userid,TRUE); BRAC_UserSpeakControl(userid,TRUE); DWORD dwState = 0; BRAC_GetCameraState(userid,dwState); logstr.Format("用户%d 的视频状态是: %d",userid,dwState); AppendLogString(logstr); m_iUserID[site] = userid; } else ///< 已经没有位置了,Demo演示限制 break; } free(lpdwUserList); return 0; } /** * 收到消息:用户进入(离开)房间 * @param wParam (INT)表示用户ID号 * @param lParam (BOOL)表示该用户是进入(TRUE)或离开(FALSE)房间 */ LRESULT CBRAnyChatSDKDemoDlg::OnGVClientUserAtRoom(WPARAM wParam, LPARAM lParam) { CString logstr; INT userid = (INT)wParam; BOOL bEnter = (BOOL)lParam; CHAR username[30]={0}; BRAC_GetUserName(userid,username,sizeof(username)); logstr.Format("编号为:%d 的用户(%s) %s 房间",userid,username, bEnter ? "进入" : "离开"); AppendLogString(logstr); if(bEnter) { // 给用户找一个空的位置显示面板(第0号位置留给自己) INT site = -1; for(INT i=1; i<DEMO_SHOW_USER_NUM; i++) { if(m_iUserID[i] == -1) { site = i; break; } } if(site != -1) { BRAC_SetVideoPos(userid,m_hWnd,m_UserRect[site].left,m_UserRect[site].top,m_UserRect[site].right,m_UserRect[site].bottom); BRAC_UserCameraControl(userid,TRUE); BRAC_UserSpeakControl(userid,TRUE); m_iUserID[site] = userid; } } else { //清除该用户占用位置的信息 for(INT i=1; i<DEMO_SHOW_USER_NUM; i++) { if(m_iUserID[i] == userid) { m_iUserID[i] = -1; break; } } } return 0; } /** * 收到消息:用户的音频设备状态变化消息 * @param wParam (INT)表示用户ID号 * @param lParam (BOOL)表示该用户是否已打开音频采集设备 */ LRESULT CBRAnyChatSDKDemoDlg::OnGVClientMicStateChange(WPARAM wParam, LPARAM lParam) { CString logstr; logstr.Format("编号为:%d 的用户 %s 本地Mic设备",wParam, lParam ? "打开" : "关闭"); AppendLogString(logstr); return 0; } /** * 收到消息:网络连接已关闭 * 该消息只有在客户端连接服务器成功之后,网络异常中断之时触发 */ LRESULT CBRAnyChatSDKDemoDlg::OnGVClientLinkClose(WPARAM wParam, LPARAM lParam) { AppendLogString("网络连接已关闭(断开)"); for(INT i=0; i<DEMO_SHOW_USER_NUM; i++) { m_iUserID[i] = -1; } return 0; } /** * 用户聊天模式发生变化 * @param wParam (INT)表示用户ID号 * @param lParam (INT)表示用户的当前聊天模式 */ LRESULT CBRAnyChatSDKDemoDlg::OnGVClientChatModeChange(WPARAM wParam, LPARAM lParam) { CString logstr; INT userid = (INT)wParam; INT chatmode = (INT)lParam; if(m_iUserID[0] == userid) { logstr.Format("自己(%d )的聊天模式改变,当前聊天模式为:%s",userid, chatmode == 0 ? "公聊模式" : "私聊模式"); } else logstr.Format("编号为:%d 的用户聊天模式改变,当前聊天模式为:%s",userid, chatmode == 0 ? "公聊模式" : "私聊模式"); AppendLogString(logstr); return 0; } void CBRAnyChatSDKDemoDlg::OnButtonVideoproperty() { BRAC_ShowLVProperty(m_hWnd,"AnyChat 本地视频画质调节"); } /** * 刷新设备列表 */ void CBRAnyChatSDKDemoDlg::OnButtonRefreshCapture() { // 刷新视频采集设备下拉列表 PCHAR DeviceName[10] = {0}; DWORD DeviceNum = 10; BRAC_EnumVideoCapture(DeviceName,DeviceNum); m_cbVideoCapture.ResetContent(); INT i=0; for(i=0; i<(INT)DeviceNum; i++) { if(DeviceName[i]) { m_cbVideoCapture.AddString(DeviceName[i]); ::GlobalFree((HGLOBAL)DeviceName[i]); DeviceName[i] = NULL; } } // 选择当前打开的视频采集设备 CHAR szVideoDeviceName[100] = {0}; BRAC_GetCurVideoCapture(szVideoDeviceName,sizeof(szVideoDeviceName)); m_cbVideoCapture.SelectString(-1,szVideoDeviceName); // 刷新音频采集设备下拉列表 DeviceNum = 10; BRAC_EnumAudioCapture(DeviceName,DeviceNum); m_cbAudioCapture.ResetContent(); for(i=0; i<(INT)DeviceNum; i++) { if(DeviceName[i]) { m_cbAudioCapture.AddString(DeviceName[i]); ::GlobalFree((HGLOBAL)DeviceName[i]); DeviceName[i] = NULL; } } // 选择当前打开的视频采集设备 CHAR szAudioDeviceName[100] = {0}; BRAC_GetCurAudioCapture(szAudioDeviceName,sizeof(szAudioDeviceName)); m_cbAudioCapture.SelectString(-1,szAudioDeviceName); } void CBRAnyChatSDKDemoDlg::OnSelchangeComboVideoCapture() { CString strCaptureName; m_cbVideoCapture.GetLBText(m_cbVideoCapture.GetCurSel(),strCaptureName); BRAC_SelectVideoCapture(strCaptureName); } void CBRAnyChatSDKDemoDlg::OnSelChangeComboAudioCapture() { CString strCaptureName; m_cbAudioCapture.GetLBText(m_cbAudioCapture.GetCurSel(),strCaptureName); BRAC_SelectAudioCapture(strCaptureName); } void CBRAnyChatSDKDemoDlg::OnSliderOutVolumeChange(NMHDR* pNMHDR, LRESULT* pResult) { DWORD dwVolume = m_ctrlOutVolume.GetPos(); BRAC_AudioSetVolume(BRAC_AD_WAVEOUT,dwVolume); *pResult = 0; } void CBRAnyChatSDKDemoDlg::OnOnSliderInVolumeChange(NMHDR* pNMHDR, LRESULT* pResult) { DWORD dwVolume = m_ctrlInVolume.GetPos(); BRAC_AudioSetVolume(BRAC_AD_WAVEIN,dwVolume); *pResult = 0; } // 录音的音量发生改变 void CBRAnyChatSDKDemoDlg::OnWaveInVolumeChange(DWORD dwVolume) { m_ctrlInVolume.SetPos(dwVolume); } // 放音的音量发生改变 void CBRAnyChatSDKDemoDlg::OnWaveOutVolumeChange(DWORD dwVolume) { m_ctrlOutVolume.SetPos(dwVolume); } void CBRAnyChatSDKDemoDlg::OnTimer(UINT nIDEvent) { switch(nIDEvent) { case REFRESH_TRANSTASK_STATUS_TIMER: // 刷新缓冲区传输任务状态 { if(m_dwTransTaskId == -1) { KillTimer(REFRESH_TRANSTASK_STATUS_TIMER); break; } DWORD ret; DWORD dwStatus = 0; ret = BRAC_QueryTransTaskInfo(-1,m_dwTransTaskId,BRAC_TRANSTASK_STATUS,(PCHAR)&dwStatus,sizeof(DWORD)); if(ret != GV_ERR_SUCCESS) { KillTimer(REFRESH_TRANSTASK_STATUS_TIMER); m_dwTransTaskId = -1; SetDlgItemText(IDC_STATIC_FILESTATUS,""); if(ret == GV_ERR_TRANSBUF_NOTASK) AppendLogString("传输任务不存在,可能对方已离开房间!"); else AppendLogString("查询任务信息失败!"); break; } DOUBLE dbProgress = 0.0; BRAC_QueryTransTaskInfo(-1,m_dwTransTaskId,BRAC_TRANSTASK_PROGRESS,(PCHAR)&dbProgress,sizeof(DOUBLE)); DWORD dwBitrate = 0; BRAC_QueryTransTaskInfo(-1,m_dwTransTaskId,BRAC_TRANSTASK_BITRATE,(PCHAR)&dwBitrate,sizeof(DWORD)); CString strStatus; switch(dwStatus) { case 1: strStatus = "Ready"; break; case 2: strStatus = "Process"; break; case 3: strStatus = "Finish"; break; case 4: strStatus = "Cancel"; break; case 5: strStatus = "Reject"; break; default: strStatus = "Unkonw"; break; } if(dwStatus == 3) // finish { KillTimer(REFRESH_TRANSTASK_STATUS_TIMER); m_dwTransTaskId = -1; AppendLogString("传输任务已完成!"); } CString strBitrate; if(dwBitrate >= 1000 * 1000) strBitrate.Format("%.02f Mbps",(float)dwBitrate/1000/1000); else if(dwBitrate >= 1000) strBitrate.Format("%.02f Kbps",(float)dwBitrate/1000); else strBitrate.Format("%.02f bps",(float)dwBitrate); CString strNotify; strNotify.Format("%s-%.02f%%-%s",strStatus,dbProgress,strBitrate); SetDlgItemText(IDC_STATIC_FILESTATUS,strNotify); } case REFRESH_SPEAKVOLUME_TIMER: // 刷新用户说话音量 { DOUBLE fSpeakVolume = 0.0; if(m_iUserID[0] != -1 && BRAC_QueryUserState(m_iUserID[0],BRAC_USERSTATE_SPEAKVOLUME,(PCHAR)&fSpeakVolume,sizeof(DOUBLE)) == GV_ERR_SUCCESS) m_ctrlSpeakVolume0.SetPos((INT)fSpeakVolume); else m_ctrlSpeakVolume0.SetPos(0); fSpeakVolume = 0.0; if(m_iUserID[1] != -1 && BRAC_QueryUserState(m_iUserID[1],BRAC_USERSTATE_SPEAKVOLUME,(PCHAR)&fSpeakVolume,sizeof(DOUBLE)) == GV_ERR_SUCCESS) m_ctrlSpeakVolume1.SetPos((INT)fSpeakVolume); else m_ctrlSpeakVolume1.SetPos(0); fSpeakVolume = 0.0; if(m_iUserID[2] != -1 && BRAC_QueryUserState(m_iUserID[2],BRAC_USERSTATE_SPEAKVOLUME,(PCHAR)&fSpeakVolume,sizeof(DOUBLE)) == GV_ERR_SUCCESS) m_ctrlSpeakVolume2.SetPos((INT)fSpeakVolume); else m_ctrlSpeakVolume2.SetPos(0); fSpeakVolume = 0.0; if(m_iUserID[3] != -1 && BRAC_QueryUserState(m_iUserID[3],BRAC_USERSTATE_SPEAKVOLUME,(PCHAR)&fSpeakVolume,sizeof(DOUBLE)) == GV_ERR_SUCCESS) m_ctrlSpeakVolume3.SetPos((INT)fSpeakVolume); else m_ctrlSpeakVolume3.SetPos(0); } break; case REFRESH_RECORDSTATE_TIMER: // 刷新录像状态 { DWORD dwRecordState = 0; if(m_iUserID[0] != -1 && BRAC_QueryUserState(m_iUserID[0],BRAC_USERSTATE_RECORDING,(PCHAR)&dwRecordState,sizeof(DWORD)) == GV_ERR_SUCCESS) { static BOOL bShow = FALSE; bShow = dwRecordState ? !bShow : FALSE; GetDlgItem(IDC_STATIC_RECORDSTATE0)->ShowWindow(bShow ? SW_SHOW : SW_HIDE); } dwRecordState = 0; if(m_iUserID[1] != -1 && BRAC_QueryUserState(m_iUserID[1],BRAC_USERSTATE_RECORDING,(PCHAR)&dwRecordState,sizeof(DWORD)) == GV_ERR_SUCCESS) { static BOOL bShow = FALSE; bShow = dwRecordState ? !bShow : FALSE; GetDlgItem(IDC_STATIC_RECORDSTATE1)->ShowWindow(bShow ? SW_SHOW : SW_HIDE); } dwRecordState = 0; if(m_iUserID[2] != -1 && BRAC_QueryUserState(m_iUserID[2],BRAC_USERSTATE_RECORDING,(PCHAR)&dwRecordState,sizeof(DWORD)) == GV_ERR_SUCCESS) { static BOOL bShow = FALSE; bShow = dwRecordState ? !bShow : FALSE; GetDlgItem(IDC_STATIC_RECORDSTATE2)->ShowWindow(bShow ? SW_SHOW : SW_HIDE); } dwRecordState = 0; if(m_iUserID[3] != -1 && BRAC_QueryUserState(m_iUserID[3],BRAC_USERSTATE_RECORDING,(PCHAR)&dwRecordState,sizeof(DWORD)) == GV_ERR_SUCCESS) { static BOOL bShow = FALSE; bShow = dwRecordState ? !bShow : FALSE; GetDlgItem(IDC_STATIC_RECORDSTATE3)->ShowWindow(bShow ? SW_SHOW : SW_HIDE); } } break; default: break; } CDialog::OnTimer(nIDEvent); } void CBRAnyChatSDKDemoDlg::OnButtonSendFile() { if(m_dwTransTaskId != -1) // 演示程序为了简洁,同时只允许传一个任务,实际上SDK是可以多任务并发的 return; static TCHAR BASED_CODE szFilter[] = _T("All Files (*.*)||*.*\0"); CFileDialog dlg(TRUE, NULL, NULL, /*OFN_HIDEREADONLY | */OFN_OVERWRITEPROMPT | OFN_ALLOWMULTISELECT, szFilter, this); if (dlg.DoModal() == IDOK) { CString strFileName = dlg.GetPathName(); DWORD dwTaskId = 0; DWORD wParam = 1; // 上层应用程序可自定义wParam、lParam的值,这两个参数的值将被回调给对方 DWORD lParam = 2; DWORD dwFlags = 0; // 该标志设置为0,则SDK将自动根据网络状态选择合适的传输途径(TCP、UDP or P2P) DWORD ret = BRAC_TransFile(m_iUserID[1],strFileName.GetBuffer(0),wParam,lParam,dwFlags,dwTaskId); if(ret == GV_ERR_SUCCESS) { m_dwTransTaskId = dwTaskId; SetTimer(REFRESH_TRANSTASK_STATUS_TIMER,100,NULL); } else { CString strError; strError.Format("创建文件传输任务失败,出错代码:%d",ret); AppendLogString(strError); SetDlgItemText(IDC_STATIC_FILESTATUS,""); } } } // 传输超大缓冲区任务演示 void CBRAnyChatSDKDemoDlg::OnButtonTransbuf() { if(m_dwTransTaskId != -1) // 演示程序为了简洁,同时只允许传一个任务,实际上SDK是可以多任务并发的 return; PCHAR lpBuf = (PCHAR)malloc(10*1024); // 为了演示,创建一个10KByte大小的缓冲区 DWORD dwLen = 10*1024; if(!lpBuf) return; lpBuf[1000] = 'Y'; // 演示的需要,为了验证收到的数据是否正确,在缓冲区中间某个位置设置一个标志,对方接收后,可判断该标志是否为设定值 DWORD dwTaskId = 0; DWORD wParam = 3; // 上层应用程序可自定义wParam、lParam的值,这两个参数的值将被回调给对方 DWORD lParam = 4; DWORD dwFlags = 0; // 该标志设置为0,则SDK将自动根据网络状态选择合适的传输途径(TCP、UDP or P2P) DWORD ret = BRAC_TransBufferEx(m_iUserID[1],(PBYTE)lpBuf,dwLen,wParam,lParam,dwFlags,dwTaskId); if(ret == GV_ERR_SUCCESS) { m_dwTransTaskId = dwTaskId; SetTimer(REFRESH_TRANSTASK_STATUS_TIMER,100,NULL); } else { CString strError; strError.Format("创建缓冲区传输任务失败,出错代码:%d",ret); AppendLogString(strError); SetDlgItemText(IDC_STATIC_FILESTATUS,""); } // 缓冲区调用完成后, 可以立即释放掉 free(lpBuf); // BRAC_TransBuffer(m_iUserID[1],(LPBYTE)"bairuitech",10); } void CBRAnyChatSDKDemoDlg::OnCheckVad() { UpdateData(TRUE); BRAC_SetSDKOption(BRAC_SO_AUDIO_VADCTRL,(PCHAR)&m_bEnableVAD,sizeof(m_bEnableVAD)); } void CBRAnyChatSDKDemoDlg::OnCheckAgc() { UpdateData(TRUE); BRAC_SetSDKOption(BRAC_SO_AUDIO_AGCCTRL,(PCHAR)&m_bEnableAGC,sizeof(m_bEnableAGC)); } void CBRAnyChatSDKDemoDlg::OnCheckEcho() { UpdateData(TRUE); BRAC_SetSDKOption(BRAC_SO_AUDIO_ECHOCTRL,(PCHAR)&m_bEnableEcho,sizeof(m_bEnableEcho)); } void CBRAnyChatSDKDemoDlg::OnCheckNs() { UpdateData(TRUE); BRAC_SetSDKOption(BRAC_SO_AUDIO_NSCTRL,(PCHAR)&m_bEnableNS,sizeof(m_bEnableNS)); } void CBRAnyChatSDKDemoDlg::OnButtonVideoctrl0() { // 为了演示程序简单,这儿采用静态变量保存上一次的状态,可能不准确,因为可能在别的地方有打开,或是关闭的操作,下同 // 特别是当前用户离开房间,别的用户再进来时,初始状态将不准确 static BOOL bLastState = TRUE; if(m_iUserID[0] != -1) { BRAC_UserCameraControl(m_iUserID[0],!bLastState); bLastState = !bLastState; } } void CBRAnyChatSDKDemoDlg::OnButtonVideoctrl1() { static BOOL bLastState = TRUE; if(m_iUserID[1] != -1) { BRAC_UserCameraControl(m_iUserID[1],!bLastState); bLastState = !bLastState; } } void CBRAnyChatSDKDemoDlg::OnButtonVideoctrl2() { static BOOL bLastState = TRUE; if(m_iUserID[2] != -1) { BRAC_UserCameraControl(m_iUserID[2],!bLastState); bLastState = !bLastState; } } void CBRAnyChatSDKDemoDlg::OnButtonVideoctrl3() { static BOOL bLastState = TRUE; if(m_iUserID[3] != -1) { BRAC_UserCameraControl(m_iUserID[3],!bLastState); bLastState = !bLastState; } } void CBRAnyChatSDKDemoDlg::OnButtonAudioctrl0() { static BOOL bLastState = TRUE; if(m_iUserID[0] != -1) { BRAC_UserSpeakControl(m_iUserID[0],!bLastState); bLastState = !bLastState; } } void CBRAnyChatSDKDemoDlg::OnButtonAudioctrl1() { static BOOL bLastState = TRUE; if(m_iUserID[1] != -1) { BRAC_UserSpeakControl(m_iUserID[1],!bLastState); bLastState = !bLastState; } } void CBRAnyChatSDKDemoDlg::OnButtonAudioctrl2() { static BOOL bLastState = TRUE; if(m_iUserID[2] != -1) { BRAC_UserSpeakControl(m_iUserID[2],!bLastState); bLastState = !bLastState; } } void CBRAnyChatSDKDemoDlg::OnButtonAudioctrl3() { static BOOL bLastState = TRUE; if(m_iUserID[3] != -1) { BRAC_UserSpeakControl(m_iUserID[3],!bLastState); bLastState = !bLastState; } } void CBRAnyChatSDKDemoDlg::OnButtonRecordctrl0() { static BOOL bLastState = FALSE; if(m_iUserID[0] != -1) { BRAC_StreamRecordCtrl(m_iUserID[0],!bLastState,0,0); bLastState = !bLastState; } } void CBRAnyChatSDKDemoDlg::OnButtonRecordctrl1() { static BOOL bLastState = FALSE; if(m_iUserID[1] != -1) { BRAC_StreamRecordCtrl(m_iUserID[1],!bLastState,0,0); bLastState = !bLastState; } } void CBRAnyChatSDKDemoDlg::OnButtonRecordctrl2() { static BOOL bLastState = FALSE; if(m_iUserID[2] != -1) { BRAC_StreamRecordCtrl(m_iUserID[2],!bLastState,0,0); bLastState = !bLastState; } } void CBRAnyChatSDKDemoDlg::OnButtonRecordctrl3() { static BOOL bLastState = FALSE; if(m_iUserID[3] != -1) { BRAC_StreamRecordCtrl(m_iUserID[3],!bLastState,0,0); bLastState = !bLastState; } } void CBRAnyChatSDKDemoDlg::OnButtonSnapshotctrl0() { if(m_iUserID[0] != -1) { BRAC_SnapShot(m_iUserID[0],0,0); } } void CBRAnyChatSDKDemoDlg::OnButtonSnapshotctrl1() { if(m_iUserID[1] != -1) { BRAC_SnapShot(m_iUserID[1],0,0); } } void CBRAnyChatSDKDemoDlg::OnButtonSnapshotctrl2() { if(m_iUserID[2] != -1) { BRAC_SnapShot(m_iUserID[2],0,0); } } void CBRAnyChatSDKDemoDlg::OnButtonSnapshotctrl3() { if(m_iUserID[3] != -1) { BRAC_SnapShot(m_iUserID[3],0,0); } }
/////////////////////////////////////////////////////////////
////////////附件中会贴上整合的源码,敬请留意!/////
//////////////19号西 2011.1.6////////
/////////////QQ839788402///////////
////////////TEL:02038109065////////
- chatqqvideo.rar (1.2 MB)
- 下载次数: 75
发表评论
-
手机视频会议
2012-11-16 14:03 846在这个时代,手机被开发者们所赋予的意义已经远远超出了大众的期望 ... -
视频通讯demo源码
2012-11-09 15:23 1174以下为anychat视频通讯系统中的部分回调函数源码: 具体 ... -
浅谈网络语音技术
2012-08-31 14:35 973浅谈网络语音技术 当我们使用像Sky ... -
手机音视频应用开发(专注于Symbian、iPhone、Android等跨平台音视频应用开发方案)
2012-08-24 14:47 1151一款好的手机应用, 能让用户在第一分钟就爱上他, 一款烂的手 ... -
手机视频通讯开发
2012-08-24 14:46 824如今,3G网络快速发展 ... -
音视频点播直播系统
2012-08-20 10:32 1478音视频点播直 ... -
网络游戏与实时视频结合,拉动网游的进步 .
2012-08-20 09:58 8182011年被称为中国网络 ... -
android视频聊天软件推荐
2012-08-15 17:00 1066正在当前那个社会 ... -
音视频交流服务系统
2012-03-15 16:22 912下面的这个平台是一种视频服务的应用,比如A(客户端)打视频电话 ... -
音视频开发平台
2012-03-15 16:12 840近日,腾讯公司发布了Q ... -
即时通讯开发平台(音视频)
2012-03-15 16:11 935近日,腾讯公司发布了Q ... -
一百年后,人类怎样编程?
2011-03-30 18:00 784很难预测一百年后的人 ... -
500个C语言开发中必须明白的问题
2011-03-16 18:01 952附件中的就是500个C语言开发中必须明白的问题。 有需要的人 ... -
Android编译本地C++程序方法
2011-01-04 15:55 993Android编译本地C++程序方法 在Android ... -
即时通讯 源码(视频)
2010-12-16 16:45 13071. BRAnyChatSDKDemoDlg.cpp : ... -
视频会议源码(客户端和服务器端,包含完整的开发文档)
2010-12-13 17:14 2515一、SDK包概述 AnyChat音视频互动开发平台(SDK ... -
音视频编码库 FFmpeg(源码)
2010-12-13 17:01 1187发布公司:ffmpeg.org授权方式:免费版软件评级:评级标 ... -
音视频编解码的一些源代码
2010-12-13 16:32 1308音视频编解码的一些源代码 (转) 资料名称:音视频编解码的一 ... -
音视频源码 (可用于各种音视频平台)
2010-12-10 17:38 11921. BRAnyChatSDKDemoDlg.cpp : ... -
用于二次开发企业即时通讯源码
2010-12-09 15:28 2266用于二次开发企业即时通讯源码(C++/MFC),现在,做一个普 ...
相关推荐
【标题】"类似QQ的代码vc++"是一个项目,它基于C++编程语言,并使用了Visual C++(vc++)开发环境,旨在实现一个类似于腾讯QQ的即时通讯软件功能。这个项目涵盖了服务器和客户端的代码实现,具备基本的即时通讯特性...
VoIP技术使得通过互联网进行语音通信成为可能,常用于即时通讯软件、视频会议系统等。理解并掌握语音电话编程,开发者能创建高质量、低延迟的语音通信应用。 综上所述,这份《VC++网络通信源程序》资源包提供了深入...
6. 音视频通话:如果模拟软件功能全面,可能还包括语音和视频通话。这需要处理音频和视频编码、解码技术,以及网络流媒体传输。 7. 其他附加功能:如空间动态查看、表情包、个性化设置等,这些都需要开发者根据QQ...
VC++作为Microsoft公司推出的C++集成开发环境,因其强大的性能和丰富的库支持,被广泛用于开发各种应用程序,包括即时通信软件。本文将深入探讨“飞鸽传书”的实现原理,以帮助开发者理解VC++在即时通信领域的应用。...
然而,实际的QQ客户端还涉及到更多高级特性,如音视频通话、群聊、文件传输等,这些都需要进一步的技能和知识。在VC++环境下实现QQ聊天源代码,是对C++编程能力、网络通信技术和软件工程实践的全面检验。
《局域网聊天工具VC++源代码》是一个利用Microsoft Foundation Class (MFC)库开发的本地网络通信应用,它提供了一个可视化的用户界面,让用户在局域网内进行实时聊天和文件传输。这个项目不仅是一个实用的软件示例,...
14. **WEB浏览器应用**:兼容IE浏览器,可以在浏览器上实现音视频即时通讯功能。 15. **音频信号处理**:包含回声消除、噪音抑制、静音检测和自动增益等功能,确保高质全双工语音通话。 16. **Windows服务模式**:...
10. **调试和优化**:在开发过程中,使用VC++的调试工具进行代码调试,确保程序运行无误。同时,对性能进行优化,比如减少内存占用、提升响应速度等,以提供更好的用户体验。 以上就是使用VC++实现QQ界面的一些关键...
除了以上主要功能,MyICQ可能还包含了其他特性,如文件传输、音视频通话等。这些功能的实现会涉及更多高级技术,如P2P网络、多媒体编码解码、流媒体传输等。通过阅读源码,我们可以学习到这些技术在实际项目中的应用...
QQ,作为全球知名的即时通讯软件,其功能包括文字聊天、文件传输、音视频通话等。模仿QQ的源码可以帮助我们了解即时通讯软件的基本架构和功能实现。源码包含了客户端和服务器端两大部分,这是所有网络应用程序的基础...
3. **即时通讯框架**:即时通讯软件的核心在于提供实时的信息交换能力,包括文本聊天、语音通话、视频通话等。该仿QQ框架可能包含了用户登录验证、好友列表管理、消息发送与接收等基本模块。 4. **GUI设计**:在仿...
QQ作为一款广泛使用的即时通讯软件,其功能包括文本聊天、文件传输、音视频通话等,而使用VC++(Visual C++)进行这样的开发,可以充分利用MFC(Microsoft Foundation Classes)库来构建用户界面和实现底层通信逻辑...
在即时通讯中,TCP常用于保证消息的准确传输,而UDP可能用于实时音视频通话等对速度要求较高的场景。 【源码学习要点】 通过分析源码,我们可以学习到: 1. **网络编程**:如何使用Winsock库进行TCP和UDP通信,...
即时通讯软件(Instant Messaging, IM)如QQ或微信,允许用户实时发送消息、文件和进行音视频通话。在VC++中实现即时通讯,开发者需要掌握网络编程(TCP/IP协议栈)、多线程技术、消息队列处理,以及可能的加密和...
【标题】"语音及时交流vc源代码"涉及的是在计算机编程领域中,使用VC++(Visual C++)开发的一个实时语音通信系统。VC++是一种由微软公司开发的集成开发环境,它支持创建Windows应用程序,包括涉及到多媒体功能如...
9. **音视频通话**:如果即时通讯系统还包括音视频通话,那么开发者需要了解和实现相关的音频/视频编码和解码技术,如OPUS、AAC等,并使用合适的库(如DirectShow或WebRTC)来处理音视频流。 10. **服务器架构**:...
在这款小QQ聊天程序中,客户端是用户交互的界面,用户可以在这里输入消息、发送文件、进行音视频通话等操作。客户端通常由一个主界面、会话窗口、联系人列表等组成,通过图形用户界面(GUI)与用户进行交互。客户端...
MSN,即Microsoft Network的即时通讯客户端,曾是全球广泛使用的通讯软件之一,它提供了文字聊天、文件传输、音视频通话等多种功能。 首先,我们需要理解VC++作为开发环境的角色。VC++是微软推出的一种面向对象的...
在视频会议系统的核心组成部分中,VC++ 6.0作为开发工具,提供了丰富的C++类库,使得开发者能够方便地构建复杂的Windows应用程序。而DirectX则是一个由微软开发的多媒体接口技术,包含了图形、音频、输入等多个组件...
这个项目包含了服务端和客户端两部分,使用了TCP(传输控制协议)和UDP(用户数据报协议)这两种网络通信协议来实现数据的传输。它具有添加好友和搜索朋友等基本的社交功能,是学习网络编程和模拟即时通讯应用的良好...