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内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

时间: 2021-02-02

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

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

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

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

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

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

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

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

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实现简单的头部缩放功能

本文通过实例代码给大家介绍了iOS实现简单的头部缩放功能.实现思路有头部视图,滚动视图,控制头部动画等多个示例代码块,大家可以参考下本文. 简单实现并集成一个头部缩放的功能,适用于UIScrollView以及其子类. 头部伴随模糊效果放大缩小,并在一定位置时悬停充当导航栏.这里提供实现思路,如有符合可直接使用. 效果如下图. 实现: 首先分解为两部分,一部分为头部视图,一部分为滚动视图.头部视图负责展示,滚动视图负责控制头部视图如何展示,比如放大和缩小. 一:头部视图 头部视图拆解为负责展示图片

微信小程序 弹幕功能简单实例

1.微信小程序----弹幕的实现(无后台) 小程序刚刚出来,现在网上的demo是多,但是要找到一个自己需要的却不容易.今天跟大家分享自己写的一个弹幕功能. 效果图: 我的思路是这样的,先用<switch>标签确定是否打开弹幕,若打开弹幕则出现弹幕文本框和发射按钮,还有弹幕遮罩层. 先贴wxml和wxss代码. wxml代码如下: <!-- pages/index/index.wxml --> <swiper indicator-dots="{{indicatorDo

React Native实现简单的登录功能(推荐)

React Native 简介: React Native 结合了 Web 应用和 Native 应用的优势,可以使用 JavaScript 来开发 iOS 和 Android 原生应用.在 JavaScript 中用 React 抽象操作系统原生的 UI 组件,代替 DOM 元素来渲染等. React Native 使你能够使用基于 JavaScript 和 React 一致的开发体验在本地平台上构建世界一流的应用程序体验.React Native 把重点放在所有开发人员关心的平台的开发效率上

Android实现炫酷的网络直播弹幕功能

现在网络直播越来越火,网络主播也逐渐成为一种新兴职业,对于网络直播,弹幕功能是必须要有的,如下图: 首先来分析一下,这个弹幕功能是怎么实现的,首先在最下面肯定是一个游戏界面View,然后游戏界面上有弹幕View,弹幕的View必须要做成完全透明的,这样即使覆盖在游戏界面的上方也不会影响到游戏的正常观看,只有当有人发弹幕消息时,再将消息绘制到弹幕的View上面就可以了,下方肯定还有有操作界面View,可以让用户来发弹幕和送礼物的功能,原理示意图如下所示: 参照原理图,下面一步一步来实现这个功能.

Android仿iOS侧滑退出当前界面功能

我们都知道在ios手机上面,有一个侧滑退出当前界面的功能,但是在安卓手机上系统没有给我们提供这样的功能,但是这依然阻挡不了强大的安卓的定制功能,我们完全可以自己定制一套这样的功能. 首先看下效果图: 分析: (1)要想模仿ios的这种效果,因为我们通过手指的滑动,所以这里肯定跟我们的滑动事件有关系(onInterceptTouchEvent,onTouchEvent这两个方法的关系,如果不清楚,请直接查阅事件传递机制原理) (2)我们要想直接拦截我们的所有触摸事件,我们可以在上层父级布局中进行拦

Android 实现仿网络直播弹幕功能详解及实例

Android 网络直播弹幕                最近看好多网络电视,播放器及直播都有弹幕功能,自己周末捣鼓下并实现,以下是网上的资料,大家可以看下. 现在网络直播越来越火,网络主播也逐渐成为一种新兴职业,对于网络直播,弹幕功能是必须要有的,如下图: 首先来分析一下,这个弹幕功能是怎么实现的,首先在最下面肯定是一个游戏界面View,然后游戏界面上有弹幕View,弹幕的View必须要做成完全透明的,这样即使覆盖在游戏界面的上方也不会影响到游戏的正常观看,只有当有人发弹幕消息时,再将消息绘

Flutter 实现虎牙/斗鱼 弹幕功能

用Flutter实现弹幕功能,轻松实现虎牙.斗鱼的弹幕效果. 先来一张效果图: 实现原理 弹幕的实现原理非常简单,即将一条弹幕从左侧平移到右侧,当然我们要计算弹幕垂直方向上的偏移,不然所有的弹幕都会在一条直线上,相互覆盖.平移代码如下: @override void initState() { _animationController = AnimationController(duration: widget.duration, vsync: this) ..addStatusListener

Angularjs制作简单的路由功能demo

从官网下载了最新版本的Angularjs 版本号:1.3.15 做一个简单的路由功能demo 首页:index.html <!DOCTYPE html > <html> <head> <meta charset="utf-8" /> <title>测试</title> <script src="./js/angular.min.js"></script> <scri