引言:《手把手教你搭建音視頻通信系統(tǒng)》專輯將推送三篇文章,分別涉及iOS、Android和Windows版本的搭建,涵蓋范圍廣,此外用到的是現(xiàn)已開源的服務器代碼和免費的SDK,感興趣的小伙伴們完全可以自己嘗試搭建呦!
現(xiàn)在市面上有許多音視頻通信軟件,比如Facetime。你是否想過開發(fā)一款獨屬于自己的音視頻通信軟件?在iOS開發(fā)中,音視頻通訊開發(fā)一直比較困難:昂貴的開發(fā)成本、較高的技術門檻讓很多開發(fā)者和公司望而卻步。
今天圖鴨君就和你說一下,如何從O開始,搭建一個完整的IOS音視頻通信系統(tǒng)。文中涉及的服務器配置問題,可以到圖鴨官網(wǎng)查看相關文檔。
一、準備
首先在圖鴨官網(wǎng):http://tucodec.com 進行注冊,獲得SDK中所需要的AppKey、AppSecret,注冊登錄后如下圖所示:

其次到開發(fā)者里選擇下載iOS中所需SDK。

最后解壓,如下圖所示:
1、解壓voipDemo.zip,如圖4所示:

把TYVoIPiOSSDK.framework拿出來,該framework即為圖鴨音視頻SDK,導入到所需的iOS項目中,有時候導入framework工程沒有自動添加該SDK的framework路徑,檢查方法:target—>Build Settings—>Search Path,在Framework Search Path中加入TYVoIPiOSSDK.framework的路徑。由于SDK是與C++混編的,所以只要使用到SDK中文件的 .m 文件都需要改成 .mm 后綴名,如圖5所示:

在使用TYVoIPiOSSDK.framework庫的時候,需要導入下面這些框架:

完成上述操作后,我們的音視頻通訊App所需的大體框架已經(jīng)完成啦。
之后就是碼代碼,完成系統(tǒng)UI界面繪制和用戶之間通訊的邏輯操作。
在圖鴨科技提供的SDK中,我們可以看到對外只有兩個頭文件,可見快速集成音視頻通信并不是那么復雜。如圖7所示:

二. 頭文件定義:
<1> TYVoipDarwinManager.h文件,該文件定義了對外提供的類和協(xié)議。以下3個是該文件中核心類與協(xié)議。
(1) TYVoipDarwinManager : VoIP主要功能以及管理類
(2) TYVoipVideoData : 接收以及發(fā)送視頻數(shù)據(jù)模型
(3) TYVoipDelegate : VoIP的代理
<2> TYVoipRender.h文件:提供渲染用戶視圖View。
了解上述主要接口文件及其定義后,我們來了解SDK中的通信原理:在SDK中,所有用戶都以通訊節(jié)點的形式存在,作為節(jié)點的用戶都擁有自己唯一的表示—— UserID ,整個SDK會根據(jù)每個用戶的UserID來進行通訊。
例如,甲和乙之間進行通訊,假設甲的UserID為401,乙的UserID為402,甲登錄后向乙發(fā)送我要和你開視頻,乙登錄后向甲發(fā)送我要和你開視頻,甲開始渲染乙的視圖,乙開始渲染甲的視圖 。完成上述所有操作后,甲乙建立通訊。
三. 完整的SDK使用步驟簡介:
<1>配置voip,在程序啟動的時候調用:
[[TYVoipManager share] configVoip];
<2>登錄轉發(fā)服務器(登錄一次即可):
[[TYVoipDarwinManager sharedVoip]? loginRelayServer:ip
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?serverPort:port
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?sessionId:sessionId
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?userId:_401
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? AppKey:AppKey
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? AppSecret:AppSecret];
<3>設置voip代理和開始voip:
[[TYVoipDarwinManager sharedVoip] setDelegate:self];
[[TYVoipDarwinManager sharedVoip] startCallWithUserId:401];
<4>根據(jù)邏輯,添加(刪除)需要通話的節(jié)點:
[[TYVoipDarwinManager sharedVoip] addClientNode:402];
//[[TYVoipDarwinManager sharedVoip] removeClientNode:402];
<5>不需要通話時,停止voip:
//關閉voip
[[TYVoipDarwinManager sharedVoip] stopCall];
//清空現(xiàn)有的連接節(jié)點(不再接收節(jié)點的數(shù)據(jù))
[[TYVoipDarwinManager sharedVoip] clearClientNodeList];
<6>根據(jù)具體的業(yè)務邏輯重復步驟3、4、5
<7>在程序結束時銷毀voip
[[TYVoipDarwinManager sharedVoip] destroy];
四、部分代碼解釋:(從用戶甲的實現(xiàn)代碼來解釋)
TYRenderView * preView; //渲染甲的視圖
TYRenderView * otherView;? //渲染乙的視圖
<1>登錄操作:
甲(UserID:401)登錄操作,返回值為是否登錄成功(非0即為成功):
-(BOOL)login{
? ? NSString * ip = @"**.**.**.**";//所需轉發(fā)服務器地址
? ? uint16_t port = 0;
? ? int sessionId = 0;
????uint32_t AppKey = 0;//填寫剛才申請的AppKey與AppSecret
????uint32_t AppSecret = 0;
????int res = [[TYVoipDarwinManager sharedVoip] loginRelayServer:ip
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? serverPort:port
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? sessionId:sessionId
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? userId:_401
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? AppKey:AppKey
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? AppSecret:AppSecret];
????return res;
}
<2>連接操作
甲連接乙操作:
-(void)startVoip{
????//設置通訊中所需代理涉及到實現(xiàn)的方法下面有解釋
????[[TYVoipDarwinManager sharedVoip] setDelegate:self];
????//甲自己加入到通訊中
? ? [[TYVoipDarwinManager sharedVoip] startCallWithUserId:401];
? ? //添加節(jié)點(添加乙的USerID)
????[[TYVoipDarwinManager sharedVoip] addClientNode:402];
????//視圖渲染
????[self.preView startRendering];//渲染甲自己
????[self.otherView startRendering];//渲染乙視圖
}
<3>斷開操作
甲進行斷開通信操作
-(void)stopVoip{
????//關閉voip
????[[TYVoipDarwinManager sharedVoip] stopCall];
????//清空現(xiàn)有的連接節(jié)點(不再接收節(jié)點的數(shù)據(jù))
????[[TYVoipDarwinManager sharedVoip] clearClientNodeList];
????//停止視圖渲染
????[self.preView stopRendering];
????[self.otherView stopRendering];
}
<4>代碼中出現(xiàn)代理方法詳解
- (void)localVideoImage:(TYVoipVideoData *)image{//甲畫面處理
????if ([self.preView isRenderring]){
? ? [self.preView renderVoipVideoData:image];//進行甲畫面渲染
}
}
- (void)remoteVideoImage:(TYVoipVideoData *)image{//乙畫面處理
????if ([self.otherView isRenderring]){
? ? [self.otherView renderVoipVideoData:image]; //乙畫面渲染
}
}
- (void)previewAudio:(NSData *)data{//本地語音
}
- (void)mixedAudio:(NSData *)data{//其他節(jié)點語音,混音
}
項目中最重要的代碼介紹完啦,那測試一下,看看我們的成果吧。
圖8? 測試效果圖

到這里,搭建一套完整的iOS音視頻通信系統(tǒng)就完成了,圖鴨君在demo里實現(xiàn)了兩路通信。多路通信的原理與兩路一模一樣,小伙伴們思考一下,動手搭建多路通信吧~
文章來自:圖鴨科技團隊,轉載或交流請關注微信公眾號:tucodec