這個文章的前置文章是:LNDanmakuMaster
這個文檔主要介紹LNDanmakuMaster中最重要的組件LNDanmakuPlayer式撼;這個組件的代碼量應(yīng)該是整個框架中最多的荐健,.m文件中包含了500行左右的代碼痕鳍;其他的主要組件通常都帶有Abstract支持定義爬早,但LNDanmakuPlayer沒有番捂,這意味著它是不可替代的账锹。
LNDanmakuPlayer結(jié)構(gòu)
LNDanmakuPlayer的責任與Controller類似哪轿,他不展示內(nèi)容窑业、也不更新數(shù)據(jù);更多的時候他只是在發(fā)號施令(ps:核心人物自己一般不會親自動手):
@interface LNDanmakuPlayer ()
<
LNDanmakuClockDelegate,
LNDanmakuContrainerViewDelegate,
LNDanmakuAbstractDispatcherDelegate,
LNDanmakuAbstractDispatcherSmoothGrainDataSource
>
@property (nonatomic, strong) LNDanmakuClock *clock;
@property (nonatomic, strong) LNDanmakuContainerView *containerView;
@property (nonatomic, strong) NSMutableArray<LNDanmakuAbstractTrackController *> *trackControllerMArr;
@property (nonatomic, strong) LNDanmakuDispatcher *dispatcher;
@property (nonatomic, strong) NSMutableArray <id<LNDanmakuClockDelegate>> *clockDelegateMArr;
@property (nonatomic, assign) LNDanmakuPlayerStatus status;
@property (nonatomic, strong) LNDanmakuPool *layerPool;
@property (nonatomic, strong) LNDanmakuPool *viewPool;
@property (nonatomic, strong) NSMutableArray <LNDanmakuTrackGroup *> *trackGroupMArr;
@property (nonatomic, strong) NSMutableSet <LNDanmakuAbstractTrackController *> *trackControllerNoRepeatMSet;
@property (nonatomic, assign) NSInteger maxSmoothGrainNum;
@property (nonatomic, assign) NSInteger restSmoothGrainNum;
@end
LNDanmakuPlayer工作涵蓋的范圍:
- 包含了:clock困后、containerView乐纸、@[trackController]、Pool摇予、trackGroup等組件汽绢。
- 實現(xiàn)了:clock、containerView侧戴、dispatcher的代理和數(shù)據(jù)源
- 除此之外宁昭,還負責時鐘信號一對多轉(zhuǎn)發(fā)、播放狀態(tài)維護酗宋、重復檢查积仗、吞吐量限制。(maxSmoothGrainNum)蜕猫、彈幕回收等工作寂曹。
- 作為LNDanmakuMaster的門面類,LNDanmakuPlayer需要向外界提供各種控制方法回右,為了劃分這些方法的職責稀颁,我為其劃分了類別,除默認類之外還包含:(Track)楣黍、(Data)匾灶、(Control)、(TrackGroup)租漂、(Recover)五個類別阶女,各個類別提供方法的用途見下面這個詳細的表格颊糜。
類別名 | 作用 |
---|---|
() | 默認類別,定義使用到的其他組件秃踩,維護播放器狀態(tài)衬鱼。 |
(Track) | 控制軌道的插入、移除憔杨。 |
(Data) | 控制彈幕數(shù)據(jù)的插入鸟赫、彈幕視圖復用。 |
(Control) | 控制Player播放狀態(tài)包括:開始消别、暫停抛蚤、恢復、結(jié)束四個基本控制方法寻狂;各個子組件的清空方法岁经;針對單點彈幕的移除方法。 |
(TrackGroup) | 軌道組專用類別蛇券,包括:插入缀壤、移除軌道組;向軌道組中插入彈幕纠亚。 |
(Recover) | 恢復操作專用類別:LNDanmakuMaster支持視頻seek后迅速恢復功能塘慕,恢復功能指視頻從一個時間點切換至另一個時間點后,彈幕播放器也可以瞬間將展示的彈幕切換至對應(yīng)時間點的狀態(tài)蒂胞,而不是清空后重新從右側(cè)飄至中央(這個功能之后進行介紹)图呢。 |
LNDanmakuPlayer工作方式
LNDanmakuPlayer實現(xiàn)的邏輯較多,這里描述一條普通的彈幕進入LNDanmakuPlayer中后經(jīng)歷的所有流程啤誊,來把Player和之前講述的其他組件串在一起岳瞭。
注意:以下所有名詞均去掉LNDanmaku前綴拥娄;暫不考慮軌道組的情況蚊锹;Player中使用的軌道是最常見的那種橫向軌道。
階段1:放置階段
- 我們得到了一個來自網(wǎng)絡(luò)的彈幕模型稚瘾,這個模型可能是使用http分段請求的牡昆,也可能是內(nèi)嵌在音視頻流中的,我們不關(guān)心來源摊欠,但我們確信他是一個NSObject類型的對象丢烘,稱之為XXModel。
- 一個專用的彈幕工廠為XXModel生產(chǎn)一個Attributes包裝了這個XXModel些椒,把XXModel放在customObj屬性上播瞳,這個工廠是與業(yè)務(wù)相關(guān)的,所以他不在LNDanmakuMaster框架中免糕。
- 這個Attributes被釋放到了Player中(通常視頻播放進度會不斷產(chǎn)生回調(diào)并釋放那些可播放的彈幕)赢乓。
- Player不會自行處理彈幕忧侧,將其轉(zhuǎn)交給Dispatcher處理。
- Dispatcher接收到Attributes后將Attributes放置到隊尾牌芋,就是之前區(qū)分高低優(yōu)先級的那條隊列蚓炬。
階段2:更新階段
- 開啟狀態(tài)的Clock產(chǎn)生了下一段更新信號。
- Player接收到更新信號后躺屁,拿到了信號中一小段“流逝的時間”肯夏,這個時間是距離上次clock發(fā)出信號的間隔,Player把這個信號和時間信息轉(zhuǎn)發(fā)給自己的TrackControllers和Dispatcher(這個先后順序是固定的)犀暑。
- TrackController收到信號后更新了已有的軌道驯击,在他們的存活時間中扣除了信號傳來那段“流逝的時間”,并使用自己的track重新擺放了這些彈幕的位置母怜。
- Dispatcher收到信號后遍歷了Player的軌道列表余耽,并找到能放下自己隊首彈幕的軌道,把隊首的彈幕放到軌道上苹熏。
- TrackController接收到彈幕后存儲彈幕并將彈幕的presentView/presentLayer放置到ContainerView上碟贾,在之后的周期中像更新其他彈幕一樣更新這條彈幕。
階段3:卸載階段
- 在階段2轨域,TrackController更新時袱耽,會遇到那些存活時間超過了預定時間的彈幕。
- TrackController調(diào)用ContainerView移除彈幕干发,并將其從自己的存儲結(jié)構(gòu)中移除朱巨,并代理給Player一個卸載回調(diào)。
- Player收到軌道控制器的卸載回調(diào)后枉长,走回收邏輯冀续,將Attributes的presentLayer/presentView存入Pool中,釋放Attributes必峰。
除TrackController卸載回調(diào)外洪唐,dispatcher的溢出丟棄、手動移除等時機也會進行Attributes回收吼蚁。
總結(jié)
LNDanmakuPlayer是這個框架的門面類凭需,封裝其他組件并對外提供調(diào)用方法和時機代理;在構(gòu)建好一個Player后肝匆,彈幕相關(guān)的全部操作都可以通過操作Player完成粒蜈,不必與內(nèi)部的其他組件交互。
結(jié)束語
至此旗国,LNDanmakuMaster這個框架的全部組件已經(jīng)介紹完了枯怖,除了基礎(chǔ)文檔中介紹的這些組件外,LNDanmakuMaster有一些額外策略或動畫的實現(xiàn):分布策略的計算能曾、pop的動畫度硝、吞吐量控制策略等设捐。