jabbany / CommentCoreLibrary

Javascript Live Comment (Danmaku) Engine Implementation. JS弹幕模块核心,提供从基本骨架到高级弹幕的支持。
http://jabbany.github.io/CommentCoreLibrary/demo
MIT License
1.9k stars 304 forks source link

关于给直播流(m3u8)插入实时的弹幕 #69

Closed zxkane closed 7 years ago

zxkane commented 7 years ago

在收到实时弹幕消息后,我目前的做法是这样的

    var cm = this.cmManager;
                var cmvideo = video;
                cm.insert({
                    stime: (cmvideo.currentTime + 1)*1000,
                    size: 25,
                    color: danmu.color == null ? Math.floor(Math.random()*16777215) : danmu.color,
                    mode: 1,
                    date: Math.floor(Date.now() / 1000),
                    pool: 0,
                    position: "absolute",
                    border: false,
                    text: danmu.text,
                    duration: danmu.duration == null ? 10 : danmu.duration,
                });
                cm.seek(cmvideo.currentTime*1000);

经测试发现在QQ浏览器上完全不显示。使用Chrome,Safari弹幕能显示,但是在网速比较慢的时候,直播流需要缓冲的时候,这时有些弹幕会丢失。

请教是否有更好的方式实现直播流的实时弹幕。

jabbany commented 7 years ago

一般来说直播弹幕(如果直播流不可回看)可以不用 timeline/insert 而是直接用 cm.send(),参考 这里。这样CCL并不保存弹幕,只是收到就立刻显示。

把弹幕插到“视频位置+1”的问题在于插入的同时,有可能视频event已经经过了这个点,弹幕就被跳过去了,如果再往回seek的话,CCL也是会忽略时间跨度小的seek期间内一段弹幕(因为视频event不稳定,普通情况也有可能出现非常短的瞬间倒流),而且向过去大跨度seek会被CCL视为用户拖动时间轴而清除显示区弹幕。

如果又想支持回看的话,一个模式是把弹幕 insert 到现在的位置 - 1 (仅对最新弹幕)来保证肯定不显示,然后 同时 用 send 一次性显示。这样回看的时候就会从timeline派发,而在看直播流最新部分的时候则显示通过 send 实时派发的版本。当然,这样还需要处理服务器接到的“历史弹幕”(比如别人在最新时间之前发送的弹幕需要被插入timeline以便回看的时候能看到)等等。具体的设计就看具体需求了。

zxkane commented 7 years ago

@jabbany 非常感谢你的建议!我最初也是参考的这篇wiki关于实时弹幕的部分

但是文档中无论poll和push的示例代码都是使用的CM.insert(),所以我完全忽略了CM.send()方法。如果将push示例代码中的insert()改为send()会更好的帮助用户理解CCL。

jabbany commented 7 years ago

有道理!这个确实应该改一下文档