simon300000 / bilibili-live-ws

Bilibili live WebSocket/tcp API
MIT License
316 stars 31 forks source link

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

Closed s3xysteak closed 1 year ago

s3xysteak commented 1 year ago

如题,这是我的代码:

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是自动循环执行,但似乎并非如此...有什么办法能达到我想要的效果吗?

simon300000 commented 1 year ago

JS的setTimeout是不block的,就是你这里要是同时收到了多个弹幕,那setTimeout会同时执行,并行的,所以起不到节流的效果。

live.on每次收到弹幕就会立即执行,是一个eventTrigger? js里面经常会碰到,所谓event driven

我个人的一个可能是这样:

let danmu = ''

live.on('DANMU_MSG', data => {
  const output = data.info[1]
  console.log(output)
  danmu = output
})

const wait = ms => new Promise(resolve => setTimeout(resolve, ms))

const tts = async () => {
  while (true) {
    if (danmu) {
      const currentDanmu = danmu
      danmu = ''
      // read danmu
    }
    await wait(3000)
  }
}

tts()
s3xysteak commented 1 year ago

感谢老哥,已解决。我的方案是在这基础上设置一个proxy,用来响应式触发tts