Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[提问]多进程处理弹幕时,弹幕接收出现问题 #479

Closed
MeowDWing opened this issue Sep 2, 2023 · 19 comments
Closed

[提问]多进程处理弹幕时,弹幕接收出现问题 #479

MeowDWing opened this issue Sep 2, 2023 · 19 comments
Labels
bug 漏洞 question 这啥呀这是,我不到啊 solved 已解决

Comments

@MeowDWing
Copy link

Python 版本: 3.11.4

模块版本: 15.5.5

运行环境: Windows 10/11


我在用pyttsx3模块做弹幕读取的时候,我不知道怎么再开新异步了,于是我开了多线程跟多进程。
多线程因为会一直连不上直播间就放弃了

于是我开了两个子进程,一个用来接收弹幕并基于一定规则传给另一个进程,另一个处理并读取弹幕

于是奇怪的事情发生了,系统直接被干趴了,之前我干脆用两个程序跑,然后用文件传信息的时候是一直没问题的,直到昨天我改用了多进程方式后,弹幕就开始时不时接收不到了。

之后我开了之前稳定可以运行的版本,发现也开始抽风了。表现就是有时收到一些弹幕有时候又收不到

今天早上调试的时候发现有一次运行是可以稳定的接收到所有弹幕的(程序运行大约20s后我关闭了程序,第二次运行时又出现了相同的问题)

我总结了昨天晚上和今天早上发生的事情,如下:

  • 昨晚:程序第一次改用多线程(代码见[1]),程序出问题,之后运行采用之前稳定运行的版本,也无法正常接收弹幕(后发现可能是因为没有加join方法导致主进程执行至结束)
  • 今早:(换了台电脑和ip)程序继续有问题,但之前稳定运行的非多进程版本没有问题。
  • 今早:(主程序加入了join方法)程序出现约20s正常接收后关闭程序,此时非多进程和多进程版本均无问题(代码见[2])。
  • 今早:(再次运行)程序又出现问题,此时非多线程版本也出现问题(代码见[2])。

[1]

  • def begin():
    
      __global_queue = multiprocessing.Queue(233)
      print('正在读取房间号...')
      rid = 34162
      with open('./files/settings.txt', mode='r', encoding='utf-8') as f:
          lines = f.readlines()
      for line in lines:
          line = line.strip().split('=')
          if line[0] == 'rid':
              rid = int(line[1])
    
      print('正在初始化弹幕获取器...')
      process_receiver = multiprocessing.Process(target=receiver, args=(__global_queue, rid,))
    
      print("正在初始化阅读器...")
      process_reader = multiprocessing.Process(target=reader, args=(__global_queue,))
    
      print("正在启动弹幕获取器与读取器...")
      process_receiver.start()
      process_reader.start()
    
      return True

[2]

  •   ...:same as [1]
      # in tails:
      -return True
      +
      process_receiver.join()
      process_reader.join()

关于接收进程:
就是收到弹幕后,根据牌子等级选择是否发送给读取进程。
方式为:

  # 前面是获得event并提取粉丝等级,名字和弹幕内容
   if len(danmaku_content) > 0 and if_read:
        if not self._queue.full():  # _queue是消息队列
            if self.local_queue_len != 0:  #  local_queue 是本地队列
                while True:
                    if not self._queue.full() and self.local_queue_len != 0:
                        c = self.local_queue.popleft()
                        self.local_queue_len -= 1
                        self._queue.put(c)
                    else:
                        break
            else:
                self._queue.put(danmaku_content)
        else:
            self.local_queue.append(danmaku_content)

即:
如果消息队列没有满,且本地队列为空,则加入消息队列
如果已经满了,则加入本地队列

关于读取进程
读取端操作就是每次循环pop消息队列直到空,其中用了一定量的time.sleep,其他应该没有能影响接收进程的东西

按我的认知来说只是开了两个进程应该不会导致b站的风控检查,也就是说我采用多进程后应该跟之前是一样的(单纯是为了不开两个窗口所以用了多进程),所以不应该有这样的问题才对?

@MeowDWing MeowDWing added the question 这啥呀这是,我不到啊 label Sep 2, 2023
@Ikaros-521
Copy link

经常接收不到弹幕+1
昨天发现,重开几次会有一段时间可以,不过长时间运行后还是有出现无法接受到的情况

@Drelf2018
Copy link
Collaborator

我来看看吧,照理说弹幕接收问题已经解决了的

@Ikaros-521
Copy link

我来看看吧,照理说弹幕接收问题已经解决了的

大佬是16.0.0版本的更新吗,我跑的是15.5.5

@MeowDWing
Copy link
Author

还有就是,因为要打包,所以用了freeze_support,别的实在想不到能影响的东西了

@Drelf2018
Copy link
Collaborator

我来看看吧,照理说弹幕接收问题已经解决了的

大佬是16.0.0版本的更新吗,我跑的是15.5.5

照理说 v15.5.4 已经修了,但是可能又有新变动,尝试在构造 live.LiveDanmaku(213, credential=credential) 时加上凭证呢?

@Ikaros-521
Copy link

我来看看吧,照理说弹幕接收问题已经解决了的

大佬是16.0.0版本的更新吗,我跑的是15.5.5

照理说 v15.5.4 已经修了,但是可能又有新变动,尝试在构造 live.LiveDanmaku(213, credential=credential) 时加上凭证呢?

这个凭证确实没有加0.0,之后试试看,感谢大佬

@xqe2011
Copy link

xqe2011 commented Sep 2, 2023

参考其他库issues,需要在认证包中的uid与credential的用户信息uid一致才行

@MeowDWing
Copy link
Author

参考其他库issues,需要在认证包中的uid与credential的用户信息uid一致才行

我试试看

@Drelf2018
Copy link
Collaborator

是的,现在必须要填入 credential 才能接收了,我现在发一个更新 pr 吧

@Ikaros-521
Copy link

(U}6}N~MZ5@LPK) I42TO D

@MeowDWing
Copy link
Author

测试完毕,是的,需要sessdata和bili_jct,那有什么更便捷的获取手段么,还是只能f12

@Drelf2018
Copy link
Collaborator

库里有一些登录方式,但是还是f12最快。

@z0z0r4
Copy link
Collaborator

z0z0r4 commented Sep 2, 2023

测试完毕,是的,需要sessdata和bili_jct,那有什么更便捷的获取手段么,还是只能f12

login.login_with_qrcode_term 如果你是 CLI 的话这大概是最快的非 F12 方式

@z0z0r4
Copy link
Collaborator

z0z0r4 commented Sep 2, 2023

建议现在测测能不能用,急急急发 release 明天上午就要返校力(悲

@MeowDWing
Copy link
Author

我来狠狠的跟进

@MeowDWing
Copy link
Author

测试完毕,是的,需要sessdata和bili_jct,那有什么更便捷的获取手段么,还是只能f12

login.login_with_qrcode_term 如果你是 CLI 的话这大概是最快的非 F12 方式

最先考虑的肯定是不用重复,我是不是获取一遍,然后定时refresh就不用每次都登录了

@z0z0r4
Copy link
Collaborator

z0z0r4 commented Sep 2, 2023

测试完毕,是的,需要sessdata和bili_jct,那有什么更便捷的获取手段么,还是只能f12

login.login_with_qrcode_term 如果你是 CLI 的话这大概是最快的非 F12 方式

最先考虑的肯定是不用重复,我是不是获取一遍,然后定时refresh就不用每次都登录了

有函数检测是否需要刷新,不用定时,出错了之后检测,有 refresh

实际上这一点和登录方式没关系,F12 拿 ac_time_value 一样可以 refresh

@MeowDWing
Copy link
Author

测试完毕,是的,需要sessdata和bili_jct,那有什么更便捷的获取手段么,还是只能f12

login.login_with_qrcode_term 如果你是 CLI 的话这大概是最快的非 F12 方式

最先考虑的肯定是不用重复,我是不是获取一遍,然后定时refresh就不用每次都登录了

有函数检测是否需要刷新,不用定时,出错了之后检测,有 refresh

好的,谢谢

@z0z0r4 z0z0r4 added bug 漏洞 solved 已解决 labels Sep 2, 2023
@blyc
Copy link

blyc commented Sep 2, 2023

根据新的pr获取到消息了
长期有没有问题待后续测试了

@z0z0r4 z0z0r4 closed this as completed Sep 3, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 漏洞 question 这啥呀这是,我不到啊 solved 已解决
Projects
None yet
Development

No branches or pull requests

6 participants