[教程] 实现视频对话应用 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…

相关文章
相关标签/搜索