`

bilibili弹幕类型网站的HTML5完美实现

阅读更多

我们今天用html5来实现国内知名弹幕网站bilibili的功能, 首先要后段配合前端, 然后一切都会变得很简单
下面先说说弹幕文件的分析



言归正传,播放器的弹幕列表是一个XML格式文件,它的地址是:
http://www.bilibili.tv/视频的cid.xml

关于cid的获取可以使用bilibili弹幕网API, wiki.bilibili.tv 我这里就不说了

在IE中输入这个文件,我们可以看到:
<?xml version="1.0" encoding="UTF-8" ?>

<d p="0,1,25,16777215,1312863760,0,eff85771,42759017">前排占位置</d>


<d p="16.6,1,25,16777215,1312863769,0,0edc8d09,42759052">站位..</d>


<d p="0,1,25,16777215,1312863770,0,658291b6,42759064">诶 蘑菇汤出了~</d>

内容部分
<d p="0,1,25,16777215,1312863760,0,eff85771,42759017">前排占位置</d>

这行内容的意义呢
先说内容“前排站位置”就不解释了
p这个字段里面的内容:
0,1,25,16777215,1312863760,0,eff85771,42759017
中几个逗号分割的数据
第一个参数是弹幕出现的时间 以秒数为单位。
第二个参数是弹幕的模式1..3 滚动弹幕 4底端弹幕 5顶端弹幕 6.逆向弹幕 7精准定位 8高级弹幕
第三个参数是字号, 12非常小,16特小,18小,25中,36大,45很大,64特别大
第四个参数是字体的颜色 以HTML颜色的十位数为准
第五个参数是Unix格式的时间戳。基准时间为 1970-1-1 08:00:00
第六个参数是弹幕池 0普通池 1字幕池 2特殊池 【目前特殊池为高级弹幕专用】
第七个参数是发送者的ID,用于“屏蔽此弹幕的发送者”功能
第八个参数是弹幕在弹幕数据库中rowID 用于“历史弹幕”功能。

比如
<d p="166.1,1,25,16777215,1312864104,0,ce083fe2,42760591">安全帽....安全X也不见得就一定安全啊</d>

一句代表着:
在整个视频166.1秒的时候,上部出现普通滚动弹幕,字号为12,颜色为16777215(10进制,16进制为&HFFFFFF,即白色),弹幕的发布日期为1312864104(UNIX时间戳,为1970年1月1日8时到弹幕发布时间之间的秒数差),弹幕发出者的ID为ce083fe2,内容为:“安全帽。。。。。”


然后我们就可以开始用php把弹幕抓下来分析了

PHP代码 
  1. <?php
  2. error_reporting(0);
  3. $cid = $_GET['c'];
  4. if (!is_numeric($cid))
  5. {
  6.     die('not vaild cid');
  7. }
  8. header('Content-Type: text/javascript; charset=utf-8');
  9. //$danmaku = file_get_contents('d.xml');
  10. $url = 'http://comment.bilibili.tv/'.$cid.'.xml';
  11. $header = array(
  12.     "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.152 Safari/537.36",
  13.     "Cookie: sid=4d0833b9; pgv_pvi=3868490752; DedeUserID=269563; DedeUserID__ckMd5=49d806d3343627e2; SESSDATA=2f6fa663%2C1396281758%2Cf3077cb7; _cnt_dyn=0; _cnt_pm=0; _cnt_notify=5; __utma=107677085.885893332.1388156294.1394854794.1394860318.91; __utmz=107677085.1394800027.86.20.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=(not%20provided)",
  14. );
  15. $ch = curl_init();
  16. curl_setopt($ch, CURLOPT_URL, $url);
  17. curl_setopt($ch, CURLOPT_ENCODING, 'gzip');
  18. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  19. curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
  20. $danmaku = curl_exec($ch);
  21. //die($danmaku);
  22. preg_match_all('/<d.*?p="(.*)">(.*)?<\/d>/'$danmaku$raw);
  23. //print_r($raw);
  24. //exit;
  25. foreach ($raw[1] as $value)
  26. {
  27.     $foo = explode(','$value);
  28.     $time[] = round($foo[0] * 1000) / 1000;
  29.     unset($foo[0]);
  30.     $param['s'][] = array_values($foo);
  31. }
  32. $param['d'] = $raw[2];
  33. //print_r($time);
  34. function danmakusort($a$b)
  35. {
  36.   if ($a == $breturn 0;
  37.   return ($a > $b) ? 1 : -1;
  38. }
  39. usort($time'danmakusort');
  40. //print_r($time);
  41. //print_r($param);
  42. foreach ($time as $key => $value)
  43. {
  44.     $dmk['t'][] = $value;
  45.     $dmk['s'][] = $param['s'][$key];
  46.     $dmk['d'][] = $param['d'][$key];
  47. }
  48. //print_r($dmk);
  49. if (isset($_GET['debug']))
  50. {
  51.     foreach ($dmk['t'as $key => $value)
  52.     {
  53.       $s = $dmk['s'][$key];
  54.       $s = array_reverse($s);
  55.       $s[] = $value;
  56.       $s = array_reverse($s);
  57.       $s = implode(','$s);
  58.       echo '<d p="'.$s.'">'.$dmk['d'][$key].'</d>'."\n";
  59.     }
  60. }
  61. else
  62. {
  63.     $res = json_encode($dmk);
  64.     if ($res == null or $res == 'null')
  65.     {
  66.       unset($res);
  67.       $res['error'] = 'could not fetch';
  68.       $res = json_encode($res);
  69.     }
  70.     die('callback('.$res.')');
  71. }

思路如下
1.先用php抓bilibili的xml弹幕, 这里用curl实现, 记得替换成你自己的cookie
2.按时间排序每一条弹幕
3.用正则解析xml, 并且输出json格式的弹幕方便前端解析


然后为了方便使用, 我的前端就转变为json, json弹幕格式示范可以看这里
http://12dora.sinaapp.com/pre/n.php?c=1456367&callback=callback&_=1395639194178
t属性里面储存所有弹幕的时间
d就是文字
s就是各种属性, 颜色字体什么的

然后就是前端解析部分, 主要分两大部分, 这里把后端库贴出来,代码很简单, 我这里大概说个思路
后端js库: http://12dora.sinaapp.com/static/js/danmaku.js
前端js库(偷懒直接写主页) h
ttp://12dora.sinaapp.com/index.html

 

1. 后端init()函数, 负责把json弹幕格式解析为元素存入全局变量
2.绑定setInterval事件, 10毫秒抓一次video tag的播放时长, 然后读入弹幕数组的第一条, 如果时间差在20毫秒内则交由gennerate_danmaku()生成弹幕并且显示
3.移动指针到下一条(这里不用遍历, 因为服务器已经按时间排序了, 所以如果当前指针的弹幕时间还没到后面的肯定时间也没到)
说一下gennerate_danmaku()函数的功能:
1.读取当前弹幕画布哪一行是空的, 指派弹幕位置
2.读取设置并用css描述设置(例如字体颜色...), 并且生成一个css3动画绑定到本条弹幕上

然后说一下前端, 前端用了一个video标签读入视频, 然后用一个一模一样大小的div用position absolute重叠在上面, 作为弹幕显示的虚拟画布, 方便控制, 这个相信各位都能轻松做出来.

然后就是弹幕动画部分, 这里我采用了css3的动画属性, 有的人建议我用canvas这样子性能会高, 不过canvas的话功能十分有限, 例如你想把当前评论的文字复制下来的话, canvas是完全无法做到的, 所以我这里采用原始的div, 每一条弹幕指派一个div, 并且赋予一个独一无二的id方便css3动画绑定元素, 而css3动画的话, 需要特别注意的是如果用from left:0px to left:100px 这样的语法整个页面弹幕一多就会崩溃, 所以这里选择用css3的translate属性, 因为这个会有硬件加速.

JavaScript代码 
  1. var classNameGen = function(charsLength,chars) {
  2. var length = charsLength;
  3. if (!chars)
  4. var chars = "abcdefghijkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ1234567890";
  5. var randomChars = "";
  6. for(x=0; x<length; x++) {
  7. var i = Math.floor(Math.random() * chars.length);
  8. randomChars += chars.charAt(i);
  9. }
  10. return 'h' + randomChars;
  11. };

上面的就是生成唯一id的函数, 然后绑定一个onanimationend事件, 让动画播放完毕就直接回收div.
**提示, css3的class名字不能以数字开头, 这个必须要注意, 不然那个class就会失效

然后贴一个单条弹幕的css例子

JavaScript代码 
  1. .hPMBMafziBSEheRYi {
  2.     text-shadow: 1px 1px 1px #000000;
  3.     left: 1109px;
  4.     top: 0px;
  5.     color: #FFFFFF;
  6.     -webkit-animation: hPMBMafziBSEheRYi linear 5s;
  7.     -webkit-animation-iteration-count: 1;
  8.     -webkit-transform-origin: 50% 0%;
  9.     -webkit-backface-visibility: hidden;
  10.     -webkit-perspective: 1000;
  11. }
  12. @-webkit-keyframes hPMBMafziBSEheRYi {
  13.     from {
  14.       -webkit-transform: translate3d(1px, 0, 0);
  15.     }
  16.     to {
  17.       -webkit-transform: translate3d(-1194px, 0, 0);
  18.     }
  19. }

text-shadow是为了加一个阴影以免弹幕与背景一体色, 然后另外的重点就是-webkit-transform, 这样子写会比left定位效率高得多, 还有动画规则的话, 这里用了线性5秒动画, 有需求可以自己改, 5秒算是比较接近官方速度的了

这个技术其实不只是可以令html5的设备可以播放弹幕, 而且只要网站允许的话, 其实每一个网站都可以为自己的视频加上一层弹幕, 增加访客看视频的互动性.

 

***还有补充一点, 上面没提到的, 就是因为我们需要为每一条弹幕的css style绑定一个动画, 这个是不能直接用style=""来解决的, 所以必须生成一个<style></style>去储存, 然后现在js没有原生函数可以去删除一个class, 所以我这里把每一条弹幕都生成了一个<style>标签, 动画完成之后直接回收对应的弹幕<div>还有<style>标签, 免去了正则匹配删除class的麻烦事

最后发一个demo
http://12dora.sinaapp.com/
希望以后css的动画功能更加强大, 可以把繁杂的flash抛弃还希望可以把弹幕这种文化普及, 因为这种弹幕形式的评论交流实在是太赞了!

 

http://cloudbbs.org/forum.php?mod=viewthread&tid=21977

分享到:
评论

相关推荐

    bilibili代码弹幕初阶入门教程

    本教程旨在帮助新手快速上手 bilibili 弹幕的编写,内容涵盖了基本的弹幕编写、变量的使用、文本弹幕对象的创建、绘图弹幕对象的创建、Utils 工具库的使用等方面。通过本教程的学习,您将掌握 bilibili 弹幕的基本...

    bilibili弹幕库图文弹幕的实现

    总的来说,实现B站弹幕库的图文弹幕功能涉及到多个组件的协同工作:处理图片的工具类、管理弹幕发送和显示的控制类、优化内存使用的缓存类、作为入口的活动类以及定义界面的布局文件。每个部分都需要精心设计和优化...

    弹幕技术革新下视频社交的互动新形式研究——以Bilibili弹幕视频网为例.pdf

    弹幕技术革新下视频社交的互动新形式研究——以Bilibili弹幕视频网为例.pdf弹幕技术革新下视频社交的互动新形式研究——以Bilibili弹幕视频网为例.pdf弹幕技术革新下视频社交的互动新形式研究——以Bilibili弹幕视频...

    基于Java的Bilibili弹幕截取小程序

    网络爬虫是自动抓取网页信息的一种程序,用于Bilibili弹幕截取,主要是获取视频的弹幕信息。在这个小程序中,可能使用了Java的HttpURLConnection或者第三方库如Apache HttpClient、OkHttp等来发送HTTP请求到Bilibili...

    p2p版bilibili弹幕.zip

    高仿bilibili 弹幕播放器 直接上传网站就可使用源代码支持二开,弹幕库如果失效,请修改index.php文件里的弹幕地址:https://danmu.izhuolin.cn/3.0/ 上传源码,调用方法:您的域名/p2p/?url= 测试链接:...

    基于Python和JavaScript的Bilibili弹幕下载播放HTML设计源码

    该项目是一款利用Python和JavaScript技术实现的Bilibili弹幕下载与播放系统,源码包含26个文件,具体包括8个Python脚本、5个JavaScript文件、4个Markdown文档、3个HTML文件、2个Git忽略规则文件、2个JSON配置文件、1...

    最新哔哩bilibili视频弹幕播放器带后台版本完整无错_站长亲测.zip

    2、修复弹幕后台管理登录系统后门 3、修复安装程序界面没有样式问题 4、后台登录支持输出账号与密码了,更改用户名与密码请修改 dmku 文件夹下的 config.inc.php 文件 5、修复在播放器中右键菜单点击后自动在新窗口...

    Bilibili直播弹幕库-windows-v1.1.2

    《Bilibili直播弹幕库-windows-v1.1.2》是一款专为Bilibili(哔哩哔哩)直播爱好者设计的应用程序,旨在提供更加便捷的直播互动体验。这款软件能够在Windows操作系统上运行,适用于x86-64架构的计算机。通过与B站...

    高防bilibili弹幕播放器1.5.zip

    高防bilibili弹幕播放器1.5.zip。

    HTML5手机视频弹幕文字评论代码

    HTML5手机视频弹幕文字评论代码是利用现代Web技术实现的一种增强用户互动体验的功能,尤其在视频播放领域,它允许用户在观看视频的同时发送实时的评论或者反馈,这些评论会以文字的形式在视频画面上飘过,类似于许多...

    精选_基于python实现的Bilibili弹幕检索系统_源码打包

    【标题】"精选_基于python实现的Bilibili弹幕检索系统_源码打包" 提供的是一个使用Python编程语言开发的Bilibili弹幕检索系统。这个系统旨在帮助用户快速、有效地搜索Bilibili平台上的弹幕内容,可能是为了进行数据...

    使用爬虫获取bilibili弹幕, 支持protobuf格式的全弹幕抓取.zip

    遵守规则: 为避免对网站造成过大负担或触发反爬虫机制,爬虫需要遵守网站的robots.txt协议,限制访问频率和深度,并模拟人类访问行为,如设置User-Agent。 反爬虫应对: 由于爬虫的存在,一些网站采取了反爬虫措施...

    demo_使用bilibili框架制作弹幕效果

    demo_使用bilibili框架制作弹幕效果

    bilibili_player:bilibili 弹幕播放器 for Linux

    bilibili 弹幕视频播放器Linux 版 bilibili 因为 flash 版本停滞于 11 的原因, 许多视频无限小电视而无法观看.虽然用 F12 大法可以获取视频地址然后 vlc 播放, 但是木弹幕了啊! 没弹幕我还不如直接下高清的看了.无吐...

    基于 SpringBoot 的仿 bilibili 弹幕网开发.zip

    基于 SpringBoot 的仿 bilibili 弹幕网开发.zip

    无后端的仿 YouTube Live Chat 风格的简易 Bilibili 弹幕姬.zip

    标题 "无后端的仿 YouTube Live Chat 风格的简易 Bilibili 弹幕姬.zip" 提供的信息表明,这是一个模仿 YouTube Live Chat 功能,为 Bilibili 平台设计的无服务器(无后端)弹幕系统。Bilibili 是中国一个流行的视频...

    基于Python和PHP的24h-raspberry-live-on-bilibili弹幕点播台设计源码

    本项目是基于Python和PHP的24h-raspberry-live-on-bilibili弹幕点播台设计源码,包含26个文件,其中包括9个Python文件、5个JPG图片文件、3个Markdown文件、2个YML文件、2个ASS文件、2个PHP文件、1个all-...

    最新哔哩bilibili视频弹幕播放器/带后台版本/完整无错

    2、修复弹幕后台管理登录系统后门 3、修复安装程序界面没有样式问题 4、后台登录支持输出账号与密码了,更改用户名与密码请修改 dmku 文件夹下的 config.inc.php 文件 5、修复在播放器中右键菜单点击后自动在新窗口...

Global site tag (gtag.js) - Google Analytics