0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

RTC脚手架的设计与实现(下)

jf_78858299 来源:网易云音乐技术团队 作者:AirLand 2023-05-26 16:48 次阅读

由于所有的 Player 都有这个逻辑因此可以将这部分再抽象成一个 AbsPlayer:

abstract class AbsPlayerIDataSource, CB : ICallback>
    : IPlayer

最后整个 Player 的类图如下所示:

图片

image.png

这里我们不关注 Player 的功能具体是如何实现的,比如如何推流,如何拉流,如何进行 RTC 等。毕竟每个项目底层所用的服务商 sdk 各不相同,技术实现也不同,因此这里我们只从架构的层面去探讨。

2、Player 的切换

Player 的切换针对的就是部分场景 RTC,这里我们引入 SwitchablePlayer 的概念专门用于此种场景,而其本身也继承自 AbsPlayer, 具备 Player 的所有功能。只不过这些功能是通过装饰者模式由其内部真正的 Player 来实现,同时增加了 Switch 的能力。再讲到 Switch 能力之前先来思考几个问题。

  1. 何时触发 Switch?
  2. 如何进行 Switch?
  3. Switch 的目标对象 Player 从何而来?

第一个问题何时触发 Switch :我们知道只要触发 Switch 就意味着需要启动另外的 Player,而启动 Player 又需要上面提到的 IDataSource,因此我们只需要判断启动 Player 所传入的 IDataSource 类型和当前 Player 的 IDataSource 类型是否相同,如果不同便可触发。判断的具体逻辑是对比当前 Player 泛型参数的 IDataSource 类型( AbsPlayer第一个范型参数 )和传入的 IDataSource 类型来实现。

private fun isSourceMatch(
        player: AbsPlayer<IDataSource, ICallback>?,
        ds: IDataSource
    ): Boolean {
        if (player == null) {
            return false
        } else {
            val clazz = player::class.java
            var type = getGenericSuperclass(clazz) ?: return false
            while (Types.getRawType(type) != AbsPlayer::class.java) {
                type = getGenericSuperclass(type) ?: return false
            }
            return if (type is ParameterizedType) {
                val args = type.actualTypeArguments
                if (args.isNullOrEmpty()) {
                    false
                } else {
                    Types.getRawType(args[0]).isInstance(ds) && isSameSource(player, ds)
                }
            } else {
                false
            }
        }
    }

第二个问题如何进行 Switch :这个就比较简单了只需要停止掉当前的 Player 再启动目标 Player 即可。

第三个问题 Switch 的目标对象 Player 从何而来 :SwitchablePlayer 并不清楚业务需要哪些 Player ,只是对 Player 功能的一层包装以及维护 Switch 功能,因此具体的 Player 创建需要由业务层来实现, SwitchablePlayer 只提供一个获取 Player 的抽象方法例如:

abstract fun getPlayer(ds: IDataSource): AbsPlayer<out IDataSource, out ICallback>?

另外由于进行 Switch 的时候会停止掉当前的 Player,而被停止的 Player 是否能复用,如果能复用则可以将其缓存起来,下次使用优先从缓存中获得。整个SwitchablePlayer对应的流程如图所示:

图片

image.png

在使用时调用者可以根据自己的业务定义相关 Player,例如在直播-> PK 的业务中,涉及到两个 Player 的切换即:LivePlayer 和 PKPlayer

class LivePKSwitchablePlayer : SwitchablePlayer(false) {
        override fun getPlayer(ds: IDataSource): AbsPlayer<out IDataSource, out ICallback> {
            return when (ds) {
                is LiveDataSource -> {
                    LivePlayer()
                }
                is PKDataSource -> {
                    PKPlayer()
                }
                else -> LivePlayer()
            }
        }

    }
3、流程封装

对于整个 RTC 流程的封装需要搞清楚两件事情:

  1. RTC 的主体流程是怎样的
  2. 业务调用方需要的是什么,关注的又是什么

由于 RTC 的主体流程和日常打电话相似,所以笔者以此类比,这样大家更容易理解。下图所示即为整个通话过程。图片

搞清楚整个流程后,接下来就是搞清楚第二件事情,业务调用方需要的是什么,关注的又是什么。结合上图来看关注的大概有三点:

  • 第一就是需要具备拨打和挂断的入口;( Player 的 Start 和 Stop
  • 第二就是要能知道当前的通话状态比如是否正在连通,是否已经接通,是否通话结束;( Player 的 状态维护
  • 第三就是一些反馈比如对方未接通,对方不在服务区,手机号是空号等。( Player 的 核心事件回调即之前提到的 ICallback

而至于它是如何连通的,底层做了哪些操作,拨打电话的人对此毫不关心。基于上述我们的整体功能设计所要关注的点就有了。

1、通过设计一个 manager 来管理 Player 并对外暴露 Start 和 Stop 方法。

2、对 Player 进行状态维护,并让其状态可被上层监听。

3、Player 的一些核心事件回调也可被上层监听。

其中第一点和第三点比较简单,这里就不做过多的赘述。第二点状态维护,笔者使用了 StateMachine 状态机来实现,在不同的状态执行不同的操作,同时每一种状态都对应一个状态码,上层可以通过监听状态码来感知状态变化。

图片

image.png

状态码和核心事件的设置这里使用了 LiveData 去处理

class RtcHolder : IRtcHolder {
    private val _rtcState = MutableLiveData(RtcStatus.IDLE)
    private val _rtcEvent = MutableLiveData(RtcEvent.IDLE)
    val rtcState = _rtcState.distinctUntilChanged()
    val rtcEvent = _rtcEvent.distinctUntilChanged()
    private val callBack = object : IRtcCallBack {
        override fun onCurrentStateChange(stateCode: Int) {
            _rtcState.value = stateCode
        }

        override fun onEvent(eventCode: Int) {
            _rtcEvent.value = eventCode
        }
       
       //......省略其他代码
        
    }

     init {
        //上层状态监听 
        rtcState.observeForever {
            when (it) {
                RtcStatus.CONNECT_END -> {
                    ToastHelper.showToast("通话结束")
                }
            }
        }
    }
    //......省略其他代码
}

到这里整个脚手架的方案设计就结束了,其中服务商 SDK 封装部分以及监控部分,笔者准备放到下期再来讲解。

总结

本文介绍了 RTC 脚手架产生的背景,并以通俗易懂的方式一步步阐述设计过程以及最终实现。在此期间发现问题,解决问题,引出思考。由于受限于篇幅,不能将每一个点都进行详尽的介绍,有兴趣的同学如有疑问,可以留言,一起探讨学习。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • RTC
    RTC
    +关注

    关注

    2

    文章

    484

    浏览量

    65439
  • 腾讯云
    +关注

    关注

    0

    文章

    190

    浏览量

    16617
收藏 人收藏

    评论

    相关推荐

    2010年沙特建材展/脚手架/照明器材/复合材料/石材/装饰材料/铝型材/防火材料

    2010第22届沙特国际建筑及石材贸易博览会 2010年沙特建材展/脚手架/照明器材/复合材料/石材/装饰材料/铝型材/防火材料英文名称:The 22ST International
    发表于 01-25 13:14

    2010年迪拜五大行业展|迪拜建材展|紧固件|脚手架|建筑五金|卫浴|陶瓷|大理石

    ;建筑安全设备;混凝土-预制、建筑系统;建筑立面、盘座面及包覆;加热装置;模板/百叶窗;工具-空气、手动及电动;砌体-砖、预制、水泥、灰浆;螺帽、锚杆、螺丝、铰链等;建筑拆除;木材-框架及结构;脚手架
    发表于 09-06 15:51

    2011年沙特建材展|吉达建材展|五大行业展|紧固件|脚手架|玻璃|门窗|

    |吉达建材展|五大行业展|紧固件|脚手架|玻璃|门窗|2011年沙特建材展|吉达建材展|五大行业展|紧固件|脚手架|玻璃|门窗|2011年沙特建材展|吉达建材展|五大行业展|紧固件|脚手架|玻璃|门窗
    发表于 09-06 15:55

    2011年沙特建材展|吉达建材展|五大行业展|紧固件|脚手架|玻璃|门窗|

    ;nbsp;2011年沙特建材展|吉达建材展|五大行业展|紧固件|脚手架|玻璃|门窗|2011年沙特建材展|吉达建材展|五大行业展|紧固件|脚手架|玻璃|门窗|2011年沙特建材展|吉达建材展|五大行业展
    发表于 09-06 16:05

    2021年建筑架子工(建筑特殊工种)考试题及建筑架子工(建筑特殊工种)考试试卷相关资料分享

    试卷祝您顺利通过建筑架子工(建筑特殊工种)考试。1、【判断题】木脚手架的单排架小横杆的大头应朝里设置。(√)2、【判断题】竹、木脚手架上下相邻两步的大横杆大头朝向应当相反。(√)3、【判断题】碗扣式钢管
    发表于 07-09 07:39

    2021年安全员-C证(山东省)考试题及安全员-C证(山东省)模拟试题相关资料下载

    通过安全员-C证(山东省)考试。1、【判断题】扣件式钢管脚手架应按照要求设置纵向剪刀撑和横向斜撑,以使脚手架具有足够的纵向和横向整体刚度。(√)2、【判断题】施工单位未能开展对作业人员的安全教育培训、安全技术交底是无锡某文教中心工程脚手
    发表于 07-12 08:11

    悬挑式脚手架监理控制要点

    悬挑式脚手架一般有两种:一种是每层一挑,将立杆底部顶在楼板、梁或墙体等建筑部位,向外倾斜固定后,在其上部搭设横杆、铺脚手板形成施工层,施工一个层高,待转入上层
    发表于 12-15 14:29 15次下载

    脚手架的避雷方法

    搭设在旷野山坡上雷击区的钢脚手架在雷雨季节应设避雷装置,避雷装置包括接闪器、接地极、接地线。
    发表于 01-19 15:26 18次下载

    现场宛如大片,国产航母下水后又装脚手架,国之重器

    国产001A航母下水后,被拖入旁边的码头进行舾装。最新网友拍到的图片显示,国产航母舰岛又安上了脚手架,开始紧锣密鼓的施工作业。02航母是何种水平也早已被军迷开始讨论了,而这艘航母到现在为止依旧是扑朔迷离。
    发表于 05-14 22:08 766次阅读

    物联网脚手架系统能带来什么益处

    横向移动不是脚手架上工人唯一需要担心的事情。超重载荷对立柱施加的压力过大可能会导致结构崩塌。平板下面的物联网传感器可以在压力成为问题之前测量到它。
    发表于 03-20 10:16 498次阅读

    脚手架挂牌方案需要符合哪些层面的规定

    脚手架挂牌的过程中,当然就必须应用到方案,即然是方案,又和生产安全有关,也就必须让它符合各个方面的规定,那麼必须让这类方案符合哪些层面的规定呢? 最先就必须让它符合机器设备构造上的规定,由于生产线
    发表于 02-11 10:52 1235次阅读

    关于针对脚手架挂牌的归纳分析

    描述:用五金锁具锁定防护设备来防止很多人 随便操作过程安全防护的能量源或者机器设备,(脚手架挂牌)直到维修结束,五金锁具消除。 :运用衣服标签来警告别人早就被安全防护的能量源或者机器设备不能随便
    发表于 03-01 11:50 591次阅读

    为何需要脚手架挂牌,它的作用是怎样的

    脚手架挂牌是便于避免员工在进行维修、维修保养时,遇到来自设备的发生意外启动、出现异常启动、动力装置释放出所导致的风险性,以保证 员工的人身安全。进行脚手架挂牌操作程序的根本所在,断掉设备与动力装置
    发表于 03-05 11:39 1640次阅读

    脚手架挂牌是什么,有什么作用

    上边的案例,看了后耐人寻味。有误实际操作脚手架挂牌,导致这么多可怜生命的身亡和资产的损害。由此可见恰当应用安全锁具,是一件多么的关键的事儿。温州市博士安全用品 解释一下什么叫脚手架挂牌?
    发表于 03-22 10:27 1764次阅读

    RTC脚手架的设计与实现(上)

    RTC即 Real-Time Communication 的简称是一种给行业提供高并发、低延时、高清流畅、安全可靠的全场景、全互动、全实时的音视频服务的终端服务。上面是比较官方的解释,通俗的来讲就是
    的头像 发表于 05-26 16:48 471次阅读
    <b class='flag-5'>RTC</b><b class='flag-5'>脚手架</b>的设计与<b class='flag-5'>实现</b>(上)