iOS彈幕組件LNDanmakuMaster的具體使用
LNDanmakuMaster是一個(gè)輕量的彈幕播放器,通過:創(chuàng)建播放器->創(chuàng)建軌道->添加彈幕的方式進(jìn)行彈幕播放,提供豐富軌道樣式的同時(shí)也支持自定義軌道;對傳入的彈幕的視圖層沒有要求(任意的View/Layer);提供多種(目前是3)彈幕分布策略;支持使用軌道組播放特殊彈幕;提供與分布策略的對應(yīng)的彈幕seek策略。
Github鏈接:LNDanmakuMaster
你可以直接下載這個(gè)鏈接并運(yùn)行上面豐富的Demo,或參考Demo代碼實(shí)現(xiàn)自己的彈幕播放器,也可以直接使用Cocoapods👇
Cocoapods
pod 'LNDanmakuMaster'
彈幕機(jī)制
1.驅(qū)動(dòng)機(jī)制
視頻播放器的刷新率通常為29frame/s,彈幕播放器采用同樣的刷新頻率會(huì)有卡頓感,因此彈幕播放器通常使用自己的刷新驅(qū)動(dòng),要么是UIView animation,要么是CADisplayLink;CADisplaylink支持更多的細(xì)節(jié)、進(jìn)度控制,因此這里我們選用的是CADisplayLink。
LNDanmakuClock是這樣一個(gè)驅(qū)動(dòng),封裝了CADisplayLink,增加了一些暫停、銷毀的控制方法,這個(gè)時(shí)鐘每次的輸出就是從上一次DisplayLink回調(diào)到這次displayLink回調(diào)的一小段時(shí)間。
2.進(jìn)度控制機(jī)制
LNDanmakuMaster整體采用時(shí)間定義進(jìn)度,這也是它與其他彈幕框架的主要區(qū)別之一,我們的所有進(jìn)度控制、追趕控制、繁忙度控制,都是使用時(shí)間計(jì)算的。
使用時(shí)間變量替代空間變量的優(yōu)勢包括:
- 如果你的軌道路線并非直線:如果你希望一個(gè)彈幕既可以在水平軌道播放也可以在圓形軌道播放,既要給出角速度,也要給出線速度,如果使用時(shí)間單位,只需要給出運(yùn)行的總時(shí)間。
- 如果你先控制一個(gè)曲線軌道兩條彈幕之間的間距,空間間距需要計(jì)算曲線的長度,而對時(shí)間間距來說處理起來就和直線一樣。
- 在做一些判斷時(shí),如果使用空間條件做判斷,則需要進(jìn)行速度、時(shí)間相關(guān)大量乘除法運(yùn)算,使用時(shí)間可能只需要加減法,雖然我不知道具體是否有優(yōu)勢,但直觀上感覺乘除法是沒有加減法快的。
- 如果是像B站那種中間出現(xiàn)一列的彈幕,它不需要速度,只需要顯示的時(shí)間就夠了。
總之,使用時(shí)間體系替代速度體系,是能統(tǒng)一多種軌道進(jìn)度控制的一個(gè)好方法。
3.刷新機(jī)制
根據(jù)Clock的輸出,我們可以得到一個(gè)穩(wěn)定的回調(diào)得知?jiǎng)倓偨?jīng)過了多長一段時(shí)間,那么彈幕的刷新過程就成為:在彈幕的剩余存活時(shí)間中扣除剛剛經(jīng)過的那段時(shí)間,并根據(jù)扣除后的剩余時(shí)間占總時(shí)間的百分比來刷新彈幕的位置、大小等信息。
經(jīng)過以上三個(gè)主要機(jī)制的介紹,已經(jīng)有了實(shí)現(xiàn)一個(gè)彈幕框架的所有主要邏輯,剩下的就是一些模塊的細(xì)分和細(xì)節(jié)上的雕琢。
模塊分工
LNDanmakuMaster將整個(gè)彈幕框架分成以下幾個(gè)部分(Abstract代表支持重寫定制):
模塊名稱 | 類名 | 備注 |
---|---|---|
播放器 | LNDanmakuPlayer | 播放器相當(dāng)于對整個(gè)彈幕框架其他組件的整合,對外提供調(diào)用方法和時(shí)機(jī)代理 |
分發(fā)器 | LNDanmakuAbstractDispatcher | Dispatcher類似管理軌道的工頭兒,根據(jù)軌道集合的狀態(tài)決定彈幕放到哪里才是最好的 |
軌道控制器 | LNDanmakuAbstractTrackController | 軌道控制器類似一個(gè)工人,定期使用工具(Track)維護(hù)自己的彈幕,并向Dispatcher反饋?zhàn)约旱模ǚ泵?空閑)狀態(tài) |
軌道 | LNDanmakuAbstractTrack | Track的職責(zé)完全符合軌道的定義,它不維護(hù)彈幕,只維護(hù)任意一條彈幕彈幕在這個(gè)軌道上的刷新的位置、大小、仿射變換等屬性與時(shí)間進(jìn)度的映射,像是一個(gè)空間信息與時(shí)間信息的函數(shù) |
樣式 | LNDanmakuAbstractAttributes | 樣式是彈幕的載體,包含了一條彈幕的所有信息,例如:存活時(shí)間、位置、攜帶的業(yè)務(wù)模型、展示時(shí)使用的View/Layer等等。對,沒錯(cuò),與CollectionViewAttributes十分類似,并根據(jù)播放器特性增加了時(shí)間戳信息 |
額外的組件
模塊名稱 | 類名 | 備注 |
---|---|---|
軌道組 | LNDanmakuTrackGroup | 這個(gè)組件是用來做一些特殊彈幕播放的,是類似一個(gè)Player的更小單元(但沒有自己的驅(qū)動(dòng)),內(nèi)部包含了一個(gè)Dispatcher和若干TrackController |
這個(gè)組件的意義:
某些彈幕播放對軌道有一定的要求,又或是軌道對自己播放的彈幕有一定要求,例如:送禮物的軌道只能出現(xiàn)在屏幕頂端,而不是中央,來避免影響用戶觀看視頻;或者是,圓形的軌道不能那些較長的文字,這樣它看起來就不是那么圓了,等等。
一但從兩個(gè)方面考慮這個(gè)問題,就會(huì)陷入:軌道挑選彈幕/彈幕挑選軌道的困境,而實(shí)際上兩種情況是都存在的,這兩個(gè)問題最后統(tǒng)一使用軌道組解決,用戶指定一個(gè)軌道的分組,并可以跨過Player層,直接向這個(gè)軌道組拋彈幕,那么這個(gè)彈幕就只有可能出現(xiàn)在這個(gè)軌道組包含的軌道中;這個(gè)功能在Demo中一個(gè)彩虹樣式的軌道中得以體現(xiàn),我將七種顏色的彈幕分別拋入七個(gè)軌道組中(每個(gè)軌道組有三根軌道,兩個(gè)相鄰的軌道組公用中間那個(gè)重合的軌道),這樣它們就呈現(xiàn)除了一種彩虹的效果。
使用示例
以上介紹完了這個(gè)框架的所有重要組件,這里舉例介紹構(gòu)建一個(gè)最簡單彈幕播放器的過程:
1.懶加載一個(gè)danmakuPlayer:
這個(gè)是起碼要做,不需要做任何配置它就可以正常工作
- (LNDanmakuPlayer *)danmakuPlayer { if (!_danmakuPlayer) { _danmakuPlayer = [[LNDanmakuPlayer alloc] init]; } return _danmakuPlayer; }
2.把這個(gè)播放器的容器View加到屏幕上:
[self.view addSubview:self.danmakuPlayer.containerView];
3.給這個(gè)Player加一些軌道:
Player支持自定義就是主要體現(xiàn)在自定義軌道和彈幕樣式上,所以,所有的軌道都是你親手加上去的,你可以在init/viewDidLoad等初始化的時(shí)機(jī)做這個(gè)時(shí),也可以在Player懶加載時(shí)一并加好
- (void)addTrack for (int i = 0; i < 20; i++) { LNDanmakuHorizontalMoveTrackController *horizontalTrackController = [[LNDanmakuHorizontalMoveTrackController alloc] init]; horizontalTrackController.horizontalTrack.startPosition = CGPointMake(0, 44.f + 30.f * i); horizontalTrackController.horizontalTrack.width = self.view.frame.size.width; horizontalTrackController.spaceTimeInterval = 0.f; [self.danmakuPlayer addTrack:horizontalTrackController]; } }
4.讓播放器動(dòng)起來!
現(xiàn)在這個(gè)播放器就可以從外界接口隨便一個(gè)彈幕并播放在屏幕上了
- (void)startPlay { [self.danmakuPlayer start]; }
5.讓我們嘗試放一個(gè)簡單的彈幕放上去:
(void)addRandomDanmaku { LNDanmakuAttributes *attributes = [[LNDanmakuAttributes alloc] init]; UIView *colorView = [[UIView alloc] init]; colorView.backgroundColor = [UIColor redColor]; attributes.presentView = colorView; attributes.trackTime =4.f; attributes.size = CGSizeMake(88.f, 44.f); [_player insertAttributes:@[attributes]]; }
這個(gè)框架盡量使用最符合正常邏輯的方法定義了每個(gè)組件的分工來保證它使用起來是最舒服的,并盡可能封裝了那些看起來比較復(fù)雜的邏輯:分發(fā)、刷新、追趕等等;當(dāng)然,我覺得一個(gè)合理的框架應(yīng)該是下限很低,上限也很高的,而不是一成不變使用規(guī)則(正如掌控疾風(fēng)的某位男子應(yīng)該算得上是設(shè)計(jì)得比較成功的角色),所以,當(dāng)使用者需要深入探討這些邏輯的時(shí)候,也可以從外部輕易定制他們,玩出自己的特色。
后續(xù)會(huì)陸續(xù)更新一些使用上或是原理方面的文章介紹這個(gè)框架,雖然實(shí)現(xiàn)起來沒有很多高超的技巧,但我認(rèn)為代碼優(yōu)秀與否并非取決于使用了多么高深或是精妙的語言特性,而是寫代碼的邏輯和思路;而且,我從心底十分抵制那些沒什么復(fù)雜邏輯卻要制定很多使用規(guī)則的組件(更惡心的是還要業(yè)務(wù)線強(qiáng)推),所以這個(gè)組件一定會(huì)朝著盡量少的使用規(guī)則、盡量樸素的代碼、更豐富的功能方向發(fā)展。
最后附上幾個(gè)Demo中的效果圖
橫向的軌道
pop動(dòng)畫軌道
波浪軌道+軌道分組
心形軌道
到此這篇關(guān)于iOS彈幕組件LNDanmakuMaster的具體使用的文章就介紹到這了,更多相關(guān)iOS彈幕組件LNDanmakuMaster內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
IOS 獲取已連接的wifi信息的實(shí)現(xiàn)代碼
這篇文章主要介紹了IOS 獲取已連接的wifi信息的實(shí)現(xiàn)代碼的相關(guān)資料,這里提供實(shí)現(xiàn)代碼幫助大家學(xué)習(xí)理解這部分內(nèi)容,需要的朋友可以參考下2017-08-08關(guān)于iOS 11的一些新特性適配實(shí)踐總結(jié)
iOS 11 為整個(gè)生態(tài)系統(tǒng)的 UI 元素帶來了一種更加大膽、動(dòng)態(tài)的新風(fēng)格。下面這篇文章主要給大家總結(jié)介紹了關(guān)于iOS 11的一些新特性適配實(shí)踐,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來一起看看吧。2017-11-11iOS內(nèi)存管理Tagged Pointer使用原理詳解
這篇文章主要為大家介紹了iOS內(nèi)存管理Tagged Pointer使用原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01iOS開發(fā)WebViewJavascriptBridge通訊原理解析
這篇文章主要為大家介紹了iOS開發(fā)WebViewJavascriptBridge通訊原理示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11利用iOS實(shí)現(xiàn)系統(tǒng)相冊大圖瀏覽功能詳解
查看大圖是們?nèi)粘i_發(fā)中經(jīng)常會(huì)遇到的一個(gè)需求,下面這篇文章主要給大家介紹了關(guān)于利用iOS實(shí)現(xiàn)系統(tǒng)相冊大圖瀏覽功能的相關(guān)資料,文中給出了詳細(xì)的示例代碼供大家參考學(xué)習(xí),需要的朋友們下面來一起看看吧。2017-09-09