AnyChat開發流程指南
下面列出AnyChatPlatform Core SDK基本開發流程,適用於開發視頻會議系統、語音視訊交談系統、遠程教育平台以及即時通訊平台IM)等。
一、初始化
該部分是首先要完成的,用於設定SDK的一些行為,包括設定對應的回呼函數、設定SDK組件路徑、設定是否產生記錄檔等,通常初始化AnyChat SDK的代碼如下C++):
01.// 開啟關閉)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++):
1.// 串連伺服器
2.BRAC_Connect("211.155.25.90",8906);
3.// 登入系統
4.BRAC_Login("testuser","",0);
串連伺服器與登入系統都是一個非同步過程,調用後會立即返回,其中:
a、串連伺服器成功,或是失敗,將會觸發非同步訊息
b、登入系統成功,或是失敗,將會觸發非同步訊息
所以應用程式需要響應這些非同步訊息才能知道串連伺服器、登入系統是否成功。
登入系統成功後,如果需要實現即時通訊應用中的好友名單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++):
1.// 進入房間
2.BRAC_EnterRoom(1,"",0);
房間由伺服器動態管理,由32位的房間ID號來唯一標示,當用戶端指定的房間ID號不存在時,伺服器將會自動建立。進入房間也是一個非同步過程,是否成功將會觸發非同步訊息,進入房間成功後,伺服器會把當前房間的線上使用者列表傳給用戶端,傳輸完成後,將會觸發非同步訊息該訊息只觸發一次),只有收到伺服器的線上使用者列表後,才能對房間內的使用者進行音視頻的相關操作。
當自己進入房間成功,且收到伺服器的線上使用者訊息後,有新的使用者進入房間,或是老使用者離開房間,將會觸發非同步訊息,這樣自己便知道誰進入,或是離開了房間。
1、開啟自己的音視頻
進入房間成功之後,便可以開啟自己的音視頻裝置,通常調用代碼如下C++):
1.// 開啟自己的視頻裝置
2.BRAC_UserCameraControl(-1,TRUE);
3.// 開啟自己的音訊裝置
4.BRAC_UserSpeakControl(-1,TRUE);
開啟自己的裝置後,並不會立即上傳音視頻流,只有當其它使用者請求自己的音視頻資料時可單獨請求音頻流,或視頻流)才對外傳輸,開啟自己的音視頻裝置,預設是按伺服器的配置資訊來初始化裝置如採樣解析度、視訊框架率、音訊採樣頻率等),如需要在用戶端程式中調節音、視頻品質。
2、請求其它使用者的音視頻
如果需要顯示其它使用者的音視頻,則必須在收到房間使用者列表訊息後,請求對方的音視頻流,然後對方才將音視頻流傳輸過來,通常請求其它使用者的音視頻資料調用代碼如下C++):
1.// 請求對方的視頻流
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”標誌,並且調用了,則SDK內部將會把視頻顯示到指定的表單的指定位置在指定位置上自動迭加一個視頻視窗);
b)如果在初始化時設定了“BRAC_FUNC_VIDEO_CBDATA”標誌,則SDK會將解碼後的視頻資料RGB、YUV)通過回呼函數回調給上層應用,由上層應用自己來繪製,或渲染,該模式適合於DirectX、HGE等沒有視窗模式下的應用程式,或是上層應用需要對視頻進行特殊處理的場合,如迭加文字、logo等。
4、文字互動
成功進入房間後,便可以調用API介面向指定使用者,或是房間中的所有使用者發送文字訊息:
1.// 發送文字訊息
2.CString strInput = "helloworld";
3.BRAC_SendTextMessage(-1,FALSE,strInput.GetBuffer(0),strInput.GetLength());
其它使用者收到自己發送的文字訊息後,便會觸發回呼函數,通過處理回調訊息,然後將收到的文字訊息顯示在介面上,便可實現文字的互動。
5、商務邏輯處理
AnyChat SDK內建的基本邏輯是:當自己的音視頻裝置開啟後,別的使用者有請求,便會將流媒體資料轉送給對方,而沒有任何何商務邏輯。
a)如要實現視頻會議系統,則使用者進入房間後,就需要知道誰是主持人,然後開啟主持人的視頻;
b)如要實現視訊交談系統,則使用者進入房間後,就需要知道當前房間有幾個公麥,誰在公麥上,然後開啟對應公麥使用者的視頻等;
c)……
這些商務邏輯需要與伺服器端的“SDKFilter Plus”或“AnyChatServer SDK”互相配合來實現,具體的實現方案可參考SDK包中的:doc\server\目錄下的《AnyChat Server SDK 開發指南》第6章節。
四、釋放資源
與前面串連伺服器、登入系統、進入房間對應的,退出系統的過程是:離開房間、登出系統、釋放資源,通常調用代碼如下C++):
1.// 離開房間
2.BRAC_LeaveRoom(-1);
3.// 登出系統將關閉網路連接)
4.BRAC_Logout();
5.// 釋放資源
6.BRAC_Release();
離開房間後,可以進入新的房間,系統登出之後,可以再次調用串連伺服器的API介面,但是釋放資源後,SDK將不再工作。
需要特別注意一下釋放資源的時機。
Windows平台AnyChat視頻顯示
1、如何顯示本地視頻,或是其它電腦上的視頻?
a)AnyChat的用戶端必須初始化、登入系統、進入房間成功之後,才能顯示本地視頻或是其它使用者的視頻。
b)AnyChat有兩種方式來顯示視頻,分別是:自動顯示BRAC_FUNC_VIDEO_AUTODISP)、回調視頻資料BRAC_FUNC_VIDEO_CBDATA),應用程式需要在初始化BRAC_InitSDK)時設定相關的標誌來告訴AnyChat如何處理視頻的顯示。
當設定了自動顯示BRAC_FUNC_VIDEO_AUTODISP)時,應用程式需要設定視頻顯示位置BRAC_SetVideoPos),當開啟本機使用者的視頻,或是請求遠端使用者的視頻時,AnyChat內部會自動將視頻顯示在指定的位置;
如果沒有設定自動顯示標誌,而只設定了回調視頻資料BRAC_FUNC_VIDEO_CBDATA)標誌時,AnyChat內部不會顯示視頻,而是將視頻資料通過回調的方式提交給應用程式,由應用程式自己來繪製;
c)當使用者使用API介面BRAC_UserCameraControl)開啟本地網路攝影機後,本機電腦的視頻即可顯示出來;
d)當使用者使用API介面BRAC_UserCameraControl)請求其它使用者的視頻資料時,只有該使用者開啟自己的網路攝影機之後,本機電腦才能收到對方使用者的視頻;
2、什麼是視頻顯示驅動,如何選擇?
Windows平台有多種方式來實現視頻的顯示,常見的有GDI繪圖和DirectShow兩種模式。當設定AnyChat自動顯示視頻標誌時,應用程式可以在這兩種模式之間進行選擇,視頻顯示驅動的選擇需要在初始化BRAC_InitSDK)成功之後設定,下面的代碼示範了選擇DirectShow顯示驅動:
1.// 選擇AnyChat顯示驅動
2.DWORD dwVideoDriver =BRAC_VSD_DIRECTSHOW;
3.BRAC_SetSDKOption(BRAC_SO_VIDEOSHOW_DRIVERCTRL,(constchar*)&dwVideoDriver, sizeof(DWORD));
AnyChat為了簡化應用程式開發流程,同時也為了相容更早期的版本,預設採用GDI繪圖方式來顯示視頻;GDI繪圖方式適合分辯率不大於CIF352x288),同時幀率低於20FPS的視頻顯示;DirectShow顯示模式適合高解析度、高幀率的視頻顯示。
DirectShow顯示模式在高視頻品質下更節約資源;
(*註:視頻顯示驅動選擇功能為AnyChat Platform CoreSDK V4.0版本新增功能)
3、顯示的視頻為何有些變形,如何設定?
當視頻顯示地區的大小與視頻的原始大小不成比例時,所顯示的視頻將會變形,所以要保證顯示的視頻不變形,則必須保證視頻顯示地區與視頻的原始大小成正比關係;
通過WM_GV_VIDEOSIZECHG訊息V4.0版本新增)可以知道每一個使用者當前原始視頻的大小,應用程式可以根據原始視頻的大小來確定視頻顯示地區的大小,也可以通過APIBRAC_QueryUserState)來擷取使用者當前的視頻大小;
當使用者進入房間時,AnyChat內部會每一個線上使用者觸發一次WM_GV_VIDEOSIZECHG訊息;
當使用者修改視頻採集解析度時,房間內所有使用者都將收到該使用者的WM_GV_VIDEOSIZECHG訊息;
4、為何有時視頻被其它視窗覆蓋,或是最小化後視頻被遮擋,不能自動重新整理?
這主要出現在DirectShow顯示模式下,主要原因是應用程式介面重繪之後,底層的DirectShow沒有獲得重繪的訊息通知,所以導致視頻被遮擋,解決方案是響應視窗的WM_PAINT訊息,在訊息處理函數中調用BRAC_RepaintVideo進行視頻的重繪。
AnyChat預設的GDI繪圖模式下,不存在該問題。
AnyChat底層的DirectShow是採用VMR的Windowless模式進行視頻顯示,有關該問題的詳細資料可參考微軟官方的開發文檔。