最近公司做新需求, 原来用的老弹幕库, 已经无法满足需要. 迫不得已自己写了一套弹幕库OCBarrage. 这套弹幕库轻量, 可拓展, 高度自定义, 超高性能, 简单易上手. 
无论哪家公司软件的性能绝对是衡量APP好坏的重要指标. 之前有一次开会, 我们领导说:”我们写的东西, 有哪些是可以拿的出手,让我们引以为豪的?”. 之前还真就得想一会儿, 现在可以毫不犹豫的说我们的弹幕库绝对是一个好家伙. 
做直播类软件核心功能一个是播放器另一个就是弹幕了. 现在iOS开源的弹幕库性能好的不多, 弹幕量稍微大一点, 或者弹幕稍微复杂一点, 就会出现卡顿,这与它的底层实现, 设计策略以及你的使用方法都有关系. 关键是动画单一,无法定制,满足不了动画的多样化需求!OCBarrage正是为解决这些问题而生的! 
OCBarrage底层使用Core Animation驱动, Core Graphics绘图, GPU渲染, 性能极高, 哪怕是同时渲染5000条弹幕也不会感觉到卡顿. 开源地址:https://github.com/w1531724247/OCBarrage 
(以下测试基于iPhone7真机)

对于全民直播这样的平台来说,在大主播高峰时期的弹幕量是很大的,特别是当主播说一句:“我们现在开始弹幕抽奖”。弹幕量瞬间就会涨的很高!所以对弹幕这一块的要求还是蛮高的.

性能优化原理

弹幕渲染时比较耗性能的点: 
1. ######弹幕阴影 
主播在户外直播时偶尔会有白色的背景, 而弹幕文字的颜色也是白色的, 这个时候弹幕飘到直播画面的白色区域会导致看不到文字内容. 为了解决这个问题我们通常会给弹幕文字添加一个隐影.以防止这种情况的发生. 然而别小看这几个像素阴影, 它可是性能消耗的大户. 哪怕是用GPU渲染因为是动态的实时的所以也相当吃性能. 在实验的过程中发现如果有文字阴影几十条弹幕就会出现弹幕卡顿, 结果就是弹幕抖动一跳一跳的. 
解决办法就是用NSAttributeStringNSStrokeColorAttributeName属性设置文字的轮廓颜色替换文字阴影.效果对比如下: 

都能解决我们的问题, 但是性能差的可不是一丁半点. 
2. ######用CALayer替代UIView展示 
与UIView相比CALayer更轻量. 性能更好.系统提供的组件为了保证其通用性, 难免有些冗余.这就是我们优化的空间. 
3. ######弹幕文字下面的渐变色背景 
彩色弹幕下面的渐变色背景如果用CAGradientLayer实现也是比较耗性能的, 但是如果是用图片呈现的话效果就会好的多, 但是不够灵活, 没关系, 我们都一并解决了. 
4. ######将内容合成一张图片展现 
将所有的内容呈现在layer上并布局好位置以后将所有的内容合成一张图片展现在barrageCell的layer上, 并删除所有的子subview及sublayer, 以提高性能.

基础类

OCBarrageManager

 
提供了弹幕渲染视图并负责弹幕引擎的启动, 暂停, 继续及停止. 
renderView:弹幕呈现的视图. 
renderStatus:renderView的状态, 开始, 暂停, 结束. 
- (void)resgisterBarrageCellClass:(Class)barrageCellClass withBarrageIndentifier:(NSString *)barrageIndentifier;
注册cell类型, 在调用- (void)renderBarrageDescriptor:(OCBarrageDescriptor *)barrageDescriptor;方法的时候会根据barrageDescriptor的barrageIndentifier去自动去缓存池中取一个注册的与barrageDescriptor的barrageIndentifier相同的cell.并将传入的barrageDescriptor赋值给cell的barrageDescriptor属性. 
- (void)start;:允许接收并渲染弹幕 
- (void)puase;:暂停弹幕动画. 如果弹幕正在运动则会暂停在当前位置, 并且不会渲染并丢弃新收到的弹幕. 
- (void)resume; :继续弹幕动画, 并渲染新收到的弹幕. 
- (void)stop;: 清空当前正在动画的弹幕, 并停止接收渲染新的弹幕.

OCBarrageDescriptor

 
OCBarrageDescriptor是负责传递弹幕数据的类, 通过barrageIndentifier找到对应的OCBarrageCell并将数据展示在OCBarrageCell上. 
positionPriority:属性决定了弹幕渲染之后在视图层次上所处的位置, 因为经常会有一些比较重要的弹幕不希望被普通弹幕覆盖, 这个时候可以将重要弹幕的positionPriority设置的高一点, 这样重要弹幕就可以渲染在普通弹幕的上方而不会被普通弹幕覆盖. 
animationDuration:动画时间, 这条弹幕从开始到结束的总时间. 
touchAction:弹幕被点击时候执行的动作. 
bindingOriginY:本条弹幕在渲染的时候将frame.origin.y固定在bindingOriginY的位置.>=0时生效. 可以固定弹幕Y坐标的位置.

OCBarrageCell

 
呈现弹幕数据的视图. 
idle:是否是空闲状态, 如果正在运动则为NO, 如果正在缓存池中等待被复用则为YES. 
idleTime:弹幕动画执行完毕后的时间点. 弹幕动画执行完毕后当前cell会被放进缓存池等待下次复用减少cell创建释放的性能开销. 如果超过5秒没有被复用则会被释放回收内存, 减少内存占用. 
barrageIndentifier:标识符. 通过这个属性与OCBarrageDescriptor类绑定. 与OCBarrageDescriptorbarrageIndentifier对应. 
barrageDescriptor:当前展示的OCBarrageDescriptor. 
barrageAnimation:当前cell所执行的动画. 
trackIndex当前cell所在的弹幕轨道的索引. 
- (instancetype)initWithBarrageIndentifier:(NSString *)barrageIndentifier;:根据传入的barrageIndentifier创建一个实例. 
- (void)addBarrageAnimationWithDelegate:(id<CAAnimationDelegate>)animationDelegate;: 子类可以通过重写这个方法为当前cell添加自定义的动画类型.animationDelegate默认为OCBarrageRenderView, 可以监听动画执行完毕的事件以便将cell放入缓存池等待下次复用. 
- (void)updateSubviewsData;:在这个方法里给cell的各个子视图赋值. 也可以在- (void)setBarrageDescriptor:(OCBarrageDescriptor *)barrageDescriptor方法里给子视图复制. 在这个方法调用以后可以计算一下子视图的的大小及位置.. 也可以在 - (void)layoutSubviews设置子视图的大小及位置. 
- (void)clearContents;设置数据前清空一下上次展示的遗留内容. 
- (void)sizeToFit;:根据子视图的边界自适应大小. 
- (void)convertContentToImageWithSize:(CGSize)contentSize;: 将当前cell上的子视图的内容绘制成一张图片, 并将生成的图片赋值给当前cell的layer的contents属性展现出来. 这个方法要在设置完数据和布局完子视图的位置之后调用. 这个方法会自动调用- (void)layoutSubviews因此不可以在layoutSubviews里调用这个方法不然后造成死循环. 图片生成之后这个方法会执行removeAllSubViewsAndSublayers

删除当前cell上所有的子视图以及子layer以优化展示性能.所以不希望被删除的视图或者layer请在这个方法调用之后添加, 在这个方法执行之后建议将子layer或者子view设置为nil以回收内存. 

  • - (void)prepareForReuse;: 在复用之前要进行的操作可以放在这个方法里执行, 在重写这个方法的时候记得调用一下[super prepareForReuse];.
OCBarrageRenderView

 
animatingCells: 正在运动的弹幕cell的数组. 
idleCells: 弹幕动画执行完毕后等待复用的弹幕cell的数组. 
renderPositionStyle: 新出生的弹幕的位置OCBarrageRenderPositionRandomTracks, 有弹幕轨道, 新出生的弹幕随机展示在其中一条轨道上, 并且尽量不覆盖在还没呈现完整的正在出来的弹幕上-默认类型.OCBarrageRenderPositionRandom没有弹幕轨道, y坐标完全随机.OCBarrageRenderPositionIncrease有弹幕轨道, y坐标循环递增. 
renderStatus: 引擎状态正在OCBarrageRenderStoped, 不接收不渲染新弹幕. OCBarrageRenderStarted接受并渲染新弹幕.OCBarrageRenderPaused暂停中, 不接收不渲染新弹幕, 已经渲染的弹幕停留在当前所处的位置. 
- (void)resgisterBarrageCellClass:(Class)barrageCellClass withBarrageIndentifier:(NSString *)barrageIndentifier;: 同OCBarrageManager- (void)resgisterBarrageCellClass:(Class)barrageCellClass withBarrageIndentifier:(NSString *)barrageIndentifier;
- (nullable OCBarrageCell *)cellWithBarrageIndentifier:(NSString *)barrageIndentifier;: 根据传入的barrageIndentifier从缓存池或者注册的cell列表中返回一个cell. 
- (void)fireBarrageCell:(OCBarrageCell *)barrageCell;: 发射弹幕. 
- (void)start;: 同OCBarrageManager
- (void)puase;: 同OCBarrageManager
- (void)resume;: 同OCBarrageManager
- (void)stop;: 同OCBarrageManager.

OCBarrageTrackInfo

 
弹幕轨道信息类. 
trackIndex: 弹幕轨道所在的位置. 
trackIdentifier: 弹幕轨道标识符, 不同类型的弹幕, 不重用同一条轨道. 
nextAvailableTime:下次可用时间, 主要是用来防止某条轨道上刚出现了一条弹幕还没有完全展现在屏幕上, 后面这条轨道上就又来了一条弹幕盖在之前的那个弹幕上, 影响用户体验. 
barrageCount: 当前轨道的弹幕数量.

当然写到这里依然还有优化的空间, 后续会继续优化, 欢迎各位仁人志士共同探讨指点. 
开源地址:https://github.com/w1531724247/OCBarrage

from:https://blog.csdn.net/w1531724247/article/details/77619111

【转】iOS弹幕库OCBarrage-如何hold住每秒5000条巨量弹幕相关推荐

  1. OpenCV学习笔记(三十一)——让demo在他人电脑跑起来 OpenCV学习笔记(三十二)——制作静态库的demo,没有dll也能hold住 OpenCV学习笔记(三十三)——用haar特征训练自己

    OpenCV学习笔记(三十一)--让demo在他人电脑跑起来 这一节的内容感觉比较土鳖.这从来就是一个老生常谈的问题.学MFC的时候就知道这个事情了,那时候记得老师强调多次,如果写的demo想在人家那 ...

  2. iOS-FXDanmaku弹幕库介绍、相关技术分享

    前言 去年, 2016年, 一大波直播平台在移动端涌出, 直播慢慢步入了人们的视角. 网上如今能够看到各式各样的直播, 如秀场直播.游戏直播.体育直播.娱乐直播等等. 在各种类型的直播中, 弹幕在PC ...

  3. 脑波技术来袭,人类hold住吗?

    用脑波控制物体,这是传说中的特异功能,心灵交流,这是人类梦想的沟通方式,现在,脑波技术正在将它们从梦想变为现实. 现在,我们一起感受一下神奇的脑波技术吧. 意识传输 上上周,国内网站cnBeta.CO ...

  4. 一个线上运营着3000+人的游戏,因为我不小心一个DROP DATABASE,全没了。 怎么办??跟我HOLD住!!!...

    前言 今天下午3点,我按照惯例,打开游戏服务器,开新服部署嘛,游戏在腾讯开放平台,简单.闭着眼睛都OK.于是一轮子的复制黏贴拷贝,把服务器加起来,然后启动查看日志. ....突然发现不断的有Excep ...

  5. 33个2017年必须了解的iOS开源库

    原文 本文翻译自Medium,原作者为 Paweł Białecki 照片版权:(Unsplash/Markus Pe) 你好,iOS 开发者们!我的名字叫 Paweł,我是一个独立 iOS 开发者, ...

  6. iOS标准库中常用数据结构和算法之内存池

    上一篇:iOS标准库中常用数据结构和算法之位串 ⛲️内存池 内存池提供了内存的复用和持久的存储功能.设想一个场景,当你分配了一块大内存并且填写了内容,但是你又不是经常去访问这块内存.这样的内存利用率将 ...

  7. 编译-C++支持iOS静态库的脚本学习

    这是一个编译C++库,支持iOS静态库的一个脚本.仅供研究学习的. #!/bin/bashPLATFORMPATH="/Applications/Xcode.app/Contents/Dev ...

  8. 云计算物联网Hold住未来十大技术趋势

    本文讲的是云计算物联网Hold住未来十大技术趋势,据国外媒体报道,思科首席未来学家.首席技术学家戴夫-埃万斯(Dave Evans)称,在未来十年内,物联网.云服务和虚拟人类等十大技术发展趋势,将深刻 ...

  9. ios 静态库冲突的解决办法

    参考:http://www.cnblogs.com/machao/p/5288460.html ios 静态库冲突的解决办法 最近在做一个 iOS 的 cocos2d-x 项目接入新浪微博 SDK 的 ...

最新文章

  1. 独家 | 一个好的事件跟踪字典是什么样的?
  2. python 三引号_Python 字符串
  3. 每日一练:Python爬虫爬取全国新冠肺炎疫情数据实例详解,使用beautifulsoup4库实现
  4. 【技术综述】如何Finetune一个小网络到移动端(时空性能分析篇)
  5. 【目录】shell 编程-xyq
  6. javac手动编译servlet
  7. 具有GlassFish和一致性的高性能JPA –第3部分
  8. comsol分析时总位移代表什么_超弹性材料模型的压缩分析
  9. CSS样式设置语法全解,样式优先级、值和单位、字体、文本、块级元素,行内元素,替换元素、非替换元素、display、float、position、table、li、光标、边距边框、轮廓、颜色背景
  10. lidar与相机联合标定开源软件介绍
  11. [转]gluPerspective函数
  12. 哈利波特:哈迷们集合啦
  13. python颜色输出
  14. Unity WebGL基于js通信实现网页录音
  15. 白帽黑客获 5 万美元赏金!只因利用漏洞控制所有特斯拉汽车
  16. android 电影放到哪个文件夹里,手机爱奇艺下载的电影保存到哪个文件夹里
  17. 吴军《态度》读后感(1):人生哲学
  18. 大数据在高校的应用场景_大数据在高校中的应用研究
  19. jumpserver简单安装及使用
  20. android修改checkbox样式边框颜色

热门文章

  1. [C] 腾讯公司后台服务器经典面试题 (2009年5月)
  2. 人物姿势怎么画?侧身、侧边的初学者人物姿势绘画技巧
  3. Java连接K8s_6-java操作k8s
  4. 【教学类-06-03】20220327 X以内数字分合题(分)及生成word 打印docx纸(方法一)(Python VS )
  5. 各大EMM厂商功能比较 第二部分 MAM Container比较
  6. ESP8266对接天猫精灵-单路继电器控制
  7. Kubernetes K8S之资源控制器Daemonset详解
  8. mybatis查询时间段sql语句和DATE_FORMAT
  9. springboot vue考试问卷源码
  10. Android7.0恢复出厂设置过程分析