HJDanmaku 2.0發(fā)布iOS彈幕

HJDanmaku 1.0版本發(fā)布已經(jīng)過(guò)去兩年之久,直播行業(yè)的快速崛起催生了直播彈幕的迫切需求,高并發(fā)、大流量卓舵、實(shí)時(shí)性的特性和以往視頻彈幕的場(chǎng)景都大有不同,為了滿足新的直播業(yè)務(wù)場(chǎng)景膀钠,HJDanmaku2.0正式發(fā)布!

流暢度

相較于1.0版本裹虫, HJDanmaku2.0采用全新的異步渲染引擎肿嘲,98%的計(jì)算工作轉(zhuǎn)移到子線程執(zhí)行,避免了主線程的卡頓延時(shí)筑公。同時(shí)雳窟,參考離屏渲染技術(shù),將組裝彈幕和渲染彈幕分布在兩個(gè)獨(dú)立線程異步執(zhí)行,確保了彈幕渲染的流暢性


NSBlockOperation?*operation?=?[NSBlockOperation?blockOperationWithBlock:^{

NSArray??*danmakuAgents?=?[self.danmakuSource?fetchDanmakuAgentsForTime:(HJDanmakuTime){HJMaxTime(time),?time.interval}];

dispatch_async(_renderQueue,?^{

if(danmakuAgents.count?>?0)?{

[self.danmakuQueuePool?insertObjects:danmakuAgents?atIndexes:[NSIndexSet?indexSetWithIndexesInRange:NSMakeRange(0,?danmakuAgents.count)]];

}

});

}];

[self.sourceQueue?cancelAllOperations];

[self.sourceQueue?addOperation:operation];

將組裝彈幕的過(guò)程拆分為獨(dú)立的子線程任務(wù)封救,統(tǒng)一由NSOperationQueue單執(zhí)行隊(duì)列管理拇涤,有效的降低CPU的使用率,提升系統(tǒng)運(yùn)行穩(wěn)定性誉结。此外鹅士,在2.0版本中,使用CADisplayLink替換定時(shí)器NSTimer惩坑,與屏幕刷新頻率保持一致掉盅,可以避免NSTimer由于線程阻塞導(dǎo)致的刷新延時(shí)

高并發(fā)

直播與傳統(tǒng)視頻最大區(qū)別在于其實(shí)時(shí)性,短時(shí)間大量的彈幕發(fā)送對(duì)底層渲染引擎是個(gè)不小的挑戰(zhàn)以舒。為了解決這個(gè)問(wèn)題趾痘,HJDanmaku2.0引入數(shù)據(jù)源Source的思想,將彈幕接收與組裝的過(guò)程分開(kāi)蔓钟,可以針對(duì)直播永票、視頻場(chǎng)景實(shí)現(xiàn)差異化的處理方案。視頻場(chǎng)景對(duì)時(shí)間精確度要求較高滥沫,涉及到彈幕的時(shí)間排序侣集,同時(shí),播放進(jìn)度回放也需要數(shù)據(jù)源保存所有的彈幕數(shù)據(jù)佣谐。直播場(chǎng)景則比較單一肚吏,播放完可以立刻釋放,避免內(nèi)存的過(guò)度消耗

13u_int?interval?=?100;

NSMutableArray?*danmakuAgents?=?[NSMutableArray?arrayWithCapacity:interval];

NSUInteger?lastIndex?=?danmakus.count?-?1;

[danmakus?enumerateObjectsUsingBlock:^(HJDanmakuModel?*danmaku,?NSUInteger?idx,?BOOL?*stop)?{

HJDanmakuAgent?*agent?=?[[HJDanmakuAgent?alloc]?initWithDanmakuModel:danmaku];

[danmakuAgents?addObject:agent];

if(idx?==?lastIndex?||?danmakuAgents.count?%?interval?==?0)?{

OSSpinLockLock(&_spinLock);

[self.danmakuAgents?addObjectsFromArray:danmakuAgents];

OSSpinLockUnlock(&_spinLock);

[danmakuAgents?removeAllObjects];

}

}];

通過(guò)拆分入庫(kù)數(shù)據(jù)分布添加可以避免線程鎖的長(zhǎng)時(shí)間占有狭魂,提升系統(tǒng)的穩(wěn)定性和流暢度

精確度

與1.0版本不同罚攀,新版本通過(guò)toleranceCount維度判斷彈幕是否過(guò)期,默認(rèn)允許最大2秒誤差雌澄。彈幕刷新頻率為0.5秒斋泄,即每個(gè)彈幕有效等待次數(shù)為2/0.5 = 4次,超過(guò)4次沒(méi)有渲染將自動(dòng)丟棄

-?(void)removeExpiredDanmakusForTime:(HJDanmakuTime)time?{

[self.danmakuQueuePool?enumerateObjectsWithOptions:NSEnumerationReverse?usingBlock:^(HJDanmakuAgent?*danmakuAgent,?NSUInteger?idx,?BOOL?*stop)?{

danmakuAgent.toleranceCount?--;

if(danmakuAgent.toleranceCount?<=?0)?{

[self.danmakuQueuePool?removeObjectAtIndex:idx];

}

}];

}

彈幕冗余度的設(shè)計(jì)使得彈幕顯示更加平均镐牺,優(yōu)化了彈幕顯示效果炫掐,但是會(huì)降低彈幕顯示的精確度,特別對(duì)于視頻場(chǎng)景睬涧,相對(duì)于1.0版本有所下降募胃,如果你對(duì)精確度要求較高,可以降低tolerance冗余值

碰撞檢測(cè)

與1.0相同畦浓,HJDanmaku2.0仍然使用系統(tǒng)動(dòng)畫(huà)的方式提供彈幕動(dòng)畫(huà)支持痹束,但是碰撞檢測(cè)方式略有不同


-?(BOOL)checkLRIsWillHitWithPreDanmaku:(HJDanmakuAgent?*)preDanmakuAgent?danmaku:(HJDanmakuAgent?*)danmakuAgent?{

CGFloat?width?=?CGRectGetWidth(self.bounds);

CGFloat?preDanmakuSpeed?=?(width?+?preDanmakuAgent.size.width)?/?self.configuration.duration;

if(preDanmakuSpeed?*?(self.configuration.duration?-?preDanmakuAgent.remainingTime)?<?preDanmakuAgent.size.width)?{

returnYES;

}

CGFloat?curDanmakuSpeed?=?(width?+?danmakuAgent.size.width)?/?self.configuration.duration;

if(curDanmakuSpeed?*?preDanmakuAgent.remainingTime?>?width)?{

returnYES;

}

returnNO;

}

在HJDanmaku2.0中,碰撞檢測(cè)不再以彈幕時(shí)間點(diǎn)為參考維度讶请,渲染的彈幕擁有剩余時(shí)間屬性祷嘶,通過(guò)剩余時(shí)間與速度的關(guān)系即可判斷兩者之間是否碰撞。同時(shí),2.0版本只在添加彈幕和恢復(fù)動(dòng)畫(huà)時(shí)為彈幕視圖添加動(dòng)畫(huà)论巍,其它時(shí)間不再校驗(yàn)

手勢(shì)

運(yùn)動(dòng)視圖系統(tǒng)默認(rèn)無(wú)法響應(yīng)手勢(shì)交互事件烛谊,整個(gè)點(diǎn)擊事件交由全局統(tǒng)一處理。HJDanmakuCell定義屬性selectionStyle控制彈幕能否點(diǎn)擊嘉汰,默認(rèn)HJDanmakuCellSelectionStyleNone丹禀,即不能點(diǎn)擊

-?(UIView?*)hitTest:(CGPoint)point?withEvent:(UIEvent?*)event?{

self.selectDanmakuAgent?=?nil;

HJDanmakuAgent?*danmakuAgent?=?[self?danmakuAgentAtPoint:point];

if(danmakuAgent)?{

if(danmakuAgent.danmakuCell.selectionStyle?==?HJDanmakuCellSelectionStyleDefault)?{

self.selectDanmakuAgent?=?danmakuAgent;

returnself;

}

CGPoint?cellPoint?=?[self?convertPoint:point?toView:danmakuAgent.danmakuCell];

return[danmakuAgent.danmakuCell?hitTest:cellPoint?withEvent:event];

}

return[superhitTest:point?withEvent:event];

}

視圖整體響應(yīng)鏈參考以上代碼,當(dāng)收到點(diǎn)擊事情時(shí)郑现,優(yōu)先判斷彈幕cell是否響應(yīng)湃崩,如果響應(yīng)則交由彈幕cell處理,否則交由全局統(tǒng)一處理

總結(jié)

時(shí)隔兩年接箫,HJDanmaku2.0在性能攒读、并發(fā)以及定制型方面都有較大的提升,以iphone6設(shè)備測(cè)試為例辛友,CPU整體使用率穩(wěn)定在5%左右薄扁,大并發(fā)100條/秒彈幕的持續(xù)輸入,F(xiàn)PS可以維持在55幀以上废累。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末邓梅,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子邑滨,更是在濱河造成了極大的恐慌日缨,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,188評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件掖看,死亡現(xiàn)場(chǎng)離奇詭異匣距,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)哎壳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)毅待,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人归榕,你說(shuō)我怎么就攤上這事尸红。” “怎么了刹泄?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,562評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵外里,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我特石,道長(zhǎng)级乐,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,893評(píng)論 1 295
  • 正文 為了忘掉前任县匠,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘乞旦。我一直安慰自己贼穆,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布兰粉。 她就那樣靜靜地躺著故痊,像睡著了一般。 火紅的嫁衣襯著肌膚如雪玖姑。 梳的紋絲不亂的頭發(fā)上愕秫,一...
    開(kāi)封第一講書(shū)人閱讀 51,708評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音焰络,去河邊找鬼戴甩。 笑死,一個(gè)胖子當(dāng)著我的面吹牛闪彼,可吹牛的內(nèi)容都是我干的甜孤。 我是一名探鬼主播,決...
    沈念sama閱讀 40,430評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼畏腕,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼缴川!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起描馅,我...
    開(kāi)封第一講書(shū)人閱讀 39,342評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤把夸,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后铭污,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體恋日,經(jīng)...
    沈念sama閱讀 45,801評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評(píng)論 3 337
  • 正文 我和宋清朗相戀三年况凉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了谚鄙。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,115評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡刁绒,死狀恐怖闷营,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情知市,我是刑警寧澤傻盟,帶...
    沈念sama閱讀 35,804評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站嫂丙,受9級(jí)特大地震影響娘赴,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜跟啤,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評(píng)論 3 331
  • 文/蒙蒙 一诽表、第九天 我趴在偏房一處隱蔽的房頂上張望唉锌。 院中可真熱鬧,春花似錦竿奏、人聲如沸袄简。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,008評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)绿语。三九已至,卻和暖如春候址,著一層夾襖步出監(jiān)牢的瞬間吕粹,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,135評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工岗仑, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留匹耕,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,365評(píng)論 3 373
  • 正文 我出身青樓赔蒲,卻偏偏與公主長(zhǎng)得像泌神,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子舞虱,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容