diff --git "a/DD\347\233\221\346\216\247\345\256\244.py" "b/DD\347\233\221\346\216\247\345\256\244.py"
index 77706d0..50137c1 100644
--- "a/DD\347\233\221\346\216\247\345\256\244.py"
+++ "b/DD\347\233\221\346\216\247\345\256\244.py"
@@ -96,8 +96,7 @@ def __init__(self, title):
self.setWindowTitle(title)
self.setObjectName(f'dock-{title}')
self.setFloating(False)
- self.setAllowedAreas(Qt.LeftDockWidgetArea |
- Qt.RightDockWidgetArea | Qt.TopDockWidgetArea)
+ self.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea | Qt.TopDockWidgetArea)
class StartLiveWindow(QWidget):
@@ -149,8 +148,7 @@ def __init__(self):
layout.addWidget(okButton, 2, 3, 1, 1)
def selectCopyPath(self):
- savePath = QFileDialog.getExistingDirectory(
- self, "选择备份缓存路径", None, QFileDialog.ShowDirsOnly)
+ savePath = QFileDialog.getExistingDirectory(self, "选择备份缓存路径", None, QFileDialog.ShowDirsOnly)
if savePath:
self.savePathEdit.setText(savePath)
@@ -167,9 +165,9 @@ def __init__(self):
self.resize(350, 150)
self.setWindowTitle('当前版本')
layout = QGridLayout(self)
- layout.addWidget(QLabel('DD监控室 v2.6正式版'), 0, 0, 1, 2)
+ layout.addWidget(QLabel('DD监控室 v2.8正式版'), 0, 0, 1, 2)
layout.addWidget(QLabel('by 神君Channel'), 1, 0, 1, 2)
- layout.addWidget(QLabel('特别鸣谢:大锅饭 美东矿业 inkydragon'), 2, 0, 1, 2)
+ layout.addWidget(QLabel('特别鸣谢:大锅饭 美东矿业 inkydragon 聪_哥'), 2, 0, 1, 2)
releases_url = QLabel('')
releases_url.setOpenExternalLinks(True)
releases_url.setText(_translate("MainWindow", "
\
@@ -182,8 +180,7 @@ def __init__(self):
layout.addWidget(checkButton, 0, 2, 1, 1)
def checkUpdate(self):
- QDesktopServices.openUrl(
- QUrl(r'https://github.com/zhimingshenjun/DD_Monitor/releases/tag/DD_Monitor'))
+ QDesktopServices.openUrl(QUrl(r'https://github.com/zhimingshenjun/DD_Monitor/releases/tag/DD_Monitor'))
class HotKey(QWidget):
@@ -209,16 +206,14 @@ def __init__(self, config):
def run(self):
try:
- configJSONPath = os.path.join(
- application_path, r'utils/config.json')
+ configJSONPath = os.path.join(application_path, r'utils/config.json')
with codecs.open(configJSONPath, 'w', encoding='utf-8') as f:
f.write(json.dumps(self.config, ensure_ascii=False))
except:
logging.exception('config.json 写入失败')
try: # 备份 防止存储config时崩溃
- configJSONPath = os.path.join(
- application_path, r'utils/config_备份%d.json' % self.backupNumber)
+ configJSONPath = os.path.join(application_path, r'utils/config_备份%d.json' % self.backupNumber)
self.backupNumber += 1
if self.backupNumber == 4:
self.backupNumber = 1
@@ -234,12 +229,11 @@ class CheckDanmmuProvider(QThread):
"""检查弹幕服务器域名解析状态"""
def __init__(self):
- super(CheckDanmmuProvider, self).__init__()
-
+ super(CheckDanmmuProvider,self).__init__()
+
def run(self):
try:
- anwsers = dns.resolver.resolve(
- 'broadcastlv.chat.bilibili.com', 'A')
+ anwsers = dns.resolver.resolve('broadcastlv.chat.bilibili.com', 'A')
danmu_ip = anwsers[0].to_text()
logging.info("弹幕IP: %s" % danmu_ip)
except Exception as e:
@@ -381,7 +375,7 @@ def __init__(self, cacheFolder, progressBar, progressText):
vlcProgressCounter = 1
for i in range(16):
if len(self.config['danmu'][i]) < 8:
- self.config['danmu'][i].append(0)
+ self.config['danmu'][i].append(3)
volume = self.config['volume'][i]
progressText.setText('设置第%s个主层播放器...' % str(i + 1))
self.videoWidgetList.append(VideoWidget(i, volume, cacheFolder, textSetting=self.config['danmu'][i],
diff --git a/VideoWidget_vlc.py b/VideoWidget_vlc.py
index 94ce753..ebddbc4 100644
--- a/VideoWidget_vlc.py
+++ b/VideoWidget_vlc.py
@@ -407,7 +407,7 @@ def __init__(self, id, volume, cacheFolder, top=False, title='', resize=[],
# 关闭窗口
self.stop = PushButton(self.style().standardIcon(
QStyle.SP_DialogCancelButton))
- self.stop.clicked.connect(self.mediaStop)
+ self.stop.clicked.connect(self._mediaStop)
frameLayout.addWidget(self.stop)
# ---- IO 交互设置 ----
@@ -431,6 +431,10 @@ def __init__(self, id, volume, cacheFolder, top=False, title='', resize=[],
self.moveTimer.timeout.connect(self.initTextPos)
self.moveTimer.start(50)
+ # self.reloadDanmuTimer = QTimer()
+ # self.reloadDanmuTimer.timeout.connect(self.reloadDanmu)
+ # self.reloadDanmuTimer.start(10000)
+
# 检查播放卡住的定时器
self.checkPlaying = QTimer()
self.checkPlaying.timeout.connect(self.checkPlayStatus)
@@ -892,11 +896,7 @@ def closeDanmu(self):
# self.setTranslator.emit([self.id, False])
def stopDanmuMessage(self):
- try:
- self.danmu.message.disconnect(self.playDanmu)
- except:
- logging.exception('停止弹幕出错')
- self.danmu.terminate()
+ self.stopDanmu()
def showDanmu(self):
if self.textBrowser.isHidden():
@@ -986,6 +986,9 @@ def mediaReload(self):
else:
self.mediaStop()
+ def _mediaStop(self):
+ self.mediaStop()
+
def mediaStop(self, deleteMedia=True):
# self.userPause = True
self.oldTitle, self.oldUname = '', ''
@@ -997,17 +1000,27 @@ def mediaStop(self, deleteMedia=True):
self.play.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
if deleteMedia:
self.deleteMedia.emit(self.id)
- try:
- self.danmu.message.disconnect(self.playDanmu)
- except:
- logging.exception('停止弹幕出错')
self.getMediaURL.recordToken = False
self.getMediaURL.checkTimer.stop()
self.checkPlaying.stop()
+ self.stopDanmu()
+
+ def stopDanmu(self):
+ # try:
+ try:
+ self.danmu.message.disconnect(self.playDanmu)
+ except:
+ pass
self.danmu.terminate()
self.danmu.quit()
self.danmu.wait()
+ def reloadDanmu(self):
+ self.stopDanmu()
+ self.danmu.setRoomID(self.roomID)
+ self.danmu.message.connect(self.playDanmu)
+ self.danmu.start()
+
def setMedia(self, cacheName):
self.retryTimes = 0
self.cacheName = cacheName
@@ -1016,7 +1029,8 @@ def setMedia(self, cacheName):
try:
self.danmu.message.disconnect(self.playDanmu)
except:
- logging.exception('停止弹幕出错')
+ pass
+ # logging.exception('停止弹幕出错')
if self.startWithDanmu:
self.danmu.message.connect(self.playDanmu)
self.danmu.terminate()
@@ -1126,7 +1140,7 @@ def playDanmu(self, message):
self.textBrowser.msgsBrowser.append(message)
return
for symbol in self.filters:
- if symbol in message[message.find(': ')+2:]:
+ if symbol in message:
self.textBrowser.transBrowser.append(message)
token = True
break
diff --git a/remote.py b/remote.py
index ff2731d..6a5c66a 100644
--- a/remote.py
+++ b/remote.py
@@ -6,15 +6,22 @@
import zlib
import json
import requests
-from aiowebsocket.converses import AioWebSocket
+# from aiowebsocket.converses import AioWebSocket
from PyQt5.QtCore import QThread, pyqtSignal
import logging
+from bilibili_api import live
+
+
+class Live(live.LiveDanmaku):
+
+ def __init__(self, room_display_id):
+ super().__init__(room_display_id)
+
+ def register(self, event: str, func: callable):
+ self.__getattribute__("_LiveDanmaku__event_handlers")[event].append(func)
class remoteThread(QThread):
- """
- TODO: 换用 bilibili_api.live.LiveDanmaku(room_display_id)
- """
message = pyqtSignal(str)
def __init__(self, roomID):
@@ -31,32 +38,38 @@ def __init__(self, roomID):
if '"roomid":' in line:
self.roomID = line.split('"roomid":')[1].split(',')[0]
- async def startup(self, url):
- logging.info('尝试打开 %s 的弹幕Socket' % self.roomID)
- data_raw = '000000{headerLen}0010000100000007000000017b22726f6f6d6964223a{roomid}7d'
- data_raw = data_raw.format(headerLen=hex(27 + len(self.roomID))[2:],
- roomid=''.join(map(lambda x: hex(ord(x))[2:], list(self.roomID))))
- async with AioWebSocket(url) as aws:
- try:
- converse = aws.manipulator
- await converse.send(bytes.fromhex(data_raw))
- tasks = [self.receDM(converse), self.sendHeartBeat(converse)]
- await asyncio.wait(tasks)
- except:
- logging.exception('弹幕Socket打开失败')
+ async def startup(self):
+ self.roomID = int(self.roomID)
+ self.room = Live(self.roomID)
+ self.room.add_event_listener('DANMU_MSG', self.danmu) # 用户发送弹幕
+ # self.room.add_event_listener('SEND_GIFT', self.gift) # 礼物
+ # self.room.add_event_listener('COMBO_SEND', self.combo_gift) # 礼物连击
+ # self.room.add_event_listener('GUARD_BUY', self.guard) # 续费大航海
+ self.room.add_event_listener('SUPER_CHAT_MESSAGE', self.sc) # 醒目留言(SC)
+ # self.room.add_event_listener('INTERACT_WORD', self.enter) # 用户进入直播间
+ await self.room.connect()
+ # await asyncio.wait([self.room.connect()])
- async def sendHeartBeat(self, websocket):
- logging.debug("向%s发送心跳包" % self.roomID)
- hb = '00000010001000010000000200000001'
- while True:
- await asyncio.sleep(30)
- await websocket.send(bytes.fromhex(hb))
+ async def danmu(self, jd):
+ self.message.emit(jd['data']['info'][1])
- async def receDM(self, websocket):
- while True:
- recv_text = await websocket.receive()
- logging.debug("从%s接收到DM" % self.roomID)
- self.printDM(recv_text)
+ async def gift(self, event):
+ print(event)
+
+ async def combo_gift(self, event):
+ print(event)
+
+ async def guard(self, event):
+ print(event)
+
+ async def sc(self, jd):
+ jd = jd['data']
+ self.message.emit(
+ f"【SC(¥{jd['data']['price']}) {jd['data']['user_info']['uname']}: {jd['data']['message']}】"
+ )
+
+ async def enter(self, event):
+ print(event)
def printDM(self, data):
packetLen = int(data[:4].hex(), 16)
@@ -118,11 +131,12 @@ def getMetal(jd):
jd = json.loads(data[16:].decode('utf-8', errors='ignore'))
if jd['cmd'] == 'DANMU_MSG':
self.message.emit(
- f"{userType[jd['info'][2][7]]}{adminType[jd['info'][2][2]]}{getMetal(jd)} {jd['info'][2][1]}: {jd['info'][1]}"
+ # f"{userType[jd['info'][2][7]]}{adminType[jd['info'][2][2]]}{getMetal(jd)} {jd['info'][2][1]}: {jd['info'][1]}"
+ f"{jd['info'][1]}"
)
elif jd['cmd'] == 'SUPER_CHAT_MESSAGE':
self.message.emit(
- f"SC(¥{jd['data']['price']}) {getMetal(jd)} {jd['data']['user_info']['uname']}: {jd['data']['message']}"
+ f"【SC(¥{jd['data']['price']}) {getMetal(jd)} {jd['data']['user_info']['uname']}: {jd['data']['message']}】"
)
elif jd['cmd'] == 'SEND_GIFT':
if jd['data']['coin_type'] == "gold":
@@ -153,12 +167,8 @@ def getMetal(jd):
logging.exception('弹幕输出失败')
def setRoomID(self, roomID):
- self.roomID = roomID
+ self.roomID = int(roomID)
def run(self):
- remote = r'wss://broadcastlv.chat.bilibili.com:2245/sub'
- try:
- asyncio.set_event_loop(asyncio.new_event_loop())
- asyncio.get_event_loop().run_until_complete(self.startup(remote))
- except:
- logging.exception('弹幕主循环出错')
+ asyncio.set_event_loop(asyncio.new_event_loop())
+ asyncio.get_event_loop().run_until_complete(self.startup())