闲的蛋疼系列之看看B站弹幕的实现方式……

关键词

XML、DOMParser、requestAnimationFrame

简述

  • 拉取数据 PC版 弹幕数据是从服务端一次性拉取过来的,数据格式为text/xml
    如弹幕数据

额外说一下 之前b站有爆弹幕的事件 比如30万弹幕这种 现在的弹幕机制貌似 最多3000 超过旧的就会被新的顶掉。
普通一个400万播放量的视频 有效弹幕也只有1000-2000之间 已经很不错了

闲的蛋疼系列之看看B站弹幕的实现方式……_第1张图片
image.png

代码位置在return new q(a,b)处 a为弹幕获取的配置参数


闲的蛋疼系列之看看B站弹幕的实现方式……_第2张图片
image.png

闲的蛋疼系列之看看B站弹幕的实现方式……_第3张图片
image.png
  • 解析数据 通过DOMParser方法 对应源码标示.Pz方法
  • load弹幕 这个过程主要是将弹幕数据结构化,采用的应该是数组 通过4891行组成基本的数据对象 add进去


    闲的蛋疼系列之看看B站弹幕的实现方式……_第4张图片
    image.png

    闲的蛋疼系列之看看B站弹幕的实现方式……_第5张图片
    image.png
  • 数据结构
    原始数据在o数组中
    承载原始弹幕数据 o数组


    闲的蛋疼系列之看看B站弹幕的实现方式……_第6张图片
    image.png

    ea数组里存放的为当前批次要渲染的弹幕对象 包含丰富的弹幕位置、颜色、速度等信息 还包括渲染方法(在原型链里)。承载单条弹幕 ea对象

承包小姐姐
闲的蛋疼系列之看看B站弹幕的实现方式……_第7张图片
image.png

闲的蛋疼系列之看看B站弹幕的实现方式……_第8张图片
image.png
  • 渲染弹幕 通过直接create node的方式渲染弹幕
    是核心函数之一 在它之前的几个函数 分别是.Mz .Dg 作用是启动渲染 每次渲染都是以Array.shift方式 弹出首位弹幕 动画结束后 检查ea数组长度 结合 是否暂停 paused参数 来决定是否继续requestAnimationFrame


    闲的蛋疼系列之看看B站弹幕的实现方式……_第9张图片
    image.png

插入弹幕的方法

image.png
a.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"等 还有一些日志收集 有时间可以再看一看 学习学习。

你可能感兴趣的:(闲的蛋疼系列之看看B站弹幕的实现方式……)