系列教程:
- [教程] 使用 Agora SDK 實現視訊對話應用 HouseParty
- [教程] 實現視訊對話應用 HouseParty教程(二)—— 開始聊天
- [教程] 實現視訊對話應用 HouseParty教程(三)—— 多人聊天
在上一篇Agora iOS SDK-開始聊天介紹瞭如何使用Agora SDK進行一對一的聊天,這篇主要介紹下如何使用Agora iOS進行多人聊天,需要實現的功能:
- 隨著加入人數的變化,而顯示不同的UI,主要是分屏
- 在多屏顯示的情況下,點選一個小窗,會放大顯示該聊天窗
- 前篇實現的聊天功能
實現上面所說的功能:分屏
,最好的方式是使用瀑布流佈局,這樣可以滿足分屏的需要。
瀑布流
分屏顯示最好的方式是採用瀑布流,這樣比較方便的能夠適應UI的變化。
瀑布流的實現方式比較多,常用的方式是使用UICollectionView
實現,自定義一個UICollectionViewLayout
。UICollectionViewLayout是向UICollectionView提供佈局資訊,也包括對於檢視的佈局資訊。需要過載UICollectionViewLayout的以下方法:
- collectionViewContentSize 返回內容的大小
- (UICollectionViewLayoutAttributes )layoutAttributesForItemAtIndexPath:(NSIndexPath )indexPath 根據位置反饋cell對應的佈局屬性
- (NSArray
*)layoutAttributesForElementsInRect:(CGRect)rect ,Cell的佈局方式 - prepareLayout 初始化方法
具體的實現可以參考github.com/LD1314/LDWa…,該demo中也會使用該實現。
有了一個已經實現的瀑布流之後,下面就可以實現分屏了。需要引入LDWaterflowLayout
。
動態聊天窗
新建一個ViewController類,命名為MutilChatViewController
,用來做分屏顯示的需求,在Agora SDK中一個遠端視訊的顯示只和該使用者的uid有關,所以使用的資料來源只需要簡單定義為包含uid即可,定義為:
public var dataArray:Array<UInt>?=Array<UInt>();複製程式碼
在Agora的委託AgoraRtcEngineDelegate
中當一個使用者加入聊天之後會觸發它的一個方法,實現該方法,把使用者的uid加入dataArray中:
func rtcEngine(_ engine: AgoraRtcEngineKit!, didJoinedOfUid uid: UInt, elapsed: Int) {
if(!(dataArray?.contains(uid))!){
dataArray?.append(uid)
collectionView.reloadData()
}
}複製程式碼
對於瀑布流的實現需要MutilChatViewController繼承:
- UIViewController
- UICollectionViewDataSource
- LDWaterflowLayoutDelegate
其中LDWaterflowLayoutDelegate
就是瀑布流的委託,重寫它的兩個方法就可以實現分屏:
- columnCount(in waterflowLayout: LDWaterflowLayout!) -> CGFloat
該方法用來指定一行顯示幾個元素,這裡採用比較簡單的方式當只有一個1個使用者的時候就顯示在一行,2個使用者的時候就在一行顯示2個元素...4個使用者的時候就顯示為2行... - waterflowLayout(_ waterflowLayout: LDWaterflowLayout!, heightForItemAt index: UInt, itemWidth: CGFloat) -> CGFloat
該方法用來設定每個元素的高度,也是採用比較簡單的方式,只用1行的時候高度為300,有2行的時候高度為150,3行的時候高度為100。
把分屏的佈局寫好之後,就可以在每一個UICollectionViewCell
上播放聊天視訊了。
播放聊天視訊
新建一個類ChatCell它繼承了UICollectionViewCell,在ChatCell中有兩個元件:videoView: UIView!
和labelUser: UILabel!
,前者用來顯示使用者視訊,後者用來顯示使用者資訊,videoView佈局在整個ChatCell上,隨著ChatCell的變化而變化。
要在ChatCell中播放聊天視訊,必須在ChatCell持有AgoraRtcEngineKit
的變數,因此需要ChatCell宣告AgoraRtcEngineKit的變數,並且在例項化ChatCell之後給該變數賦值:
public var agora :AgoraRtcEngineKit!複製程式碼
之前說過播放遠端使用者的只需要例項化一個AgoraRtcVideoCancas之後再把uid賦值給它就可以了,而播放本地視訊也是類似的方法,還需要區分一個使用者是自己還是遠端使用者,因此需要傳入當前使用者的uid,在ChatCell中定義方法用來播放視訊:
func setUid(uid:UInt,localUid:UInt){
labelUser.text=String(uid)
let videoCanvas = AgoraRtcVideoCanvas()
videoCanvas.uid=uid
videoCanvas.view=videoView
videoCanvas.renderMode = .render_Fit
if(uid != localUid){
agora.setupRemoteVideo(videoCanvas)
}else{
agora.setupLocalVideo(videoCanvas)
}
}複製程式碼
這樣在多人聊天的時候就能使用分屏的方式播放使用者聊天視訊了,如果想放大某一個使用者的視訊該怎麼辦呢?
放大顯示
當使用者點選某一個UICollectionViewCell的時候,希望對應的視訊能夠放大顯示。因為一個視訊的播放只能顯示在一個view上面,所以必須在點選一個UICollectionViewCell的時候把它的播放顯示移除掉,在放大區域播放該聊天視訊,為了預留足夠空間顯示放大的時候,還需要調整UICollextionViewCell的高度,給放大顯示預留出足夠的空間。
因此首先我們在MutilChatViewController
中新增一個顯示放大區域的view:
@IBOutlet weak var remoteView: UIView!複製程式碼
在放大視訊的時候,不知道使用者是需要放大自己的視訊,還是放大遠端使用者的視訊,因此首先要記錄下使用者自己的uid,在點選的時候拿到使用者的uid,再判斷是顯示本地視訊還是遠端使用者的視訊,放大視訊方法:
func setupVideo(uid:UInt){
if(self.remoteView.isHidden){
self.remoteView.isHidden=false
}
let videoCanvas=AgoraRtcVideoCanvas()
videoCanvas.uid=uid
videoCanvas.view=remoteView
videoCanvas.renderMode = .render_Fit
if(uid==localUid){
agoraKit.setupLocalVideo(videoCanvas)
}else{
agoraKit.setupRemoteVideo(videoCanvas)
}
}複製程式碼
當使用者觸發點選事件的時候使用變數isSelect
記錄使用者的點選行為,如果使用者有點選行為的時候,在判斷Cell高度的時候就返回和Cell寬度一樣的值(這裡只是在demo的情況做的考慮,如果實際使用中還要根據Cell的個數進行顯示高度的考慮),判斷高度方法:
func waterflowLayout(_ waterflowLayout: LDWaterflowLayout!, heightForItemAt index: UInt, itemWidth: CGFloat) -> CGFloat {
let count:Int=(dataArray?.count)!
if(self.isSelect!){
return itemWidth
}
....
}複製程式碼
這樣就可以在使用者點選某一個Cell的時候進行放大顯示的處理,在上一篇文章中,介紹了使用reportAudioVolumeIndicationOfSpeakers
監聽是誰在說話,如果真實的專案中,在每一個Cell中可以做一個小廣播,在某一個使用者說話的時候,可以通過小廣播的變化進行標識。
這裡使用Agora SDK做了一個簡短的demo,後續的還會繼續完善,利用Agora SDK模仿Housparty
的功能實現比較簡單,先要產品化還有很多的東西要做,在這裡先做一個簡單的總結吧!
Agora SDK使用總結
Agora提供了高質量的視訊通訊SDK,覆蓋了主流的作業系統,整合效率也比較高,而且還支援多個模式的視訊通話,包括聊天,會議,直播等功能。SDK中API設計基本能夠滿足大部分的開發需要,而且隱藏了底層開發,這樣對於應用層的開發者來說十分友好。非常適合有視訊聊天開發需求的開發者。在視訊領域創業大爆發的今天,建議更多的想要從事該領域的開發者可以嘗試下。
在使用Agora iOS SDK的過程中有兩個建議希望廠商可以考慮下:
- 支援 Cocoapods,不支援Cocoapods需要在整合的時候在依賴上面花費時間,而且以後升級也不是太容易。
- 希望可以提供基礎UI的SDK,就像友盟的分享SDK一樣,提供一套可用的帶UI的SDK,當然還要允許使用者定製,這樣應用層的開發者整合效率會更高。
參考文件:docs.agora.io/cn/user_gui…
demo地址:github.com/jjz/agora-s…