Giter Site home page Giter Site logo

bilibili-live-ws's Introduction

bilibili-live-ws npm Node CI

Bilibili 直播 WebSocket/TCP API

LiveWS/KeepLiveWS 支持浏览器 (实验性)

应该支持 bilibili直播开放平台 https://open-live.bilibili.com

注:如果在浏览器环境遇到问题,可以尝试手动指定引入 bilibili-live-ws/browser

API

const { LiveWS, LiveTCP, KeepLiveWS, KeepLiveTCP } = require('bilibili-live-ws')
const live = new LiveWS(roomid)
// 或
const live = new LiveTCP(roomid)

举个栗子:

const live = new LiveWS(14275133)

live.on('open', () => console.log('Connection is established'))
// Connection is established
live.on('live', () => {
  live.on('heartbeat', console.log)
  // 74185
})

或者用TCP (新功能):

const live = new LiveTCP(26283)

live.on('open', () => console.log('Connection is established'))
// Connection is established
live.on('live', () => {
  live.on('heartbeat', console.log)
  // 13928
})

晚上做梦梦到一个白胡子的老爷爷和我说TCP更节约内存哦!

Class: LiveWS / LiveTCP / KeepLiveWS / KeepLiveTCP

(Keep)LiveWS 和 (Keep)LiveTCP 的大部分API基本上一样, 区别在本文末尾有注明

new LiveWS(roomid [, { address, protover, key, authBody, uid, buvid }])

new LiveTCP(roomid [, { host, port, protover, key, authBody, uid, buvid }])

  • roomid 房间号

    比如 https://live.bilibili.com/14327465 中的 14327465

  • address 可选, WebSocket连接的地址

    默认 'wss://broadcastlv.chat.bilibili.com/sub'

  • host 可选, TCP连接的地址

    默认 'broadcastlv.chat.bilibili.com'

  • port 可选, TCP连接的端口

    默认 2243

  • protover 可选 (1, 2, 3)

    默认 2

    • 1 (见 #17)
    • 2 (zlib.inflate)
    • 3 (brotliDecompress)
  • uid 可选, WS握手的 uid #397

  • key 可选, WS握手的 Token #397

  • buvid 可选, WS握手的 Token #397

  • authBody 可选, 可以和 https://open-live.bilibili.com/document/ 配合使用, 会覆盖掉 protover roomid key uid buvid. 如果是 object 会按照握手包编码,如果是 string/Buffer 会直接发送

live.on('open')

WebSocket连接上了

live.on('live')

成功登入房间

live.on('heartbeat', (online) => ...)

收到服务器心跳包,会在30秒之后自动发送心跳包。

  • online 当前人气值

live.on('msg', (data) => ...)

  • data 收到信息/弹幕/广播等

    data的例子: (我simon3000送了一个辣条)

    {
      cmd: 'SEND_GIFT',
      data: {
        giftName: '辣条',
        num: 1,
        uname: 'simon3000',
        face: 'http://i1.hdslb.com/bfs/face/c26b9f670b10599ad105e2a7fea4b5f21c0f0bcf.jpg',
        guard_level: 0,
        rcost: 2318827,
        uid: 3499295,
        top_list: [],
        timestamp: 1555690631,
        giftId: 1,
        giftType: 0,
        action: '喂食',
        super: 0,
        super_gift_num: 0,
        price: 100,
        rnd: '1555690616',
        newMedal: 0,
        newTitle: 0,
        medal: [],
        title: '',
        beatId: '0',
        biz_source: 'live',
        metadata: '',
        remain: 6,
        gold: 0,
        silver: 0,
        eventScore: 0,
        eventNum: 0,
        smalltv_msg: [],
        specialGift: null,
        notice_msg: [],
        capsule: null,
        addFollow: 0,
        effect_block: 1,
        coin_type: 'silver',
        total_coin: 100,
        effect: 0,
        tag_image: '',
        user_count: 0
      }
    }

live.on(cmd, (data) => ...)

用法如上,只不过只会收到特定cmd的Event。

比如 live.on('DANMU_MSG') 只会收到弹幕Event,一个弹幕Event的Data例子如下: (我simon3000发了个233)

{
  cmd: 'DANMU_MSG',
  info: [
    [0, 1, 25, 16777215, 1555692037, 1555690616, 0, 'c5c630b1', 0, 0, 0],
    '233',
    [3499295, 'simon3000', 0, 0, 0, 10000, 1, ''],
    [5, '財布', '神楽めあOfficial', 12235923, 5805790, ''],
    [11, 0, 6406234, '>50000'],
    ['title-58-1', 'title-58-1'],
    0,
    0,
    null,
    { ts: 1555692037, ct: '2277D56A' }
  ]
}

live.on('close')

连接关闭事件

live.on('error', (e) => ...)

连接 error 事件,连接同时也会关闭

live.heartbeat()

无视30秒时间,直接发送一个心跳包。

如果连接正常,会收到来自服务器的心跳包,也就是 live.on('heartbeat'),可以用于更新人气值。

live.close()

关闭WebSocket/TCP Socket连接。

live.getOnline()

立即调用 live.heartbeat() 刷新人气数值,并且返回 Promise,resolve 人气刷新后数值

live.on('message')

WebSocket/TCP收到的Raw Buffer(不推荐直接使用)

live.send(buffer)

使用 WebSocket 或者 TCP 发送信息

getConf(roomid)

选一个cdn,Resolve host, address 和 key, 可以直接放进(Keep)LiveWS/TCP设置

const { getConf } = require('bilibili-live-ws')

getConf(roomid)
// Return
Promise<{
    key: string;
    host: string;
    address: string;
}>

getRoomid(short)

通过短房间号获取长房间号

const { getRoomid } = require('bilibili-live-ws')

getRoomid(255)
// Return Promise<number>: 48743

Keep和无Keep的区别

KeepLiveWS 和 KeepLiveTCP 有断线重新连接的功能

new KeepLiveWS(roomid [, { address, protover, key }])

new KeepLiveTCP(roomid [, { host, port, protover, key }])

所有上方的API都是一样的, 只不过会有以下微小的区别

  • 收到error或者close事件的时候并不代表连接关闭, 必须要手动调用live.close()来关闭连接
  • 内部的连接对象(LiveWS/LiveTCP)在live.connection
  • 内部的连接关闭了之后, 如果不是因为live.close()关闭, 会在100毫秒之后自动打开一个新的连接。
    • 这个100毫秒可以通过改变live.interval来设置
  • 内部的boolean, live.closed, 用于判断是否是因为live.close()关闭。

LiveWS 和 LiveTCP 的区别

LiveWS.ws

LiveWS 内部 WebSocket 对象,需要时可以直接操作

Doc: https://github.com/websockets/ws/blob/master/doc/ws.md#class-websocket

LiveTCP.socket

LiveTCP 内部 TCP Socket 对象,需要时可以直接操作

Doc: https://nodejs.org/api/net.html#net_class_net_socket

LiveTCP.buffer

LiveTCP内部TCP流的Buffer缓冲区,有不完整的包

LiveTCP.splitBuffer()

处理LiveTCP内部TCP流的Buffer缓冲区,把其中完整的包交给decoder处理

BenchMark 简单对比

在连接了640个直播间后过了一分钟左右(@2.0.0)

LiveWS (wss) LiveWS (ws) LiveTCP
内存占用 63 MB 26 MB 18 MB

参考资料: https://github.com/lovelyyoshino/Bilibili-Live-API/blob/master/API.WebSocket.md

贡献

欢迎Issue和Pull Request!

bilibili-live-ws's People

Contributors

bybybybyb avatar dependabot-preview[bot] avatar dependabot[bot] avatar shigma avatar simon300000 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bilibili-live-ws's Issues

未知错误

Connection is established
(node:12659) UnhandledPromiseRejectionWarning: TypeError: packs.flatMap is not a function
at Object.exports.decoder (/home/apple/danmuku/node_modules/_bilibili-live-ws@5.1.0@bilibili-live-ws/src/buffer.js:45:18)
at process._tickCallback (internal/process/next_tick.js:68:7)
(node:12659) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:12659) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
(node:12659) UnhandledPromiseRejectionWarning: TypeError: packs.flatMap is not a function
at Object.exports.decoder (/home/apple/danmuku/node_modules/_bilibili-live-ws@5.1.0@bilibili-live-ws/src/buffer.js:45:18)
at process._tickCallback (internal/process/next_tick.js:68:7)
(node:12659) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)
(node:12659) UnhandledPromiseRejectionWarning: TypeError: packs.flatMap is not a function
at Object.exports.decoder (/home/apple/danmuku/node_modules/_bilibili-live-ws@5.1.0@bilibili-live-ws/src/buffer.js:45:18)
at process._tickCallback (internal/process/next_tick.js:68:7)
(node:12659) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 3)
(node:12659) UnhandledPromiseRejectionWarning: TypeError: packs.flatMap is not a function
at Object.exports.decoder (/home/apple/danmuku/node_modules/_bilibili-live-ws@5.1.0@bilibili-live-ws/src/buffer.js:45:18)
at process._tickCallback (internal/process/next_tick.js:68:7)
(node:12659) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 4)
(node:12659) UnhandledPromiseRejectionWarning: TypeError: packs.flatMap is not a function
at Object.exports.decoder (/home/apple/danmuku/node_modules/_bilibili-live-ws@5.1.0@bilibili-live-ws/src/buffer.js:45:18)

再问个问题

用这个是不是也可以打开官方长连API给的地址呀?

上舰长会报错

舰长消息变了
上舰长会报错

TypeError: Cannot read property 'includes' of undefined
at LiveWS. ( /bilibili-live-ws/src/index.js:38:33)
at runMicrotasks ()
at processTicksAndRejections (internal/process/task_queues.js:93:5)

protover可选性

希望大佬加一下弹幕协议protover项用1的选项

原因是版本2去掉了GUARD_LOTTERY_START的播报

{
    "cmd": "GUARD_LOTTERY_START",
    "data": {
        "id": 1972383,
        "link": "https://live.bilibili.com/3629359",
        "lottery": {
            "asset_animation_pic": "https://i0.hdslb.com/bfs/vc/ff2a28492970850ce73df0cc144f1766b222d471.gif",
            "asset_icon": "https://i0.hdslb.com/bfs/vc/43f488e7c4dca5ba6fbdcb88f40052d56bf777d8.png",
            "id": 1972383,
            "keyword": "guard",
            "mobile_animation_asset": "",
            "mobile_display_mode": 2,
            "mobile_static_asset": "",
            "privilege_type": 3,
            "sender": {
                "face": "http://i0.hdslb.com/bfs/face/3a48db0bf08caf72d551e45073066c156532c2a4.jpg",
                "uid": 1662330,
                "uname": "罗卜卜卜卜卜卜有毒"
            },
            "status": 1,
            "thank_text": "恭喜<%罗卜卜卜卜卜卜有毒%>上任舰长",
            "time": 1200,
            "time_wait": 0,
            "weight": 0
        },
        "payflow_id": "gd_0d4c52a0a8fbb52759_202002",
        "privilege_type": 3,
        "roomid": 3629359,
        "type": "guard"
    }
}

照着用其它语言做了个类似的实现,但是有时候发送心跳会突然断开连接

遇到的情况就是有时候发送完心跳包后连接莫名其妙就断开了,也没有错误提示,直接就触发关闭,但相同的心跳包有时候就正常收到响应,排查了两天也不知道是哪里的问题,心跳包都是一样的,发送间隔的话,感觉因为有网络延迟,差几十毫秒应该也能接受,所以也排除了,第一次连接时发送的数据也都是对的,实在想不出问题出在哪,想问下大佬有没有什么头绪……

报错:KeepLiveTCP is not a constructor

RT:使用KeepLiveTCP 时报错,使用KeepLiveWS时正常

主要环境:

  • win10
  • Google chrome 版本 98.0.4750.0(正式版本)dev (64 位)
  • node 12.16.2
  • vue-cli 4
  • vue 2.6.11
  • bilibili-live-ws 6.2.1

报错截图:
1661399770815

相关代码:

  const { KeepLiveWS, KeepLiveTCP } = require("bilibili-live-ws");
  const live = new KeepLiveTCP(176190);
  live.on("open", () => console.log("Connection is established"));
  live.on("live", () => {
    live.on("msg", (e) => {
      console.log(e);
    });
  });

分别打印了下KeepLiveTCP,KeepLiveWS, 结果:
1661401962704

弹幕用户名打码功能跟进

最近b站开始对弹幕用户名进行随机打码,打码后 UID 返回为 0:

preview

目前观察下来这个功能是灰度的,不是每次都会出现这个情况,有时候主播的弹幕机刷新一下就正常了,但过一会所有 DANMU_MSG 事件又会被打码。具体触发条件未知

监听房间上限

发现监听超过18个房间就会出现错误,无法链接服务器。
Error 5895809 Error: connect ECONNREFUSED 120.92.158.137:443

内存溢出

我在Linux服务器跑脚本时,bilibili-live-ws发生了内存溢出。服务器只记录了溢出时的日志。据推测,溢出前所有直播间连接(20个左右)正在不断尝试重连。
推测重连从10月8日17:00开始。重连前CPU利用率平均6%,内存用量674MB,外网流量正常。之后负载不断升高,到10月9日10:25,CPU利用率100%,内存用量几乎不变,外网出带宽接近满值。10月9日从18:00到23:40,CPU占用仍为100%,但内存占用持续上升到1431MB,之后发生了内存溢出。
重连时弹幕数据都正常记录了。根据数据库中记录的弹幕数据,重连时未发生直播服务器维护等情况。重连时live.on('open')和live.on('live')都执行了。
以下是崩溃日志。

<--- Last few GCs --->
[7181:0x472f9e0] 602648411 ms: Mark-sweep (reduce) 898.5 (909.2) -> 898.5 (910.2) MB, 2830.8 / 0.0 ms  (average mu = 0.240, current mu = 0.004) last resort GC in old space requested
[7181:0x472f9e0] 602651217 ms: Mark-sweep (reduce) 898.5 (909.2) -> 898.4 (910.2) MB, 2805.8 / 0.0 ms  (average mu = 0.136, current mu = 0.000) last resort GC in old space requested
<--- JS stacktrace --->
FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
 1: 0xa25510 node::Abort() [node]
 2: 0x9664d3 node::FatalError(char const*, char const*) [node]
 3: 0xb9a8be v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bool) [node]
 4: 0xb9ac37 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [node]
 5: 0xd56ca5  [node]
 6: 0xd692c1 v8::internal::Heap::AllocateRawWithRetryOrFailSlowPath(int, v8::internal::AllocationType, v8::internal::AllocationOrigin, v8::internal::AllocationAlignment) [node]
 7: 0xd2e9fd v8::internal::Factory::AllocateRaw(int, v8::internal::AllocationType, v8::internal::AllocationAlignment) [node]
 8: 0xd2ac59 v8::internal::FactoryBase<v8::internal::Factory>::AllocateRawArray(int, v8::internal::AllocationType) [node]
 9: 0xd2ad14 v8::internal::FactoryBase<v8::internal::Factory>::NewFixedArrayWithFiller(v8::internal::Handle<v8::internal::Map>, int, v8::internal::Handle<v8::internal::Oddball>, v8::internal::AllocationType) [node]
10: 0xf5705d v8::internal::Handle<v8::internal::StringTable> v8::internal::HashTable<v8::internal::StringTable, v8::internal::StringTableShape>::New<v8::internal::Isolate>(v8::internal::Isolate*, int, v8::internal::AllocationType, v8::internal::MinimumCapacity) [node]
11: 0xf572d6 v8::internal::Handle<v8::internal::StringTable> v8::internal::HashTable<v8::internal::StringTable, v8::internal::StringTableShape>::EnsureCapacity<v8::internal::Isolate>(v8::internal::Isolate*, v8::internal::Handle<v8::internal::StringTable>, int, v8::internal::AllocationType) [node]
12: 0xf57701 v8::internal::Handle<v8::internal::String> v8::internal::StringTable::LookupKey<v8::internal::SeqSubStringKey<v8::internal::SeqTwoByteString> >(v8::internal::Isolate*, v8::internal::SeqSubStringKey<v8::internal::SeqTwoByteString>*) [node]
13: 0xd3020f v8::internal::Handle<v8::internal::String> v8::internal::Factory::InternalizeString<v8::internal::SeqTwoByteString>(v8::internal::Handle<v8::internal::SeqTwoByteString>, int, int, bool) [node]
14: 0xe4eade v8::internal::JsonParser<unsigned short>::MakeString(v8::internal::JsonString const&, v8::internal::Handle<v8::internal::String>) [node]
15: 0xe4f314 v8::internal::JsonParser<unsigned short>::BuildJsonObject(v8::internal::JsonParser<unsigned short>::JsonContinuation const&, std::vector<v8::internal::JsonProperty, std::allocator<v8::internal::JsonProperty> > const&, v8::internal::Handle<v8::internal::Map>) [node]
16: 0xe50ef5 v8::internal::JsonParser<unsigned short>::ParseJsonValue() [node]
17: 0xe515ef v8::internal::JsonParser<unsigned short>::ParseJson() [node]
18: 0xc465b5  [node]
19: 0xc46cb6 v8::internal::Builtin_JsonParse(int, unsigned long*, v8::internal::Isolate*) [node]
20: 0x14269f9  [node]
Aborted (core dumped)

[Question]获取的数据会自动组成队列吗?

如题,这是我的代码:

live.on('DANMU_MSG',data=>{
  const output = data.info[1]
  console.log(output)
  const tts = ()=>{...}
  setTimeout(() => {
    // tts()
  }, 3000);
})

我把output进行输出可以获得弹幕,tts()是将弹幕转为人声播放的代码块,我想使用setTimeout起到弹幕密集时节流的效果,但是似乎只是等一会儿然后继续播放下一个弹幕
需求示意:
直播间弹幕:[弹幕1][弹幕2][弹幕3][弹幕4][弹幕5]
tts弹幕:[播放弹幕1] ...(这里等了3秒)... [播放弹幕5]
然而实际上的情况:
直播间弹幕:[弹幕1][弹幕2][弹幕3][弹幕4][弹幕5]
tts弹幕:[播放弹幕1] ...(这里等了3秒)... [播放弹幕2] ...(这里等了3秒)... [播放弹幕3]...

我以为live.on是自动循环执行,但似乎并非如此...有什么办法能达到我想要的效果吗?

Uncaught (in promise) TypeError: packs.flatMap is not a function

大佬您好。
在electron-vue 项目中使用了 "bilibili-live-ws": "^5.1.1"
node -v :
v14.17.4
运行过程中提示:

Uncaught (in promise) TypeError: packs.flatMap is not a function
    at Object.exports.decoder (F:\git_pro\muamuamua\node_modules\bilibili-live-ws\src\buffer.js:51)

buffer.js:

return packs.flatMap(pack => {
        if (pack.protocol === 2) {
            return pack.data;
        }
        return pack;
    });

我改成:

packs.forEach(pack => {
        if (pack.protocol === 2) {
            pack = pack.data
        }
    });
    return packs

倒是可以。
不过最近在使用GitHub 的 actions就又出现了。
QAQ

开放平台要怎么连接?

我看文档说可以支持开放平台,现在野生连接不支持了,开放平台要怎么建立连接呢?如果能给个例子就好了。

[bug] 有些直播间心跳包只会返回1,并且接收不到数据

如题,目前是猜测和直播间有关。大多数直播间可以正常工作,少数直播间(已知直播间号404, 510)会出现如题的情况

live.on('live', () => {
  live.on('heartbeat', console.log)
})

也就是只有这一段在打印1
获取不到弹幕,live.on('DANMU_MSG',xxx)不工作

新問題

請問一下

WELCOME 類型沒有反應

想请教下ts的问题

请问这是什么语法啊?

const keepLive = (Base: typeof LiveWS | typeof LiveTCP) => class extends EventEmitter{
    //...
}

type为DANMU_MSG的信息里,用户名变成了****,uid和灯牌信息都变成了0

数据如下:
{
cmd: 'DANMU_MSG',
info: [
[
0, 1,
25, 16777215,
1688137738344, -1938799775,
0, 'e040a292',
0, 0,
0, '',
0, '{}',
'{}', [Object],
[Object], 0
],
'打雷',
[ 0, '折***', 0, 0, 0, 10000, 1, '' ],
[],
[ 0, 0, 9868950, '>50000', 0 ],
[ '', '' ],
0,
0,
null,
{ ts: 1688137738, ct: 'A7DACCD7' },
0,
0,
null,
null,
0,
7,
[ 0 ]
],
dm_v2: 'CiI0NDdjZjdjMmM0ODA2M2UzNjE5M2JjNWFmMDY0OWVmMDY5EAEYGSD///8HKghlMDQwYTI5MjIG5omT6Zu3OOjQ5uaQMUjhhsHj+P////8BYgCKAQCaARAKCEE3REFDQ0Q3EIrg+6QGogFXEgbmipgqKioiL2h0dHBzOi8vaTAuaGRzbGIuY29tL2Jmcy9mYWNlL21lbWJlci9ub2ZhY2UuanBnOJBOQAFaAggBYg0Qlq3aBBoGPjUwMDAwagByAHoAqgEFGKLlrAw='
}

关于 【Could not resolve "pako"】 与 【Dynamic require of "buffer" is not supported】的问题

您好~
vite-react-electron模板构建的一个electron项目中,
在渲染进程中使用 import { LiveWS } from 'bilibili-live-ws/browser'
运行提示:

X [ERROR] Could not resolve "pako"

    node_modules/bilibili-live-ws/src/inflate/browser.js:6:23:
      6 │ const pako_1 = require("pako");

之后我就yarn add pako
再次运行后
提示:

Uncaught Error: Dynamic require of "buffer" is not supported
    at chunk-ACCAMVX6.js?v=d5e4b460:12:9
    at node_modules/bilibili-live-ws/src/inflate/browser.js (browser.js:4:18)
    at __require2 (chunk-ACCAMVX6.js?v=d5e4b460:18:50)
    at node_modules/bilibili-live-ws/src/browser.js (browser.js:4:19)
    at __require2 (chunk-ACCAMVX6.js?v=d5e4b460:18:50)
    at node_modules/bilibili-live-ws/browser.js (browser.js:17:14)
    at __require2 (chunk-ACCAMVX6.js?v=d5e4b460:18:50)
    at dep:bilibili-live-ws_browser:1:16

browser.js 的第4行是这个:const buffer_1 = require("buffer");

KeepLive有遗留未关闭的连接

使用KeepLiveTCP时,发现接收到'close'后,原connection似乎并未关闭或销毁。
Node ver: 12.18.0
OS: Ubuntu 18
Handlers:

    this.on('open', () => {
       let ts = new Date();
       let output = `${ts.toISOString()}|Connected to room ${this.roomid}`;
       console.log(output);
       this.writeLog(output);
     });
 
     this.on('error', (e) => {
       let ts = new Date();
       let output = `${ts.toISOString()}|Connection got an error from room ${this.roomid}: ${e.message}`;
       console.log(output);
       this.writeLog(output);
     });
 
     this.on('close', () => {
       let ts = new Date();
       let output = `${ts.toISOString()}|Connection closed from room ${this.roomid}`;
       console.log(output);
       this.writeLog(output);
     });
 
     this.on('live', () => {
       this.on('heartbeat', (online) => {
         console.log(new Date(), online);
       });
    });

Log:
Screenshot from 2020-06-04 16-37-49

Bug: `Buffer` 未定义

调用 LiveWS 类出现 Uncaught (in promise) ReferenceError: Buffer is not defined 的错误,代码位置如下(ws.ts#22):

ws.onmessage = isNode ? ({ data }) => this.emit('message', data) : async ({ data }) => this.emit('message', Buffer.from(await new Response(data as unknown as InstanceType<typeof Blob>).arrayBuffer()))

请问这是什么问题呢?是我的配置错误吗?怎么解决?

谢谢。

[feature request] 允许使用房间短号

目前无法通过房间短号连接至直播间。
可以通过 https://api.live.bilibili.com/room/v1/Room/mobileRoomInit?id=${room_id} 根据 room_id (短号或实际房间号)获取房间信息,包括实际房间号。

vue中调用LiveTCP出错

QQ截图20200530010021
image

<script> document.title = 'BiliBili直播弹幕抽奖' // import connect from "./websocketClient/BiliLiveWs"; import RoomChoosing from "./components/RoomChoosing"; import Recording from "./components/Recording"; import Lottery from "./components/Lottery"; import Result from "./components/Result"; import {LiveTCP} from "bilibili-live-ws"; export default { name: 'App', components: { Result, Lottery, Recording, RoomChoosing }, data: () => ({ currentStep: 1, roomid: 0, recording: false, involvedUid: [], // 所有参与用户的uid involvedUname: {}, // 所有参与用户的用户名 luckyDogs: [] }), methods: { enterRoom: function(rid) { this.involvedUid = []; this.involvedUname = {}; this.recording = true; this.roomid = parseInt(rid); this.connectWs(); this.currentStep++; }, stopRecording: function() { this.recording = false; this.currentStep++; }, onDanmu: function(userInfo) { if (this.recording && !this.involvedUid.includes(userInfo[2][0])) { this.involvedUid.push(userInfo[2][0].toString()); this.involvedUname[userInfo[2][0]] = userInfo[2][1]; } }, connectWs: function() { console.log(this.roomid) let live = new LiveTCP(this.roomid); live.on('open'); live.on('live', () => { live.on('heartbeat') live.on('DANMU_MSG', (data) => { this.onDanmu(data.info) }) }) } } } </script>

请教问题

rm index.js index.d.ts browser.js browser.d.ts src/.js src/.d.ts;exit 0
'rm' 不是内部或外部命令,也不是可运行的程序
为什么会这样?

请教一下DANMU的数据结构

不好意思,想要请教一下DANMU的数据里面字段的含义是啥,不知道这个有没有相关信息参考呢?
image

需要登录能力

游客模式弹幕用户名打码且漏弹幕
以下行为经过测试:
只传uid 不行
传入 uid,key 不行
传入 uid,buvid 不行
传入 uid,key,buvid 不行
传入 uid,key,buvid(host|address) 不行
protover 1 2 3 均不行

authbody该传什么?
能传cookie吗

WELCOME問題

為什麼有人進入直播間不會輸出呢 有時候輸出 但是絕大部分都是不輸出的 是不是這個事件已經廢了啊

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.