@@ -59,3 +59,91 @@ container.style.transform = "scale(" + scale + ")";
5959```
6060
6161进而通过让用户设置 ` options.global.className = 'cmt bold' ` 即可开启/关闭粗体等等。
62+
63+ ### 实时弹幕支持 Live Comments
64+ 实时弹幕也需要后端服务器的支持,而且比发送弹幕要复杂一些。实时弹幕可以采取Polling(定时读取)或者
65+ Push Notify(监听等待)两个主动和被动模式实现。实时弹幕还有绝对实时和相对性时间轴更新两个时间模式。
66+
67+ - Polling
68+
69+ Polling是指设计的弹幕播放器定时访问服务器,询问服务器在某个弹幕池内某段时间后新产生的弹幕,然后把它
70+ 添加到播放列表或者呈现出来的一种简单的模式。优点是:仅仅基于HTTP,可以在各种服务器(VPS、云、
71+ 共享主机)和语言(PHP,Python,Ruby,Nodejs)上实现。缺点是:需要反复联网,效率底下,对服务
72+ 器压力大。
73+
74+ 推荐用于实时性不强的系统。
75+
76+ - Push Notify
77+
78+ Push Notify是指在客户端连接到服务器的一个端口,在有新的弹幕时,服务器主动发送弹幕信息,而客户
79+ 端在收到信息后被动的呈现或者更新列表。优点:速度快,效率高,处理开销低。缺点:需要用Websockets
80+ 或者Flash作为桥,要么兼容性略差一点(虽然几乎现代浏览器都支持Websockets 了),要么性能不好。
81+
82+ 推荐用于非常实时的系统,如不可回看的直播间等。
83+
84+ 时间轴模式也不一样
85+
86+ - 绝对实时
87+ 每当收到实时弹幕就直接显示,不保存或者少量保存历史弹幕,不能自由的回看。占用内存小。
88+
89+ - 实时时间轴
90+ 定期更新时间轴,把弹幕按顺序正确插入,保持弹幕时间轴新鲜度,可以自由更改播放时间。
91+
92+ 下面是两个模式的一些参考伪代码:
93+
94+ // Polling example code
95+
96+ var hasLastCheckReturned = true; // 标记之前检测是否已经完成,避免服务器过载
97+ var lastCheckedTime = 0; // 上次检测时间
98+ setTimeout(function(){
99+ if(!hasLastCheckReturned){
100+ return; // 上次还没返回结果。放弃这次请求。
101+ }
102+ var xhr = new XMLHttpRequest();
103+ xhr.onreadystatechange = function(){
104+ if(xhr.readyState === 4){
105+ if(xhr.responseCode === 200){
106+ // 解析弹幕
107+ var danmakuList = yourFormatParser(xhr.responseText);
108+ for(var i = 0; i < danmakuList.length; i++){
109+ CM.insert(danmakuList[i]); // 把增量弹幕每一个都插入
110+ };
111+ lastCheckedTime = Date.now(); // 更新上次检测的时间
112+ hasLastCheckReturned = true;
113+ } else {
114+ // 可能出了问题
115+ hasLastCheckReturned = true;
116+ }
117+ }
118+ };
119+ xhr.open('GET', 'http://yoururl/somevideoid/?from=' + lastCheckedTime, true); // 告诉服务器上次检查的时间,来获取增量
120+ xhr.send(); // 发送请求
121+ hasLastCheckReturned = false;
122+ }, 3000); // 每3s检查新的弹幕
123+
124+ 以及:
125+
126+ // Push notify example code
127+ // 基于 socket.io 和 JQuery来简化代码
128+
129+ var socket = io(); //开启流
130+
131+ socket.on('danmaku', function(data){
132+ // 当遇到 danmaku 事件,就把推送来的弹幕推送给 CCL
133+ var danmaku = yourFormatParser(data);
134+ CM.insert(danmaku);
135+ });
136+
137+ $('#send-danmaku-btn').click(function(){
138+ //当按了发送弹幕的按钮
139+ var data = {
140+ "text":"获取信息。。"
141+ ...
142+ };// 通过UI获取新弹幕的信息
143+
144+ //包装并发射弹幕
145+ socket.emit('send-danmaku', JSON.stringify(yourFormatPackager(data));
146+
147+ //清除 UI 文字部分
148+ $('#send-danmaku-field').value("");
149+ });
0 commit comments