天天看點

音視訊即時通訊的基本開發流程

面對現在的即時通訊應用軟體的崛起,很多開發者也是竭盡所能在這方面進行研究和學習!今天我在這裡介紹一款音視訊即時通訊的開發流程。

下面列出AnyChat Platform Core SDK基本開發流程,适用于開發視訊會議系統、語音視訊聊天系統、遠端教育平台以及即時通訊平台(IM)等。

一、初始化

該部分是首先要完成的,用于設定SDK的一些行為,包括設定對應的回調函數、設定SDK元件路徑、設定是否産生日志檔案等,通常初始化AnyChat SDK的代碼如下(C++):

// 打開(關閉)SDK的日志記錄功能 
02.BRAC_ActiveCallLog(TRUE); 
03.      
04.// 設定SDK核心元件所在目錄 
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.// 根據BRAC_InitSDK的第二個參數:dwFuncMode,來告訴SDK該如何處理相關的任務(詳情請參考開發文檔) 
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.// 設定錄像臨時檔案儲存路徑 
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.// 設定錄像檔案品質參數 
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.// 設定快照臨時檔案儲存路徑 
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.// 設定SDK臨時檔案路徑 
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.// 啟用音頻自動參數功能(預設關閉) 
43.DWORD bAudioAutoParam = TRUE; 
44.BRAC_SetSDKOption(BRAC_SO_AUDIO_AUTOPARAM,(PCHAR)&bAudioAutoParam,sizeof(DWORD));
      

二、登入系統

當第一步初始化完成之後,便可以連接配接伺服器、驗證使用者身份。通常調用代碼如下(C++):

// 連接配接伺服器 
2.BRAC_Connect("211.155.25.90",8906); 
3.// 登入系統 
4.BRAC_Login("testuser","",0);
      

連接配接伺服器與登入系統都是一個異步的過程,調用後會立即傳回,其中:

a、連接配接伺服器成功,或是失敗,将會觸發異步消息:115. 網絡連接配接消息

b、登入系統成功,或是失敗,将會觸發異步消息:116. 登入系統消息

是以應用程式需要響應這些異步消息(或處理:145. 異步消息通知回調函數)才能知道連接配接伺服器、登入系統是否成功。

登入系統成功後,如果需要實作即時通訊應用中的好友清單(AnyChat預設沒有實作),則需要利用AnyChat的擴充API接口與Server SDK來配合實作,具體實作方案可參考SDK包中的:doc\server\目錄下的《AnyChat Server SDK 開發指南》第6章節。

登入系統成功後,伺服器會傳回一個32位的使用者ID,如果登入時沒有傳入密碼參數,則系統會認為是遊客登入,并配置設定一個獨立的使用者ID(如-1、-2等),如果登入時傳入了密碼參數,則登入請求将會交給“SDK Filter Plus”接口,或“Server SDK”對應的接口,使用者可開發一個自己的伺服器插件“SDK Filter Plus”,或是調用“Server SDK”所對應的API來處理使用者身份驗證的請求,完成對使用者ID的管理,實作與第三方系統的互聯互通,詳細内容可參考SDK包中的:doc\server\目錄下的相關文檔。

三、進入房間

在第二步登入系統成功之後,就可以進入房間,因為隻有在房間中,才能完成語音和視訊的互動。通常調用代碼如下(C++):

// 進入房間 
2.BRAC_EnterRoom(1,"",0);
      

房間由伺服器動态管理,由32位的房間ID号來唯一标示,當用戶端指定的房間ID号不存在時,伺服器将會自動建立。進入房間也是一個異步的過程,是否成功将會觸發異步消息:117. 自己進入房間消息,進入房間成功後,伺服器會把目前房間的線上使用者清單傳給用戶端,傳輸完成後,将會觸發異步消息:121. 目前房間線上使用者消息(該消息隻觸發一次),隻有收到伺服器的線上使用者清單後,才能對房間内的使用者進行音視訊的相關操作。

當自己進入房間成功,且收到伺服器的線上使用者消息後,有新的使用者進入房間,或是老使用者離開房間,将會觸發異步消息:119. 使用者進入(離開)房間消息,這樣自己便知道誰進入,或是離開了房間。

1、打開自己的音視訊

進入房間成功之後,便可以打開自己的音視訊裝置,通常調用代碼如下(C++):

// 打開自己的視訊裝置 
2.BRAC_UserCameraControl(-1,TRUE); 
3.// 打開自己的音頻裝置 
4.BRAC_UserSpeakControl(-1,TRUE);
      

打開自己的裝置後,并不會立即上傳音視訊流,隻有當其它使用者請求自己的音視訊資料時(可單獨請求音頻流,或視訊流)才對外傳輸,參考:174. AnyChat在打開音頻裝置的同時會自動釋出視訊資料嗎?,打開自己的音視訊裝置,預設是按伺服器的配置資訊來初始化裝置(如采樣分辨率、視訊幀率、音頻的采樣頻率等),如需要在用戶端程式中調節音、視訊品質,參考:187. 如何修改音頻通信品質?、175. 如何設定AnyChat視訊品質?

2、請求其它使用者的音視訊

如果需要顯示其它使用者的音視訊,則必須在收到房間使用者清單消息後,請求對方的音視訊流,然後對方才将音視訊流傳輸過來,通常請求其它使用者的音視訊資料調用代碼如下(C++):

// 請求對方的視訊流 
2.BRAC_UserCameraControl(dwUserId,TRUE); 
3.// 請求對方的音頻流 
4.BRAC_UserSpeakControl(dwUserId,TRUE);
      

資料傳輸優先P2P方式,隻有當P2P不通時,才由伺服器轉發,P2P的NAT打洞過程,以及資料流傳輸政策均由伺服器控制,隻要有請求,而且對方已打開了自己的音視訊裝置,則就能收到對方的音視訊流資料。

3、音視訊的播放與顯示

當收到其它使用者的音頻資料後:

a)如果在初始化時設定了“BRAC_FUNC_AUDIO_AUTOPLAY”标志,則SDK内部将會自動播放,自動混音;

b)如果在初始化時設定了“BRAC_FUNC_AUDIO_CBDATA”标志,則SDK會将解碼後的音頻資料(PCM格式)通過回調函數回調給上層應用。

當收到其它使用者的視訊資料後:

a)如果在初始化時設定了“BRAC_FUNC_VIDEO_AUTODISP”标志,并且調用了API:31. BRAC_SetVideoPos,則SDK内部将會把視訊顯示到指定的窗體的指定位置(在指定位置上自動疊加一個視訊視窗);

b)如果在初始化時設定了“BRAC_FUNC_VIDEO_CBDATA”标志,則SDK會将解碼後的視訊資料(RGB、YUV)通過回調函數回調給上層應用,由上層應用自己來繪制,或渲染,該模式适合于DirectX、HGE等沒有視窗模式下的應用程式,或是上層應用需要對視訊進行特殊處理的場合,如疊加文字、logo等。

4、文字互動

成功進入房間後, 便可以調用API接口向指定使用者,或是房間中的所有使用者發送文字消息:

// 發送文字消息 
2.CString strInput = "hello world"; 
3.BRAC_SendTextMessage(-1,FALSE,strInput.GetBuffer(0),strInput.GetLength());
      

其它使用者收到自己發送的文字消息後,便會觸發回調函數:132. 文字消息回調函數,通過處理回調消息,然後将收到的文字消息顯示在界面上,便可實作文字的互動。

5、業務邏輯處理

AnyChat SDK内置的基本邏輯是:當自己的音視訊裝置打開後,别的使用者有請求,便會将流媒體資料傳輸給對方,而沒有任何何業務邏輯。

a)如要實作視訊會議系統,則使用者進入房間後,就需要知道誰是主持人,然後打開主持人的視訊;

b)如要實作視訊聊天系統,則使用者進入房間後,就需要知道目前房間有幾個公麥,誰在公麥上,然後打開對應公麥使用者的視訊等;

c)……

這些業務邏輯需要與伺服器端的“SDK Filter Plus”或“AnyChat Server SDK”互相配合來實作,具體的實作方案可參考SDK包中的:doc\server\目錄下的《AnyChat Server SDK 開發指南》第6章節。

四、釋放資源

與前面連接配接伺服器、登入系統、進入房間對應的,退出系統的過程是:離開房間、登出系統、釋放資源,通常調用代碼如下(C++):

// 離開房間 
2.BRAC_LeaveRoom(-1); 
3.// 登出系統(将關閉網絡連接配接) 
4.BRAC_Logout(); 
5.// 釋放資源 
6.BRAC_Release();
      

離開房間後,可以進入新的房間,系統登出之後,可以再次調用連接配接伺服器的API接口,但是釋放資源後,SDK将不再工作。