视频聊天室开发详解
?互聯(lián)網(wǎng)的不斷發(fā)展,各種新技術(shù)的興起,原本做管理軟件的我也逐漸轉(zhuǎn)向從事著互聯(lián)網(wǎng)相關(guān)的運(yùn)營(yíng)產(chǎn)品的開發(fā)。尤其是目前抄得最火熱的音視頻互動(dòng)平臺(tái)技術(shù),今天我先列出最基本開發(fā)流程,適用于開發(fā)視頻會(huì)議系統(tǒng)、語音視頻聊天系統(tǒng)、遠(yuǎn)程教育平臺(tái)以及即時(shí)通訊平臺(tái)(IM)等。希望對(duì)喜歡這方面的朋友有所幫助。同時(shí)歡迎各大高手參與討論,相互交流、學(xué)習(xí)。
首先,知其然,先看看如何開始工作。
下載:http://anychat.storage.aliyun.com/AnyChatCoreSDK_Win32(MBCS)_V4.5.zip
一、初始化
該部分是首先要完成的,包括設(shè)置對(duì)應(yīng)的回調(diào)函數(shù)、設(shè)置SDK組件路徑、設(shè)置是否產(chǎn)生日志文件等,通常初始化的代碼如下(C++):
01.// 打開(關(guān)閉)的日志記錄功能 02.BRAC_ActiveCallLog(TRUE); 03.?????? 04.// 設(shè)置核心組件所在目錄 05.CHAR szCoreSDKPath[MAX_PATH] = {0}; 06.GetModuleFileName(NULL,szCoreSDKPath,sizeof(szCoreSDKPath)); 07.(strrchr(szCoreSDKPath,'\\'))[1] = 0;? 08.BRAC_SetSDKOption(BRAC_SO_CORESDK_PATH,szCoreSDKPath,strlen(szCoreSDKPath)); 09.?????? 10.// 根據(jù)BRAC_InitSDK的第二個(gè)參數(shù):dwFuncMode,來告訴該如何處理相關(guān)的任務(wù)(詳情請(qǐng)參考開發(fā)文檔) 11.DWORD dwFuncMode = BRAC_FUNC_VIDEO_CBDATA | BRAC_FUNC_AUDIO_AUTOPLAY | BRAC_FUNC_CHKDEPENDMODULE | BRAC_FUNC_AUDIO_VOLUMECALC | BRAC_FUNC_NET_SUPPORTUPNP | BRAC_FUNC_FIREWALL_OPEN | 12.BRAC_FUNC_AUDIO_AUTOVOLUME | BRAC_FUNC_CONFIG_LOCALINI; 13.BRAC_InitSDK(this->GetSafeHwnd()/*NULL*/,dwFuncMode); 14.?????? 15.// 設(shè)置錄像臨時(shí)文件保存路徑 16.CHAR szRecordDirectory[MAX_PATH] = {0}; 17.::GetModuleFileName(NULL,szRecordDirectory,MAX_PATH); 18.(strrchr(szRecordDirectory,'\\'))[1] = 0;? 19.strcat(szRecordDirectory,"Record"); 20.BRAC_SetSDKOption(BRAC_SO_RECORD_TMPDIR,szRecordDirectory,strlen(szRecordDirectory)); 21.?? 22.// 設(shè)置錄像文件質(zhì)量參數(shù) 23.DWORD dwVideoBitrate = 200 * 1000;? // 200kbps 24.BRAC_SetSDKOption(BRAC_SO_RECORD_VIDEOBR,(PCHAR)&dwVideoBitrate,sizeof(DWORD)); 25.DWORD dwAudioBitrate = 96 * 1000;?? // 96kbps 26.BRAC_SetSDKOption(BRAC_SO_RECORD_AUDIOBR,(PCHAR)&dwAudioBitrate,sizeof(DWORD)); 27.?????? 28.// 設(shè)置快照臨時(shí)文件保存路徑 29.CHAR szSnapShotDirectory[MAX_PATH] = {0}; 30.::GetModuleFileName(NULL,szSnapShotDirectory,MAX_PATH); 31.(strrchr(szSnapShotDirectory,'\\'))[1] = 0;? 32.strcat(szSnapShotDirectory,"SnapShot"); 33.BRAC_SetSDKOption(BRAC_SO_SNAPSHOT_TMPDIR,szSnapShotDirectory,strlen(szSnapShotDirectory)); 34.?????? 35.// 設(shè)置臨時(shí)文件路徑 36.CHAR szTempPath[MAX_PATH] = {0}; 37.::GetModuleFileName(NULL,szTempPath,MAX_PATH); 38.(strrchr(szTempPath,'\\'))[1] = 0;? 39.strcat(szTempPath,"Temp"); 40.BRAC_SetSDKOption(BRAC_SO_CORESDK_TMPDIR,szTempPath,strlen(szTempPath)); 41.?? 42.// 啟用音頻自動(dòng)參數(shù)功能(默認(rèn)關(guān)閉) 43.DWORD bAudioAutoParam = TRUE; 44.BRAC_SetSDKOption(BRAC_SO_AUDIO_AUTOPARAM,(PCHAR)&bAudioAutoParam,sizeof(DWORD));二、登錄系統(tǒng)
當(dāng)?shù)谝徊匠跏蓟瓿芍?#xff0c;便可以連接服務(wù)器、驗(yàn)證用戶身份。通常調(diào)用代碼如下(C++):
1.// 連接服務(wù)器 2.BRAC_Connect("211.155.25.90",8906); 3.// 登錄系統(tǒng) 4.BRAC_Login("testuser","",0);連接服務(wù)器與登錄系統(tǒng)都是一個(gè)異步的過程,調(diào)用后會(huì)立即返回,其中:
a、連接服務(wù)器成功,或是失敗,將會(huì)觸發(fā)異步消息:網(wǎng)絡(luò)連接消息
b、登錄系統(tǒng)成功,或是失敗,將會(huì)觸發(fā)異步消息:登錄系統(tǒng)消息
所以應(yīng)用程序需要響應(yīng)這些異步消息(或處理:異步消息通知回調(diào)函數(shù))才能知道連接服務(wù)器、登錄系統(tǒng)是否成功。
登錄系統(tǒng)成功后,如果需要實(shí)現(xiàn)即時(shí)通訊應(yīng)用中的好友列表(AnyChat默認(rèn)沒有實(shí)現(xiàn)),則需要利用AnyChat的擴(kuò)展API接口與Server SDK來配合實(shí)現(xiàn),登錄系統(tǒng)成功后,服務(wù)器會(huì)返回一個(gè)32位的用戶ID,如果登錄時(shí)沒有傳入密碼參數(shù),則系統(tǒng)會(huì)認(rèn)為是游客登錄,并分配一個(gè)獨(dú)立的用戶ID(如-1、-2等),如果登錄時(shí)傳入了密碼參數(shù),則登錄請(qǐng)求將會(huì)交給“SDK Filter Plus”接口,或“Server SDK”對(duì)應(yīng)的接口,用戶可開發(fā)一個(gè)自己的服務(wù)器插件“SDK Filter Plus”,或是調(diào)用“Server SDK”所對(duì)應(yīng)的API來處理用戶身份驗(yàn)證的請(qǐng)求,完成對(duì)用戶ID的管理,實(shí)現(xiàn)與第三方系統(tǒng)的互聯(lián)互通,詳細(xì)內(nèi)容可參考SDK包中的:doc\server\目錄下的相關(guān)文檔。
三、進(jìn)入房間
在第二步登錄系統(tǒng)成功之后,就可以進(jìn)入房間,因?yàn)橹挥性诜块g中,才能完成語音和視頻的交互。通常調(diào)用代碼如下(C++):
1.// 進(jìn)入房間 2.BRAC_EnterRoom(1,"",0);房間由服務(wù)器動(dòng)態(tài)管理,由32位的房間ID號(hào)來唯一標(biāo)示,當(dāng)客戶端指定的房間ID號(hào)不存在時(shí),服務(wù)器將會(huì)自動(dòng)創(chuàng)建。進(jìn)入房間也是一個(gè)異步的過程,是否成功將會(huì)觸發(fā)異步消息:自己進(jìn)入房間消息,進(jìn)入房間成功后,服務(wù)器會(huì)把當(dāng)前房間的在線用戶列表傳給客戶端,傳輸完成后,將會(huì)觸發(fā)異步消息: 當(dāng)前房間在線用戶消息(該消息只觸發(fā)一次),只有收到服務(wù)器的在線用戶列表后,才能對(duì)房間內(nèi)的用戶進(jìn)行音視頻的相關(guān)操作。
當(dāng)自己進(jìn)入房間成功,且收到服務(wù)器的在線用戶消息后,有新的用戶進(jìn)入房間,或是老用戶離開房間,將會(huì)觸發(fā)異步消息:用戶進(jìn)入(離開)房間消息,這樣自己便知道誰進(jìn)入,或是離開了房間。
1、打開自己的音視頻
進(jìn)入房間成功之后,便可以打開自己的音視頻設(shè)備,通常調(diào)用代碼如下(C++):
1.// 打開自己的視頻設(shè)備
2.BRAC_UserCameraControl(-1,TRUE); 3.// 打開自己的音頻設(shè)備 4.BRAC_UserSpeakControl(-1,TRUE);打開自己的設(shè)備后,并不會(huì)立即上傳音視頻流,只有當(dāng)其它用戶請(qǐng)求自己的音視頻數(shù)據(jù)時(shí)(可單獨(dú)請(qǐng)求音頻流,或視頻流)才對(duì)外傳輸,打開自己的音視頻設(shè)備,默認(rèn)是按服務(wù)器的配置信息來初始化設(shè)備(如采樣分辨率、視頻幀率、音頻的采樣頻率等),如需要在客戶端程序中調(diào)節(jié)音、視頻質(zhì)量,
2、請(qǐng)求其它用戶的音視頻
如果需要顯示其它用戶的音視頻,則必須在收到房間用戶列表消息后,請(qǐng)求對(duì)方的音視頻流,然后對(duì)方才將音視頻流傳輸過來,通常請(qǐng)求其它用戶的音視頻數(shù)據(jù)調(diào)用代碼如下(C++):
1.// 請(qǐng)求對(duì)方的視頻流
2.BRAC_UserCameraControl(dwUserId,TRUE); 3.// 請(qǐng)求對(duì)方的音頻流 4.BRAC_UserSpeakControl(dwUserId,TRUE);數(shù)據(jù)傳輸優(yōu)先P2P方式,只有當(dāng)P2P不通時(shí),才由服務(wù)器轉(zhuǎn)發(fā),P2P的NAT打洞過程,以及數(shù)據(jù)流傳輸策略均由服務(wù)器控制,只要有請(qǐng)求,而且對(duì)方已打開了自己的音視頻設(shè)備,則就能收到對(duì)方的音視頻流數(shù)據(jù)。
3、音視頻的播放與顯示
當(dāng)收到其它用戶的音頻數(shù)據(jù)后:
a)如果在初始化時(shí)設(shè)置了“BRAC_FUNC_AUDIO_AUTOPLAY”標(biāo)志,則SDK內(nèi)部將會(huì)自動(dòng)播放,自動(dòng)混音;
b)如果在初始化時(shí)設(shè)置了“BRAC_FUNC_AUDIO_CBDATA”標(biāo)志,則SDK會(huì)將解碼后的音頻數(shù)據(jù)(PCM格式)通過回調(diào)函數(shù)回調(diào)給上層應(yīng)用。
當(dāng)收到其它用戶的視頻數(shù)據(jù)后:
a)如果在初始化時(shí)設(shè)置了“BRAC_FUNC_VIDEO_AUTODISP”標(biāo)志,并且調(diào)用了API: BRAC_SetVideoPos,則SDK內(nèi)部將會(huì)把視頻顯示到指定的窗體的指定位置(在指定位置上自動(dòng)迭加一個(gè)視頻窗口);
b)如果在初始化時(shí)設(shè)置了“BRAC_FUNC_VIDEO_CBDATA”標(biāo)志,則SDK會(huì)將解碼后的視頻數(shù)據(jù)(RGB、YUV)通過回調(diào)函數(shù)回調(diào)給上層應(yīng)用,由上層應(yīng)用自己來繪制,或渲染,該模式適合于DirectX、HGE等沒有窗口模式下的應(yīng)用程序,或是上層應(yīng)用需要對(duì)視頻進(jìn)行特殊處理的場(chǎng)合,如迭加文字、logo等。
4、文字交互
成功進(jìn)入房間后, 便可以調(diào)用API接口向指定用戶,或是房間中的所有用戶發(fā)送文字消息:
1.// 發(fā)送文字消息 2.CString strInput = "hello world"; 3.BRAC_SendTextMessage(-1,FALSE,strInput.GetBuffer(0),strInput.GetLength());其它用戶收到自己發(fā)送的文字消息后,便會(huì)觸發(fā)回調(diào)函數(shù):文字消息回調(diào)函數(shù),通過處理回調(diào)消息,然后將收到的文字消息顯示在界面上,便可實(shí)現(xiàn)文字的交互。
5、業(yè)務(wù)邏輯處理?
AnyChat SDK內(nèi)置的基本邏輯是:當(dāng)自己的音視頻設(shè)備打開后,別的用戶有請(qǐng)求,便會(huì)將流媒體數(shù)據(jù)傳輸給對(duì)方,而沒有任何何業(yè)務(wù)邏輯。
a)如要實(shí)現(xiàn)視頻會(huì)議系統(tǒng),則用戶進(jìn)入房間后,就需要知道誰是主持人,然后打開主持人的視頻;
b)如要實(shí)現(xiàn)視頻聊天系統(tǒng),則用戶進(jìn)入房間后,就需要知道當(dāng)前房間有幾個(gè)公麥,誰在公麥上,然后打開對(duì)應(yīng)公麥用戶的視頻等;
c)……
這些業(yè)務(wù)邏輯需要與服務(wù)器端的“SDK Filter Plus”或“AnyChat Server SDK”互相配合來實(shí)現(xiàn),具體的實(shí)現(xiàn)方案可參考SDK包中的:doc\server\目錄下的《AnyChat Server SDK 開發(fā)指南》第6章節(jié)。?
四、釋放資源
與前面連接服務(wù)器、登錄系統(tǒng)、進(jìn)入房間對(duì)應(yīng)的,退出系統(tǒng)的過程是:離開房間、注銷系統(tǒng)、釋放資源,通常調(diào)用代碼如下(C++):
1.// 離開房間
2.BRAC_LeaveRoom(-1); 3.// 注銷系統(tǒng)(將關(guān)閉網(wǎng)絡(luò)連接) 4.BRAC_Logout(); 5.// 釋放資源 6.BRAC_Release();離開房間后,可以進(jìn)入新的房間,系統(tǒng)注銷之后,可以再次調(diào)用連接服務(wù)器的API接口,但是釋放資源后,將不再工作。
需要特別注意一下釋放資源的時(shí)機(jī)。
完了之后,我們就來知其所以然了,如果你喜歡這個(gè)項(xiàng)目,請(qǐng)繼續(xù)關(guān)注。也可加QQ:992139738
總結(jié)
- 上一篇: 光大信用卡看重负债吗?负债高可以这么办卡
- 下一篇: C语言void关键字