<acronym id="s8ci2"><small id="s8ci2"></small></acronym>
<rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
<acronym id="s8ci2"></acronym>
<acronym id="s8ci2"><center id="s8ci2"></center></acronym>
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

而至于它是如何連通的,底層做了哪些操作,撥打電話的人對此毫不關心?;谏鲜鑫覀兊恼w功能設計所要關注的點就有了。

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

    文章

    491

    瀏覽量

    65524
  • 騰訊云
    +關注

    關注

    0

    文章

    196

    瀏覽量

    16640
收藏 人收藏

    評論

    相關推薦

    2010年沙特建材展/腳手架/照明器材/復合材料/石材/裝飾材料/鋁型材/防火材料

    2010第22屆沙特國際建筑及石材貿易博覽會 2010年沙特建材展/腳手架/照明器材/復合材料/石材/裝飾材料/鋁型材/防火材料英文名稱:The 22ST International
    發表于 01-25 13:14

    2010年迪拜五大行業展|迪拜建材展|緊固件|腳手架|建筑五金|衛?。沾桑罄硎?/a>

    ;建筑安全設備;混凝土-預制、建筑系統;建筑立面、盤座面及包覆;加熱裝置;模板/百葉窗;工具-空氣、手動及電動;砌體-磚、預制、水泥、灰漿;螺帽、錨桿、螺絲、鉸鏈等;建筑拆除;木材-框架及結構;腳手架
    發表于 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證(山東?。┠M試題相關資料下載

    通過安全員-C證(山東?。┛荚?。1、【判斷題】扣件式鋼管腳手架應按照要求設置縱向剪刀撐和橫向斜撐,以使腳手架具有足夠的縱向和橫向整體剛度。(√)2、【判斷題】施工單位未能開展對作業人員的安全教育培訓、安全技術交底是無錫某文教中心工程腳手
    發表于 07-12 08:11

    懸挑式腳手架監理控制要點

    懸挑式腳手架一般有兩種:一種是每層一挑,將立桿底部頂在樓板、梁或墻體等建筑部位,向外傾斜固定后,在其上部搭設橫桿、鋪腳手板形成施工層,施工一個層高,待轉入上層
    發表于 12-15 14:29 ?15次下載

    腳手架的避雷方法

    搭設在曠野山坡上雷擊區的鋼腳手架在雷雨季節應設避雷裝置,避雷裝置包括接閃器、接地極、接地線。
    發表于 01-19 15:26 ?18次下載

    物聯網腳手架系統能帶來什么益處

    橫向移動不是腳手架上工人唯一需要擔心的事情。超重載荷對立柱施加的壓力過大可能會導致結構崩塌。平板下面的物聯網傳感器可以在壓力成為問題之前測量到它。
    發表于 03-20 10:16 ?514次閱讀

    科學家研發可溶解的植入骨折的腳手架材料——特殊繃帶

    植入骨折的腳手架材料,能夠促使身體自身的骨細胞長入其中并治愈骨折。而現在,科學家們開發了一種特殊的繃帶,也可以做到這一點。
    的頭像 發表于 09-25 11:30 ?1579次閱讀

    腳手架掛牌方案需要符合哪些層面的規定

    腳手架掛牌的過程中,當然就必須應用到方案,即然是方案,又和生產安全有關,也就必須讓它符合各個方面的規定,那麼必須讓這類方案符合哪些層面的規定呢? 最先就必須讓它符合機器設備構造上的規定,由于生產線
    發表于 02-11 10:52 ?1260次閱讀

    關于針對腳手架掛牌的歸納分析

    描述:用五金鎖具鎖定防護設備來防止很多人 隨便操作過程安全防護的能量源或者機器設備,(腳手架掛牌)直到維修結束,五金鎖具消除。 :運用衣服標簽來警告別人早就被安全防護的能量源或者機器設備不能隨便
    發表于 03-01 11:50 ?620次閱讀

    為何需要腳手架掛牌,它的作用是怎樣的

    腳手架掛牌是便于避免員工在進行維修、維修保養時,遇到來自設備的發生意外啟動、出現異常啟動、動力裝置釋放出所導致的風險性,以保證 員工的人身安全。進行腳手架掛牌操作程序的根本所在,斷掉設備與動力裝置
    發表于 03-05 11:39 ?1714次閱讀

    腳手架掛牌是什么,有什么作用

    上邊的案例,看了后耐人尋味。有誤實際操作腳手架掛牌,導致這么多可憐生命的身亡和資產的損害。由此可見恰當應用安全鎖具,是一件多么的關鍵的事兒。溫州市博士安全用品 解釋一下什么叫腳手架掛牌?
    發表于 03-22 10:27 ?1824次閱讀

    RTC腳手架的設計與實現(上)

    RTC即 Real-Time Communication 的簡稱是一種給行業提供高并發、低延時、高清流暢、安全可靠的全場景、全互動、全實時的音視頻服務的終端服務。上面是比較官方的解釋,通俗的來講就是
    的頭像 發表于 05-26 16:48 ?503次閱讀
    <b class='flag-5'>RTC</b><b class='flag-5'>腳手架</b>的設計與<b class='flag-5'>實現</b>(上)
    亚洲欧美日韩精品久久_久久精品AⅤ无码中文_日本中文字幕有码在线播放_亚洲视频高清不卡在线观看
    <acronym id="s8ci2"><small id="s8ci2"></small></acronym>
    <rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
    <acronym id="s8ci2"></acronym>
    <acronym id="s8ci2"><center id="s8ci2"></center></acronym>