[教程] 實現視頻對話應用 HouseParty教程(三)—— 多人聊天|附 iOS 源碼

系列教程:javascript

  1. [教程] 使用 Agora SDK 實現視頻對話應用 HouseParty
  2. [教程] 實現視頻對話應用 HouseParty教程(二)—— 開始聊天
  3. [教程] 實現視頻對話應用 HouseParty教程(三)—— 多人聊天

在上一篇Agora iOS SDK-開始聊天介紹瞭如何使用Agora SDK進行一對一的聊天,這篇主要介紹下如何使用Agora iOS進行多人聊天,須要實現的功能:html

  1. 隨着加入人數的變化,而顯示不一樣的UI,主要是分屏
  2. 在多屏顯示的狀況下,點擊一個小窗,會放大顯示該聊天窗
  3. 前篇實現的聊天功能

實現上面所說的功能:分屏,最好的方式是使用瀑布流佈局,這樣能夠知足分屏的須要。java

瀑布流

分屏顯示最好的方式是採用瀑布流,這樣比較方便的可以適應UI的變化。
瀑布流的實現方式比較多,經常使用的方式是使用UICollectionView實現,自定義一個UICollectionViewLayout。UICollectionViewLayout是向UICollectionView提供佈局信息,也包括對於視圖的佈局信息。須要重載UICollectionViewLayout的如下方法:ios

  • collectionViewContentSize 返回內容的大小
  • (UICollectionViewLayoutAttributes )layoutAttributesForItemAtIndexPath:(NSIndexPath )indexPath 根據位置反饋cell對應的佈局屬性
  • (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect ,Cell的佈局方式
  • prepareLayout 初始化方法

具體的實現能夠參考github.com/LD1314/LDWa…,該demo中也會使用該實現。
有了一個已經實現的瀑布流以後,下面就能夠實現分屏了。須要引入LDWaterflowLayoutgit

動態聊天窗

新建一個ViewController類,命名爲MutilChatViewController,用來作分屏顯示的需求,在Agora SDK中一個遠程視頻的顯示只和該用戶的uid有關,因此使用的數據源只須要簡單定義爲包含uid便可,定義爲:github

public var dataArray:Array<UInt>?=Array<UInt>();複製代碼

在Agora的委託AgoraRtcEngineDelegate中當一個用戶加入聊天以後會觸發它的一個方法,實現該方法,把用戶的uid加入dataArray中:swift

func rtcEngine(_ engine: AgoraRtcEngineKit!, didJoinedOfUid uid: UInt, elapsed: Int) {
        if(!(dataArray?.contains(uid))!){
            dataArray?.append(uid)
            collectionView.reloadData()
        }

    }複製代碼

對於瀑布流的實現須要MutilChatViewController繼承:api

  • UIViewController
  • UICollectionViewDataSource
  • LDWaterflowLayoutDelegate

其中LDWaterflowLayoutDelegate就是瀑布流的委託,重寫它的兩個方法就能夠實現分屏:app

  1. columnCount(in waterflowLayout: LDWaterflowLayout!) -> CGFloat
    該方法用來指定一行顯示幾個元素,這裏採用比較簡單的方式當只有一個1個用戶的時候就顯示在一行,2個用戶的時候就在一行顯示2個元素...4個用戶的時候就顯示爲2行...
  2. waterflowLayout(_ waterflowLayout: LDWaterflowLayout!, heightForItemAt index: UInt, itemWidth: CGFloat) -> CGFloat
    該方法用來設定每一個元素的高度,也是採用比較簡單的方式,只用1行的時候高度爲300,有2行的時候高度爲150,3行的時候高度爲100。

把分屏的佈局寫好以後,就能夠在每個UICollectionViewCell上播放聊天視頻了。ide

播放聊天視頻

新建一個類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的過程當中有兩個建議但願廠商能夠考慮下:

  1. 支持 Cocoapods,不支持Cocoapods須要在集成的時候在依賴上面花費時間,並且之後升級也不是太容易。
  2. 但願能夠提供基礎UI的SDK,就像友盟的分享SDK同樣,提供一套可用的帶UI的SDK,固然還要容許用戶定製,這樣應用層的開發者集成效率會更高。

參考文檔:docs.agora.io/cn/user_gui…
demo地址:github.com/jjz/agora-s…

相關文章
相關標籤/搜索