iOS弹幕组件LNDanmakuMaster的具体使用

LNDanmakuMaster是一个轻量的弹幕播放器,通过:创建播放器->创建轨道->添加弹幕的方式进行弹幕播放,提供丰富轨道样式的同时也支持自定义轨道;对传入的弹幕的视图层没有要求(任意的View/Layer);提供多种(目前是3)弹幕分布策略;支持使用轨道组播放特殊弹幕;提供与分布策略的对应的弹幕seek策略。

Github链接:LNDanmakuMaster

你可以直接下载这个链接并运行上面丰富的Demo,或参考Demo代码实现自己的弹幕播放器,也可以直接使用Cocoapods👇

Cocoapods

pod 'LNDanmakuMaster'

弹幕机制

1.驱动机制
视频播放器的刷新率通常为29frame/s,弹幕播放器采用同样的刷新频率会有卡顿感,因此弹幕播放器通常使用自己的刷新驱动,要么是UIView animation,要么是CADisplayLink;CADisplaylink支持更多的细节、进度控制,因此这里我们选用的是CADisplayLink。
LNDanmakuClock是这样一个驱动,封装了CADisplayLink,增加了一些暂停、销毁的控制方法,这个时钟每次的输出就是从上一次DisplayLink回调到这次displayLink回调的一小段时间。

2.进度控制机制
LNDanmakuMaster整体采用时间定义进度,这也是它与其他弹幕框架的主要区别之一,我们的所有进度控制、追赶控制、繁忙度控制,都是使用时间计算的。
使用时间变量替代空间变量的优势包括:

  • 如果你的轨道路线并非直线:如果你希望一个弹幕既可以在水平轨道播放也可以在圆形轨道播放,既要给出角速度,也要给出线速度,如果使用时间单位,只需要给出运行的总时间。
  • 如果你先控制一个曲线轨道两条弹幕之间的间距,空间间距需要计算曲线的长度,而对时间间距来说处理起来就和直线一样。
  • 在做一些判断时,如果使用空间条件做判断,则需要进行速度、时间相关大量乘除法运算,使用时间可能只需要加减法,虽然我不知道具体是否有优势,但直观上感觉乘除法是没有加减法快的。
  • 如果是像B站那种中间出现一列的弹幕,它不需要速度,只需要显示的时间就够了。

总之,使用时间体系替代速度体系,是能统一多种轨道进度控制的一个好方法。

3.刷新机制
根据Clock的输出,我们可以得到一个稳定的回调得知刚刚经过了多长一段时间,那么弹幕的刷新过程就成为:在弹幕的剩余存活时间中扣除刚刚经过的那段时间,并根据扣除后的剩余时间占总时间的百分比来刷新弹幕的位置、大小等信息。
经过以上三个主要机制的介绍,已经有了实现一个弹幕框架的所有主要逻辑,剩下的就是一些模块的细分和细节上的雕琢。

模块分工

LNDanmakuMaster将整个弹幕框架分成以下几个部分(Abstract代表支持重写定制):

模块名称 类名 备注
播放器 LNDanmakuPlayer 播放器相当于对整个弹幕框架其他组件的整合,对外提供调用方法和时机代理
分发器 LNDanmakuAbstractDispatcher Dispatcher类似管理轨道的工头儿,根据轨道集合的状态决定弹幕放到哪里才是最好的
轨道控制器 LNDanmakuAbstractTrackController 轨道控制器类似一个工人,定期使用工具(Track)维护自己的弹幕,并向Dispatcher反馈自己的(繁忙/空闲)状态
轨道 LNDanmakuAbstractTrack Track的职责完全符合轨道的定义,它不维护弹幕,只维护任意一条弹幕弹幕在这个轨道上的刷新的位置、大小、仿射变换等属性与时间进度的映射,像是一个空间信息与时间信息的函数
样式 LNDanmakuAbstractAttributes 样式是弹幕的载体,包含了一条弹幕的所有信息,例如:存活时间、位置、携带的业务模型、展示时使用的View/Layer等等。对,没错,与CollectionViewAttributes十分类似,并根据播放器特性增加了时间戳信息

额外的组件

模块名称 类名 备注
轨道组 LNDanmakuTrackGroup 这个组件是用来做一些特殊弹幕播放的,是类似一个Player的更小单元(但没有自己的驱动),内部包含了一个Dispatcher和若干TrackController

这个组件的意义:
某些弹幕播放对轨道有一定的要求,又或是轨道对自己播放的弹幕有一定要求,例如:送礼物的轨道只能出现在屏幕顶端,而不是中央,来避免影响用户观看视频;或者是,圆形的轨道不能那些较长的文字,这样它看起来就不是那么圆了,等等。
一但从两个方面考虑这个问题,就会陷入:轨道挑选弹幕/弹幕挑选轨道的困境,而实际上两种情况是都存在的,这两个问题最后统一使用轨道组解决,用户指定一个轨道的分组,并可以跨过Player层,直接向这个轨道组抛弹幕,那么这个弹幕就只有可能出现在这个轨道组包含的轨道中;这个功能在Demo中一个彩虹样式的轨道中得以体现,我将七种颜色的弹幕分别抛入七个轨道组中(每个轨道组有三根轨道,两个相邻的轨道组公用中间那个重合的轨道),这样它们就呈现除了一种彩虹的效果。

使用示例

以上介绍完了这个框架的所有重要组件,这里举例介绍构建一个最简单弹幕播放器的过程:
1.懒加载一个danmakuPlayer:
这个是起码要做,不需要做任何配置它就可以正常工作

- (LNDanmakuPlayer *)danmakuPlayer
{
  if (!_danmakuPlayer) {
    _danmakuPlayer = [[LNDanmakuPlayer alloc] init];
  }
  return _danmakuPlayer;
}

2.把这个播放器的容器View加到屏幕上:

  [self.view addSubview:self.danmakuPlayer.containerView];

3.给这个Player加一些轨道:
Player支持自定义就是主要体现在自定义轨道和弹幕样式上,所以,所有的轨道都是你亲手加上去的,你可以在init/viewDidLoad等初始化的时机做这个时,也可以在Player懒加载时一并加好

- (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.让播放器动起来!
现在这个播放器就可以从外界接口随便一个弹幕并播放在屏幕上了

- (void)startPlay {
  [self.danmakuPlayer start];
}

5.让我们尝试放一个简单的弹幕放上去:

(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]];
}

这个框架尽量使用最符合正常逻辑的方法定义了每个组件的分工来保证它使用起来是最舒服的,并尽可能封装了那些看起来比较复杂的逻辑:分发、刷新、追赶等等;当然,我觉得一个合理的框架应该是下限很低,上限也很高的,而不是一成不变使用规则(正如掌控疾风的某位男子应该算得上是设计得比较成功的角色),所以,当使用者需要深入探讨这些逻辑的时候,也可以从外部轻易定制他们,玩出自己的特色。

后续会陆续更新一些使用上或是原理方面的文章介绍这个框架,虽然实现起来没有很多高超的技巧,但我认为代码优秀与否并非取决于使用了多么高深或是精妙的语言特性,而是写代码的逻辑和思路;而且,我从心底十分抵制那些没什么复杂逻辑却要制定很多使用规则的组件(更恶心的是还要业务线强推),所以这个组件一定会朝着尽量少的使用规则、尽量朴素的代码、更丰富的功能方向发展。

最后附上几个Demo中的效果图

横向的轨道

pop动画轨道

波浪轨道+轨道分组

心形轨道

到此这篇关于iOS弹幕组件LNDanmakuMaster的具体使用的文章就介绍到这了,更多相关iOS弹幕组件LNDanmakuMaster内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 代码详解iOS视频直播弹幕功能

    本篇内容通过步骤详细给大家讲解了iOS视频直播弹幕的原理以及实现代码分析,以下就是全部内容: 1.弹幕的实现性分析 首先,从视觉上明确当前弹幕所具有的功能 从屏幕右侧滑入左侧,直至完全消失 不管是长的弹幕,还是短的弹幕,速度一致(可能有的需求是依据弹幕长度,调整速度) 有弹幕轨道,不是随机产生的弹幕 弹幕不会进行重叠 接下来从功能角度思考需要做什么 重用机制,类似tableView有一个重用池,每个弹幕就是一个cell,当有弹幕发送的时候,如果当前的重用池没有控件,则创建一个新的控件,如果重用池

  • ios弹幕高效加载实现方式实例代码

    看直播的童鞋们应该会经常看到满屏幕的滚动弹幕,看到密密麻麻的弹幕第一印象就是怎么样高效加载来避免卡顿,弹幕组成部分包含用户头像.用户昵称.弹幕的内容.表情等,本文介绍的实现原理就是把这几部分绘制成一张图片,然后通过定时器移动弹幕图片,当图片不在屏幕范围内即销毁. 先看下效果 下面我会详细介绍下实现原理 1 .获取弹幕数据来源,因为我是模拟生成弹幕,弹幕的数据存放在工程里的plist文件中 emotions存放这条弹幕的表情,type表示是否是自己发的,text表示弹幕内容,userName表示用

  • iOS 弹幕功能的实现思路图解

    先来看一张效果图(LICEcap录制的有点卡, 凑合看) 理一下大概流程: 接下来实现: 弹幕视图从底部弹上来, 依次动画向上滚动, 出屏幕就移除加入重用队列, 下次使用. 定义相关属性: 1. 根据弹幕区域, 确定总共需要的弹幕itemView个数(总区域高度/最小高度),并添加到弹幕控件底部 追加一条新数据(由于需要动画处理, 当前数据动画完成后才能处理下一条数据,这里需要定义两个区:正在处理区和等待处理区) 追加数据并弹出 从处理区取出itemView并初始化其将要展示的位置,计算宽高,

  • IOS 实现简单的弹幕功能

    前言 简单实现弹幕功能,表跟我谈效率,但也有用队列控制同时弹的数量. 正文 代码实现: let DANMAKU_SPEED: CGFloat = 150 // 弹幕每秒移动速度 let DANMAKU_SPACE_TIME: NSTimeInterval = 1 // 弹幕之间的时间间隔 let DANMAKU_MAX_ROW = 3 // 最多同时弹幕行数 let danmakuFont = UIFont.systemFontOfSize(18) // 弹幕字体大小 var rowArray

  • iOS弹幕开发中遇到的问题汇总

    前言 弹幕在现在的各类视频中都有,也是每位开发者们必须会的一个功能,最近在开发中就遇到了一些问题,下面简单说说弹幕开发碰到的两个小问题. 正文 需求:实现一个弹幕容器,里面同时会有多行互不重叠的.运动中的弹幕 .每一条弹幕均需要支持点击事件. 用脚底板想的方法:在弹幕容器里面创建几个 UIButton,并且 addTarget,增加点击事件.最后利用 UIView 的 block API 实现动画. 结果:嗯...可惜的是,代码运行起来,你会发现在 UIButton 运动过程,点击事件并没有响应

  • iOS弹幕组件LNDanmakuMaster的具体使用

    LNDanmakuMaster是一个轻量的弹幕播放器,通过:创建播放器->创建轨道->添加弹幕的方式进行弹幕播放,提供丰富轨道样式的同时也支持自定义轨道:对传入的弹幕的视图层没有要求(任意的View/Layer):提供多种(目前是3)弹幕分布策略:支持使用轨道组播放特殊弹幕:提供与分布策略的对应的弹幕seek策略. Github链接:LNDanmakuMaster 你可以直接下载这个链接并运行上面丰富的Demo,或参考Demo代码实现自己的弹幕播放器,也可以直接使用Cocoapods

  • 使用canvas实现一个vue弹幕组件功能

    看B站时,对弹幕的实现产生了兴趣,一开始想到用css3动画去实现,后来感觉这样性能不是很好,查了下资料,发现可以用canvas实现,于是就摸索着写了一个简单的弹幕. 弹幕功能 支持动态添加弹幕 弹幕不重叠 自定义弹幕颜色 效果图 demo 源码地址 前端框架选了比较熟悉的vuejs 弹幕滚动的基本思路就是通过定时器不断地改变弹幕的位置,时时重绘画布. 实现步骤 先加入一个canvas标签,这里有个注意点,关于设备像素比对canvas的影响,会出现绘图模糊. <canvas width="6

  • 原生JavaScript实现弹幕组件的示例代码

    前言 如今几乎所有的视频网站都有弹幕功能,那么今天我们就自己用原生 JavaScript 封装一个弹幕类.这个类希望有如下属性和实例方法: 属性 el容器节点的选择器,容器节点应为绝对定位,设置好宽高 height 每条弹幕的高度 mode 弹幕模式,half则为一半容器高度,top为三分之一,full为占满 speed弹幕划过屏幕的时间 gapWidth后一条弹幕与前一条弹幕的距离 方法 pushData 添加弹幕元数据 addData持续加入弹幕 start开始调度弹幕 stop停止弹幕 r

  • IOS小组件实现时钟按秒刷新功能

    引言   上一节中我们了解了IOS小组件的刷新机制,发现根本没法实现按秒刷新,但是看别的App里面有做到,以为用了什么黑科技,原来是因为系统提供了一个额外的机制实现时间的动态更新,不用走小组件的刷新机制. Text控件支持显示日期时间,下面是来自官网的代码 计算时间差 let components = DateComponents(minute: 11, second: 14) let futureDate = Calendar.current.date(byAdding: components

  • vue封装一个弹幕组件详解

    目录 前言 功能实现 1.获取随机颜色 随机数生成 随机颜色编码生成 2.随机生成弹幕出现的高度坐标 3.格式化弹幕对象 颜色 定位 4.创建弹幕对象 滚动动画定义 创建弹幕dom对象实例 弹幕销毁 弹幕循环 5.实时弹幕发送 html JavaScript 源码地址 前言 现在很多地方都有使用到弹幕,最近在捣鼓自己的个人博客网站,也想着在里面加入一个弹幕模块,所以在这里封装了一个可复用的弹幕组件,目前已经实现了基本的功能,可能还会有存在缺陷,后续会继续优化.这里给大家介绍分享一下实现的过程.

  • vue.js实现仿原生ios时间选择组件实例代码

    前言 最近几个月一直在看VUE,然后试着只用原生js+vue实现某些组件. PC端时间选择组件 这是最开始实现的pc上的时间选择,平时移动端也在做,所以就想实现一下移动端的时间选择器,下面分享一下我实现移动端滚轮特效时间选择器的思路和过程.整个组件是基于vue-cli来进行构建的 功能 1.时间选择[ A.年月日选择 B.年月日小时分钟选择 C.小时分钟选择 D.分钟选择] 2.滚轮效果[ A.构成一个圆环首尾相连 B.不构成首尾相连] 3.时间选择范围设置(所选时间超过范围将弹窗提示),分钟间

  • iOS常用组件之高效切圆角的方法汇总

    前言 圆角(RounderCorner)是一种很常见的视图效果,相比于直角,它更加柔和优美,易于接受.但很多人并不清楚如何设置圆角的正确方式和原理. iOS 客户端开发中,经常碰到圆角视图的需求,本文简单总结一下 UIView 及其子类的一些切圆角方法,并且保证避免出现离屏渲染.下面话不多说了,来一起看看详细的介绍吧. UIView(不包括其子类) UIView *view = [[UIView alloc] init]; view.backgroundColor = [UIColor blac

随机推荐