关键词
XML、DOMParser、requestAnimationFrame
简述
- 拉取数据 PC版 弹幕数据是从服务端一次性拉取过来的,数据格式为text/xml
如弹幕数据
image.png额外说一下 之前b站有爆弹幕的事件 比如30万弹幕这种 现在的弹幕机制貌似 最多3000 超过旧的就会被新的顶掉。
普通一个400万播放量的视频 有效弹幕也只有1000-2000之间 已经很不错了
代码位置在return new q(a,b)处 a为弹幕获取的配置参数
image.png
image.png
- 解析数据 通过DOMParser方法 对应源码标示.Pz方法
-
load弹幕 这个过程主要是将弹幕数据结构化,采用的应该是数组 通过4891行组成基本的数据对象 add进去
image.png
image.png -
数据结构
原始数据在o数组中
承载原始弹幕数据 o数组
image.png
ea数组里存放的为当前批次要渲染的弹幕对象 包含丰富的弹幕位置、颜色、速度等信息 还包括渲染方法(在原型链里)。承载单条弹幕 ea对象
承包小姐姐
image.png
image.png
-
渲染弹幕 通过直接create node的方式渲染弹幕
👇是核心函数之一 在它之前的几个函数 分别是.Mz .Dg 作用是启动渲染 每次渲染都是以Array.shift方式 弹出首位弹幕 动画结束后 检查ea数组长度 结合 是否暂停 paused参数 来决定是否继续requestAnimationFrame
image.png
插入弹幕的方法
image.pnga.prototype.wj = function(a, d) {
var b = []
, c = k.rb(this.Hh(a, d));
b[0] = "1px 0 1px " + c + ",0 1px 1px " + c + ",0 -1px 1px " + c + ",-1px 0 1px " + c;
b[1] = "0px 0px 1px " + c + ",0 0 1px " + c + ",0 0 1px " + c;
b[2] = "1px 1px 2px " + c + ",0 0 1px " + c;
c = document.createElement("div");
c.className = "bilibili-danmaku";
c.style.cssText = d.gy;
c.appendChild(document.createTextNode(a.text.replace(/\r/g, "\r\n")));
6 === a.mode ? c.style.right = this.parent.offsetWidth - 1 + "px" : c.style.left = this.parent.offsetWidth - 1 + "px";
c.style.color = k.rb(a.color);
c.style.fontSize = a.size * d.fontsize * (d.fullscreensync ? this.parent.getBoundingClientRect().height / 440 : 1) + "px";
c.style.fontFamily = d.fontfamily + ", Arial, Helvetica, sans-serif";
c.style.fontWeight = d.bold ? "bold" : "normal";
c.style.lineHeight = 1.125;
c.style.opacity = .1 > d.opacity ? .1 : d.opacity;
c.style.textShadow = b[d.fontborder];
a.border && (c.style.border = "1px solid " + k.rb(a.borderColor),
c.style.paddingLeft = "1px",
c.style.paddingRight = "1px");
c.style.filter = "glow(color=#000000,strength=3)";
this.parent.appendChild(c);
return {
Yk: c,
width: c.offsetWidth,
height: c.offsetHeight
}
}
里面还有一堆辅助方法 来保证播放和弹幕的配合 不过从分析代码 还是可以比较清楚的了解实现机制。里面还有一些自定义事件 比如"video_danmaku_load"等 还有一些日志收集 有时间可以再看一看 学习学习。
网友评论