17 Commits

Author SHA1 Message Date
77d7f35d25 Add: Actions When Upload Finished 2019-02-01 16:20:50 +08:00
84ca4d0a62 修改isValidRoom判断,避免误更改导致无法获取弹幕 2019-02-01 16:17:21 +08:00
4a59cbcf82 抽奖信息可从弹幕中提取,可实时检测抽奖避免刷屏 2019-02-01 13:33:01 +08:00
1b920fa55c 修复:因isValidRoom判断错误导致的无法获取弹幕,修正抽奖结束时间判断 2019-02-01 13:08:09 +08:00
81f730ea68 各种适配新Android Api,修复各种Bug 2019-01-31 23:05:48 +08:00
a1cfc9b914 Update : Replace delete downloaded files With move to oss 2019-01-31 17:23:18 +08:00
81763fdf37 Emeg Update : Fix isLive is always True 2019-01-31 13:09:21 +08:00
884122b007 Emeg Update: dynamic roomId fix 2019-01-30 19:07:07 +08:00
8c0320c97e 全面改为AndroidApi,添加抽奖识别及消息提示 2019-01-29 13:50:29 +08:00
14525ee76e 添加搜索功能[Beta]
Update ReadMe.md

Signed-off-by: Jerry Yan <792602257@qq.com>
2019-01-28 20:26:23 +08:00
cd4d7605f5 Fix Conflicts
# Conflicts:
#	api.py
2019-01-28 18:58:16 +08:00
5da70e81f9 Api使用Android app弹幕协议 2019-01-28 18:54:24 +08:00
f7727a3c39 Emeg: fix default room 2019-01-27 22:26:06 +08:00
e46e4ec0d7 Update README.md 2019-01-27 22:20:23 +08:00
a4f4c10efc 修正Linux版显示 2019-01-27 22:18:17 +08:00
82b076df3f 修正因未开播而导致的Queue内占满了False的BUG 2019-01-26 18:54:41 +08:00
cf8cbaae8c 修复删除已上传视频的逻辑,添加 追加上传功能 2019-01-26 16:29:04 +08:00
12 changed files with 532 additions and 245 deletions

20
Chat.py
View File

@ -1,19 +1,27 @@
from User import User from User import User
from Lottery import Lottery
class Chat: class Chat:
content:str="" content: str =""
user:User=None user: User=None
filterString:list = ["",]
isFiltered = False
def __init__(self, json=None): def __init__(self, json=None, lottery:Lottery = None):
if json: if json:
self.parse(json) self.parse(json)
if lottery:
self.filterString.append(lottery.content)
def parse(self, json): def parse(self, json):
self.user = User(json) self.user = User(json)
if "Msg" in json: if "extra" in json:
if "content" in json["Msg"]: if "content" in json["extra"]:
self.content = json["Msg"]['content'] self.content = json["extra"]['content']
if self.content in self.filterString:
self.isFiltered = True
def __str__(self): def __str__(self):
return "{} : {}".format(self.user,self.content) return "{} : {}".format(self.user,self.content)

0
Digg.py Normal file
View File

35
Gift.py
View File

@ -16,26 +16,31 @@ class Gift:
def parse(self, json): def parse(self, json):
self.user = User(json) self.user = User(json)
if "Msg" in json: if "common" in json and json["common"] is not None:
if "present_end_info" in json["Msg"]: if Gift.roomID != int(json["common"]["room_id"]):
self.ID = json["Msg"]['present_end_info']['id'] Gift.roomID = int(json["common"]["room_id"])
self.count = json["Msg"]['present_end_info']['count'] self.update()
elif "present_info" in json["Msg"]: if "extra" in json and json["extra"] is not None:
self.ID = json["Msg"]['present_info']['id'] if "present_info" in json["extra"] and json["extra"]['present_info'] is not None:
self.count = json["Msg"]['present_info']['repeat_count'] self.ID = int(json["extra"]['present_info']['id'])
if self.ID in self.giftList: self.count = json["extra"]['present_info']['repeat_count']
elif "present_end_info" in json["extra"] and json["extra"]['present_end_info'] is not None:
self.ID = int(json["extra"]['present_end_info']['id'])
self.count = json["extra"]['present_end_info']['count']
if self.ID != 0 and self.ID in self.giftList:
self.amount = self.giftList[self.ID]["Price"] * self.count self.amount = self.giftList[self.ID]["Price"] * self.count
else:
self.update()
@staticmethod def update(self):
def update(roomID): p = requests.get("https://i.snssdk.com/videolive/gift/get_gift_list?room_id={roomID}".format(roomID = self.roomID))
Gift.roomID = roomID
p = requests.get("https://live.ixigua.com/api/gifts/{roomID}".format(roomID= roomID))
d = p.json() d = p.json()
if isinstance(d, int) or "data" not in d: if "gift_info" not in d:
print("错误:礼物更新失败") print("错误:礼物更新失败")
else: else:
for i in d["data"]: for i in d["gift_info"]:
Gift.giftList[i["ID"]] = {"Name": i["Name"], "Price": i["DiamondCount"]} _id = int(i["id"])
Gift.giftList[_id] = {"Name": i["name"], "Price": i["diamond_count"]}
def __str__(self): def __str__(self):
if self.ID in self.giftList: if self.ID in self.giftList:

71
Lottery.py Normal file
View File

@ -0,0 +1,71 @@
import requests
import time
from LuckyUser import LuckyUser
class Lottery:
ID: int = 0
isActive = False
content = ""
isFinished = False
luckyUsers = []
joinedUserCount = 0
prizeName = ""
finish:int = 0
def __init__(self, json=None):
if json:
self.parse(json)
def parse(self, json):
if "lottery_info" in json and json["lottery_info"] is not None:
self.isActive = int(json["lottery_info"]["status"]) > 0
self.ID = json["lottery_info"]["lottery_id"]
for i in json["lottery_info"]['conditions']:
if i['type'] != 3:
continue
self.content = i["content"]
self.joinedUserCount = int(json["lottery_info"]["candidate_num"])
self.prizeName = json["lottery_info"]["prize_info"]["name"]
_delta = int(json["lottery_info"]["draw_time"]) - int(json["lottery_info"]["current_time"])
self.finish = time.time()+_delta+1
elif "extra" in json and json["extra"] is not None:
if "lottery_info" in json["extra"] and json["extra"]["lottery_info"] is not None:
return self.parse(json["extra"])
def update(self):
if self.isActive:
if not self.isFinished and self.finish > time.time():
self.checkFinished()
return True
return False
def checkFinished(self):
p = requests.get("https://i.snssdk.com/videolive/lottery/check_user_right?lottery_id={}"
"&version_code=730&device_platform=android".format(
self.ID
))
d = p.json()
if d["base_resp"]["status_code"] != 0:
self.isActive = False
self.isFinished = False
return
self.isActive = int(d["lottery_info"]["status"]) > 0
self.isFinished = int(d["lottery_info"]["status"]) == 2
self.joinedUserCount = int(d["lottery_info"]["candidate_num"])
if self.isFinished:
for i in d["lottery_info"]["lucky_users"]:
self.luckyUsers.append(LuckyUser(i))
def __str__(self):
if self.isFinished:
ret = "恭喜以下中奖用户:\n"
for i in self.luckyUsers:
ret += "> {} {}\n".format(i,self.prizeName)
ret += "> 参与人数:{}".format(self.joinedUserCount)
return ret
elif self.isActive:
return "正在抽奖中。。。\n" \
"> 参与人数:{}".format(self.joinedUserCount)
else:
return "抽奖已失效"

19
LuckyUser.py Normal file
View File

@ -0,0 +1,19 @@
from User import User
class LuckyUser:
user = None
count = 0
def __init__(self, json=None):
if json:
self.parse(json)
def parse(self, json):
self.user = User()
self.user.ID = json['user_id']
self.user.name = json['user_name']
self.count = int(json["grant_count"])
def __str__(self):
return "用户 {} 获得了 {}".format(self.user,self.count)

View File

@ -12,11 +12,11 @@ class MemberMsg:
def parse(self, json): def parse(self, json):
self.user = User(json) self.user = User(json)
if "Msg" in json: if "extra" in json:
if "action" in json["Msg"]: if "action" in json["extra"]:
self.type = json["Msg"]['action'] self.type = json["extra"]['action']
elif "content" in json["Msg"]: elif "content" in json["extra"]:
self.content = json["Msg"]['content'] self.content = json["extra"]['content']
def __str__(self): def __str__(self):
if self.type == 3: if self.type == 3:
@ -28,6 +28,8 @@ class MemberMsg:
elif self.type == 1: elif self.type == 1:
return "{} 进入了房间".format(self.user) return "{} 进入了房间".format(self.user)
else: else:
if self.content == "":
return "未知消息{} 关于用户 {}".format(self.type, self.user)
return self.content.format(self.user) return self.content.format(self.user)
def __unicode__(self): def __unicode__(self):

View File

@ -1,8 +1,16 @@
# XiguaLiveDanmakuHelper # XiguaLiveDanmakuHelper
### 西瓜直播弹幕助手 ### 西瓜直播弹幕助手--控制台版
因个人能力有限不懂C#,无法做出界面版,只好用控制台版先顶着 界面版:[q792602257/XiguaDanmakuHelperGUI](https://github.com/q792602257/XiguaDanmakuHelperGUI "C# ver")
### 计划更新: ### 计划更新:
- 使用android app协议避免出现网页版协议更改后无法使用 + Digg消息点亮了喜欢实例化
- 闲的无聊的时候看一看有没有好用的GUI轮子可以用用 + √ ~~使用android app协议~~
已使用
除从用户ID获取roomID外其他均改为Android Api
+ √ ~~闲的无聊的时候看一看有没有好用的GUI轮子可以用用~~
已完成
已基于BiliLive_dm制作出初代西瓜直播弹幕姬api未跟进

34
User.py
View File

@ -4,25 +4,37 @@ class User:
brand: str = "" brand: str = ""
level: int = 0 level: int = 0
type: int = 0 type: int = 0
block: bool = False
mute: bool = False
def __init__(self, json=None): def __init__(self, json=None):
if json: if json:
self.parse(json) self.parse(json)
def parse(self, json): def parse(self, json):
if "Msg" in json: if "extra" in json:
if "user" in json["Msg"]: if "user" in json["extra"] and json["extra"]["user"] is not None:
self.ID = json["Msg"]['user']['user_id'] self.ID = json["extra"]['user']['user_id']
self.name = json["Msg"]['user']['name'] self.name = json["extra"]['user']['name']
if "discipulus_info" in json["Msg"]: if "im_discipulus_info" in json["extra"] and json["extra"]["im_discipulus_info"] is not None:
self.level = json["Msg"]["discipulus_info"]["level"] self.level = json["extra"]["im_discipulus_info"]["level"]
self.brand = json["Msg"]["discipulus_info"]["discipulus_group_title"] self.brand = json["extra"]["im_discipulus_info"]["discipulus_group_title"]
elif "data" in json: if "user_room_auth_status" in json["extra"] and json["extra"]["user_room_auth_status"] is not None:
if "anchorInfo" in json["data"]: self.type = json["extra"]["user_room_auth_status"]["user_type"]
self.ID = json["data"]['anchorInfo']['id'] self.block = json["extra"]["user_room_auth_status"]["is_block"]
self.name = json["data"]['anchorInfo']['name'] self.mute = json["extra"]["user_room_auth_status"]["is_silence"]
elif "room" in json and json["room"] is not None:
if "user_info" in json["room"] and json["room"]["user_info"] is not None:
self.ID = json["room"]['user_info']['user_id']
self.name = json["room"]['user_info']['name']
elif "anchor" in json and json["anchor"] is not None:
if "user_info" in json["anchor"] and json["anchor"]['user_info'] is not None:
self.ID = json["anchor"]['user_info']['user_id']
self.name = json["anchor"]['user_info']['name']
if self.type is None: if self.type is None:
self.type = 0 self.type = 0
if isinstance(self.level, str):
self.level = int(self.level)
def __str__(self): def __str__(self):
if self.level == 0: if self.level == 0:

View File

@ -3,9 +3,9 @@ import sys
import time import time
from Gift import Gift from Gift import Gift
from Lottery import Lottery
from MemberMsg import MemberMsg from MemberMsg import MemberMsg
from User import User from User import User
from Chat import Chat from Chat import Chat
from api import XiGuaLiveApi as Api from api import XiGuaLiveApi as Api
import msvcrt import msvcrt
@ -31,7 +31,9 @@ def readInput(caption, default, timeout: int = 5):
msvcrt.putch(b"\b") msvcrt.putch(b"\b")
if len(input) == 0: if len(input) == 0:
start_time = time.time() start_time = time.time()
elif 32 <= ord(chr) <= 126: # space_char elif 32 > ord(chr) or 255 > ord(chr) > 126: # space_char
continue
else:
input += chr.decode("utf8") input += chr.decode("utf8")
if len(input) == 0 and (time.time() - start_time) > timeout: if len(input) == 0 and (time.time() - start_time) > timeout:
break break
@ -104,17 +106,13 @@ class WinMain(Api):
if self._tmp > 10: if self._tmp > 10:
self._tmp = 0 self._tmp = 0
if self._tmp < 5 : if self._tmp < 5 :
return "{} {} --弹幕助手 by JerryYan".format(self.roomLiver, "的直播间") return "{} 的直播间 --弹幕助手 by JerryYan".format(self.roomLiver)
else: else:
if self.roomPopularity == 0: if self.roomPopularity == 0:
self._tmp = 0 self._tmp = 0
return self.getTitle() return self.getTitle()
else: else:
if self.roomMember > 0: return "人气:{} --弹幕助手 by JerryYan".format(self.roomPopularity)
return "观看:{} 人气:{} --弹幕助手 by JerryYan".format(self.roomMember, self.roomPopularity)
else:
return "观看:待刷新 人气:{} --弹幕助手 by JerryYan".format(self.roomPopularity)
def onMessage(self, msg: str): def onMessage(self, msg: str):
set_cmd_text_color(FOREGROUND_DARKGRAY) set_cmd_text_color(FOREGROUND_DARKGRAY)
@ -123,7 +121,7 @@ class WinMain(Api):
def onJoin(self, user: User): def onJoin(self, user: User):
set_cmd_text_color(BACKGROUND_WHITE | FOREGROUND_BLACK) set_cmd_text_color(BACKGROUND_WHITE | FOREGROUND_BLACK)
print("感谢", user, "加入了粉丝团") print("欢迎", user, "加入了粉丝团")
resetColor() resetColor()
def onSubscribe(self, user: User): def onSubscribe(self, user: User):
@ -140,7 +138,14 @@ class WinMain(Api):
def onChat(self, chat: Chat): def onChat(self, chat: Chat):
if SHOW_ALL: if SHOW_ALL:
print(chat) resetColor()
if not chat.isFiltered:
print(chat)
def onLottery(self, i:Lottery):
set_cmd_text_color(FOREGROUND_WHITE | BACKGROUND_DARKGRAY)
print(i)
resetColor()
def onPresent(self, gift: Gift): def onPresent(self, gift: Gift):
if SHOW_ALL: if SHOW_ALL:
@ -168,24 +173,14 @@ def warning(*args):
if __name__ == "__main__": if __name__ == "__main__":
room = 97621754276 # 永恒 name = "永恒de草薙"
# room = 75366565294
# room = 83940182312 #Dae
resetColor() resetColor()
print("西瓜直播弹幕助手 by JerryYan") print("西瓜直播弹幕助手 by JerryYan")
if len(sys.argv) > 1: if len(sys.argv) > 1:
if sys.argv[-1] == "a": name = sys.argv[1]
SHOW_ALL = True
try:
room = int(sys.argv[1])
except:
pass
else: else:
try: name = readInput("请输入主播用户名(请用拼音字母),默认为", name, 3)
room = int(readInput("请输入用户ID号默认为永恒的ID号", room, 3)) api = WinMain(name)
except ValueError:
pass
api = WinMain(room)
print("进入", api.roomLiver, "的直播间") print("进入", api.roomLiver, "的直播间")
if not api.isValidRoom: if not api.isValidRoom:
input("房间不存在") input("房间不存在")
@ -194,11 +189,11 @@ if __name__ == "__main__":
print("=" * 30) print("=" * 30)
while True: while True:
if api.isLive: if api.isLive:
os.system("title {}".format(api.getTitle()))
try: try:
os.system("title {}".format(api.getTitle()))
api.getDanmaku() api.getDanmaku()
except Exception as e: except Exception as e:
warning(e) print(e.__str__())
time.sleep(1) time.sleep(1)
else: else:
set_cmd_text_color(FOREGROUND_RED) set_cmd_text_color(FOREGROUND_RED)

188
api.py
View File

@ -4,6 +4,7 @@ from MemberMsg import MemberMsg
from User import User from User import User
from Gift import Gift from Gift import Gift
from Chat import Chat from Chat import Chat
from Lottery import Lottery
import requests import requests
import time import time
@ -16,25 +17,23 @@ class XiGuaLiveApi:
isLive: bool = False isLive: bool = False
isValidRoom: bool = False isValidRoom: bool = False
_rawRoomInfo = {} _rawRoomInfo = {}
name: str = ""
roomID: int = 0 roomID: int = 0
roomTitle: str = "" roomTitle: str = ""
roomLiver: User = None roomLiver: User = None
roomPopularity: int = 0 roomPopularity: int = 0
roomMember: int = 0 _cursor:str = "0"
_cursor = "" _updRoomCount:int = 0
lottery:Lottery = None
def __init__(self, room: int): def __init__(self, name: str = "永恒de草薙"):
self.room = room self.name = name
self.updRoomInfo() self.updRoomInfo()
Gift.update(self.roomID)
self._enterRoom()
def _updateRoomInfo(self, json): def _updateRoomInfo(self, json):
if "Msg" in json: if "extra" in json:
if "member_count" in json["Msg"]: if "member_count" in json["extra"] and json["extra"]["member_count"] > 0:
self.roomMember = json["Msg"]["member_count"] self.roomPopularity = json["extra"]["member_count"]
if "popularity" in json["Msg"]:
self.roomPopularity = json["Msg"]["popularity"]
elif "data" in json: elif "data" in json:
if "popularity" in json["data"]: if "popularity" in json["data"]:
self.roomPopularity = json["data"]["popularity"] self.roomPopularity = json["data"]["popularity"]
@ -44,7 +43,7 @@ class XiGuaLiveApi:
print(*args) print(*args)
def onPresent(self, gift: Gift): def onPresent(self, gift: Gift):
print("礼物连击 : ", gift) print("礼物连击 :", gift)
def onPresentEnd(self, gift: Gift): def onPresentEnd(self, gift: Gift):
print("感谢", gift) print("感谢", gift)
@ -54,118 +53,169 @@ class XiGuaLiveApi:
pass pass
def onChat(self, chat: Chat): def onChat(self, chat: Chat):
print(chat) if not chat.isFiltered:
print(chat)
def onEnter(self, msg: MemberMsg): def onEnter(self, msg: MemberMsg):
print("提示 : ", msg) print("提示 :", msg)
def onSubscribe(self, user: User): def onSubscribe(self, user: User):
print("消息 : ", user, "关注了主播") print("消息 :", user, "关注了主播")
def onJoin(self, user: User): def onJoin(self, user: User):
print("感谢", user, "加入了粉丝团") print("欢迎", user, "加入了粉丝团")
def onMessage(self, msg: str): def onMessage(self, msg: str):
print("消息 : ", msg) print("消息 :", msg)
def onLike(self, user: User): def onLike(self, user: User):
print("用户", user, "点了喜欢") print("用户", user, "点了喜欢")
def onLeave(self, json: any): def onLeave(self, json: any):
print("消息 : ", "主播离开一小会") print("消息 :", "主播离开")
def _enterRoom(self): def onLottery(self, i:Lottery):
if not self.isValidRoom: print("中奖消息 :", i)
return
p = s.post("https://live.ixigua.com/api/room/enter/{roomID}".format(roomID=self.roomID))
if DEBUG:
print(p.text)
def updRoomInfo(self): def updRoomInfo(self):
p = s.get("https://live.ixigua.com/api/room?anchorId={room}".format(room=self.room)) if self.isLive:
p = s.post("https://i.snssdk.com/videolive/room/enter?version_code=730"
"&device_platform=android",
data="room_id={roomID}&version_code=730"
"&device_platform=android".format(roomID=self.roomID),
headers={"Content-Type":"application/x-www-form-urlencoded"})
d = p.json()
self.isValidRoom = d["base_resp"]["status_code"] == 0
if d["base_resp"]["status_code"] != 0:
return False
if "room" not in d and d["room"] is None:
self.apiChangedError("Api发生改变请及时联系我")
return False
self._rawRoomInfo = d["room"]
self.isLive = d["room"]["status"] == 2
self.roomLiver = User(d)
self.roomTitle = d["room"]["title"]
self.roomPopularity = d["room"]["user_count"]
l = Lottery(d)
if l.isActive:
self.lottery = l
return True
else:
p = s.get("https://security.snssdk.com/video/app/search/live/?version_code=730&device_platform=android"
"&format=json&keyword={}".format(self.name))
d = p.json()
if "data" in d and d["data"] is not None:
for i in d["data"]:
if i["block_type"] != 0:
continue
if len(i["cells"]) == 0:
return
self.isValidRoom = True
self.isLive = i["cells"][0]["anchor"]["user_info"]["is_living"]
self.roomID = int(i["cells"][0]["anchor"]["room_id"])
self.roomLiver = User(i["cells"][0])
if self.isLive:
return self.updRoomInfo()
else:
return False
@staticmethod
def findRoomByUserId(userId:int):
p = s.get("https://live.ixigua.com/api/room?anchorId={room}".format(room=userId))
if DEBUG: if DEBUG:
print(p.text) print(p.text)
d = p.json() d = p.json()
if "data" not in d or "title" not in d["data"] or "id" not in d["data"]: if "data" not in d or "title" not in d["data"] or "id" not in d["data"]:
self.apiChangedError("无法获取RoomID请与我联系") XiGuaLiveApi.apiChangedError("无法获取RoomID请与我联系")
return return XiGuaLiveApi()
self.isValidRoom = True return XiGuaLiveApi(d["data"]["id"])
self._rawRoomInfo = d["data"]
self.roomLiver = User(d) @staticmethod
self.roomTitle = d["data"]["title"] def searchLive(keyword):
self.roomID = d["data"]["id"] ret = []
self._updateRoomInfo(d) p = s.get("https://security.snssdk.com/video/app/search/live/?version_code=730&device_platform=android"
if "status" in d["data"] and d["data"]["status"] == 2: "&format=json&keyword={}".format(keyword))
self.isLive = True d = p.json()
else: if "data" in d:
self.isLive = False for i in d["data"]:
if i["block_type"] != 0:
continue
for _i in i["cells"]:
ret.append(_i["room"])
return ret
def getDanmaku(self): def getDanmaku(self):
if not self.isValidRoom: if not self.isValidRoom:
self.updRoomInfo()
return return
p = s.get("https://live.ixigua.com/api/msg/list/{roomID}?AnchorID={room}&Cursor={cursor}".format( p = s.get("https://i.snssdk.com/videolive/im/get_msg?cursor={cursor}&room_id={roomID}"
roomID=self.roomID, "&version_code=730&device_platform=android".format(
room=self.room, roomID=self.roomID,
cursor=self._cursor cursor=self._cursor
)) ))
d = p.json() d = p.json()
if "data" not in d or "Extra" not in d["data"] or "Cursor" not in d["data"]["Extra"]: if "data" not in d or "extra" not in d or "cursor" not in d["extra"]:
if DEBUG: if DEBUG:
print(d) print(d)
self.apiChangedError("数据结构改变,请与我联系") self.apiChangedError("数据结构改变,请与我联系")
return return
else: else:
self._cursor = d["data"]["Extra"]["Cursor"] self._cursor = d["extra"]["cursor"]
if DEBUG: if DEBUG:
print("Cursor", self._cursor) print("Cursor", self._cursor)
if "LiveMsgs" not in d["data"]: for i in d['data']:
self.updRoomInfo()
return
for i in d['data']['LiveMsgs']:
if DEBUG: if DEBUG:
print(i) print(i)
if "Method" not in i: if "common" not in i and "method" not in i["common"]:
continue continue
if i['Method'] == "VideoLivePresentMessage": if i["common"]['method'] == "VideoLivePresentMessage":
self.onPresent(Gift(i)) self.onPresent(Gift(i))
elif i['Method'] == "VideoLivePresentEndTipMessage": elif i["common"]['method'] == "VideoLivePresentEndTipMessage":
self.onPresentEnd(Gift(i)) self.onPresentEnd(Gift(i))
elif i['Method'] == "VideoLiveRoomAdMessage": elif i["common"]['method'] == "VideoLiveRoomAdMessage":
self.onAd(i) self.onAd(i)
elif i['Method'] == "VideoLiveChatMessage": elif i["common"]['method'] == "VideoLiveChatMessage":
self.onChat(Chat(i)) self.onChat(Chat(i, self.lottery))
elif i['Method'] == "VideoLiveMemberMessage": elif i["common"]['method'] == "VideoLiveMemberMessage":
self._updateRoomInfo(i) self._updateRoomInfo(i)
self.onEnter(MemberMsg(i)) self.onEnter(MemberMsg(i))
elif i['Method'] == "VideoLiveSocialMessage": elif i["common"]['method'] == "VideoLiveSocialMessage":
self.onSubscribe(User(i)) self.onSubscribe(User(i))
elif i['Method'] == "VideoLiveJoinDiscipulusMessage": elif i["common"]['method'] == "VideoLiveJoinDiscipulusMessage":
self.onJoin(User(i)) self.onJoin(User(i))
elif i['Method'] == "VideoLiveControlMessage": elif i["common"]['method'] == "VideoLiveControlMessage":
print("消息:", "主播离开一小会") print("消息:", "主播离开一小会")
elif i['Method'] == "VideoLiveDiggMessage": elif i["common"]['method'] == "VideoLiveDiggMessage":
self.onLike(User(i)) self.onLike(User(i))
else: else:
pass pass
self.lottery = Lottery(i)
self._updRoomCount += 1
if self.lottery is not None or self.lottery.ID != 0:
self.lottery.update()
if self.lottery.isFinished:
self.onLottery(self.lottery)
self.lottery = None
if self._updRoomCount > 120 or len(d['data']) == 0:
self.updRoomInfo()
self._updRoomCount = 0
return
if __name__ == "__main__": if __name__ == "__main__":
room = 97621754276 # 永恒 # name = "永恒de草薙"
# room = 75366565294 name = "尤美"
# room = 83940182312 #Dae if len(sys.argv) > 2:
if len(sys.argv) > 1:
if sys.argv[-1] == "d": if sys.argv[-1] == "d":
DEBUG = True DEBUG = True
try: name = sys.argv[1]
room = int(sys.argv[1])
except ValueError:
pass
print("西瓜直播弹幕助手 by JerryYan") print("西瓜直播弹幕助手 by JerryYan")
api = XiGuaLiveApi(room) api = XiGuaLiveApi(name)
print("进入", api.roomLiver, "的直播间")
if not api.isValidRoom: if not api.isValidRoom:
print(api.roomID)
input("房间不存在") input("房间不存在")
sys.exit() sys.exit()
print("进入", api.roomLiver, "的直播间")
print("=" * 30) print("=" * 30)
while True: while True:
if api.isLive: if api.isLive:

View File

@ -2,6 +2,7 @@
import os import os
import re import re
import shutil
from datetime import datetime from datetime import datetime
import rsa import rsa
@ -11,6 +12,8 @@ import hashlib
import requests import requests
from urllib import parse from urllib import parse
from config import config
class VideoPart: class VideoPart:
def __init__(self, path, title='', desc=''): def __init__(self, path, title='', desc=''):
@ -18,8 +21,10 @@ class VideoPart:
self.title = title self.title = title
self.desc = desc self.desc = desc
class Bilibili: class Bilibili:
def __init__(self, cookie=None): def __init__(self, cookie=None):
self.files = []
self.videos = [] self.videos = []
self.session = requests.session() self.session = requests.session()
if cookie: if cookie:
@ -41,12 +46,12 @@ class Bilibili:
:return: if success return True :return: if success return True
else return msg json else return msg json
""" """
APPKEY = '1d8b6e7d45233436' APPKEY = '1d8b6e7d45233436'
ACTIONKEY = 'appkey' ACTIONKEY = 'appkey'
BUILD = 520001 BUILD = 520001
DEVICE = 'android' DEVICE = 'android'
MOBI_APP = 'android' MOBI_APP = 'android'
PLATFORM = 'android' PLATFORM = 'android'
APPSECRET = '560c52ccd288fed045859ed18bffd973' APPSECRET = '560c52ccd288fed045859ed18bffd973'
def md5(s): def md5(s):
@ -81,9 +86,9 @@ class Bilibili:
:return: hash, key :return: hash, key
""" """
r = self.session.post( r = self.session.post(
'https://passport.bilibili.com/api/oauth2/getKey', 'https://passport.bilibili.com/api/oauth2/getKey',
signed_body({'appkey': APPKEY}), signed_body({'appkey': APPKEY}),
) )
# {"ts":1544152439,"code":0,"data":{"hash":"99c7573759582e0b","key":"-----BEGIN PUBLIC----- -----END PUBLIC KEY-----\n"}} # {"ts":1544152439,"code":0,"data":{"hash":"99c7573759582e0b","key":"-----BEGIN PUBLIC----- -----END PUBLIC KEY-----\n"}}
json = r.json() json = r.json()
data = json['data'] data = json['data']
@ -98,19 +103,19 @@ class Bilibili:
self.session.headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8' self.session.headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8'
h, k = getkey() h, k = getkey()
pwd = base64.b64encode( pwd = base64.b64encode(
rsa.encrypt( rsa.encrypt(
(h + pwd).encode('utf-8'), (h + pwd).encode('utf-8'),
rsa.PublicKey.load_pkcs1_openssl_pem(k.encode()) rsa.PublicKey.load_pkcs1_openssl_pem(k.encode())
) )
) )
user = parse.quote_plus(user) user = parse.quote_plus(user)
pwd = parse.quote_plus(pwd) pwd = parse.quote_plus(pwd)
r = self.session.post( r = self.session.post(
'https://passport.bilibili.com/api/v2/oauth2/login', 'https://passport.bilibili.com/api/v2/oauth2/login',
signed_body('appkey={appkey}&password={password}&username={username}' signed_body('appkey={appkey}&password={password}&username={username}'
.format(appkey=APPKEY, username=user, password=pwd)) .format(appkey=APPKEY, username=user, password=pwd))
) )
try: try:
json = r.json() json = r.json()
except: except:
@ -122,22 +127,21 @@ class Bilibili:
r = self.session.get('https://passport.bilibili.com/captcha') r = self.session.get('https://passport.bilibili.com/captcha')
captcha = cnn_captcha(base64.b64encode(r.content)) captcha = cnn_captcha(base64.b64encode(r.content))
r = self.session.post( r = self.session.post(
'https://passport.bilibili.com/api/v2/oauth2/login', 'https://passport.bilibili.com/api/v2/oauth2/login',
signed_body('actionKey={actionKey}&appkey={appkey}&build={build}&captcha={captcha}&device={device}' signed_body('actionKey={actionKey}&appkey={appkey}&build={build}&captcha={captcha}&device={device}'
'&mobi_app={mobi_app}&password={password}&platform={platform}&username={username}' '&mobi_app={mobi_app}&password={password}&platform={platform}&username={username}'
.format(actionKey=ACTIONKEY, .format(actionKey=ACTIONKEY,
appkey=APPKEY, appkey=APPKEY,
build=BUILD, build=BUILD,
captcha=captcha, captcha=captcha,
device=DEVICE, device=DEVICE,
mobi_app=MOBI_APP, mobi_app=MOBI_APP,
password=pwd, password=pwd,
platform=PLATFORM, platform=PLATFORM,
username=user)), username=user)),
) )
json = r.json() json = r.json()
if json['code'] is not 0: if json['code'] is not 0:
return r.text return r.text
@ -154,7 +158,6 @@ class Bilibili:
return True return True
def upload(self, def upload(self,
parts, parts,
title, title,
@ -186,38 +189,23 @@ class Bilibili:
:type no_reprint: int :type no_reprint: int
""" """
self.preUpload(parts) self.preUpload(parts)
self.finishUpload(title,tid,tag,desc,source,cover,no_reprint) self.finishUpload(title, tid, tag, desc, source, cover, no_reprint)
def preUpload(self,parts): def preUpload(self, parts):
""" """
:param parts: e.g. VideoPart('part path', 'part title', 'part desc'), or [VideoPart(...), VideoPart(...)] :param parts: e.g. VideoPart('part path', 'part title', 'part desc'), or [VideoPart(...), VideoPart(...)]
:type parts: VideoPart or list<VideoPart> :type parts: VideoPart or list<VideoPart>
:param title: video's title
:type title: str
:param tid: video type, see: https://member.bilibili.com/x/web/archive/pre
or https://github.com/uupers/BiliSpider/wiki/%E8%A7%86%E9%A2%91%E5%88%86%E5%8C%BA%E5%AF%B9%E5%BA%94%E8%A1%A8
:type tid: int
:param tag: video's tag
:type tag: list<str>
:param desc: video's description
:type desc: str
:param source: (optional) 转载地址
:type source: str
:param cover: (optional) cover's URL, use method *cover_up* to get
:type cover: str
:param no_reprint: (optional) 0=可以转载, 1=禁止转载(default)
:type no_reprint: int
""" """
self.session.headers['Content-Type'] = 'application/json; charset=utf-8' self.session.headers['Content-Type'] = 'application/json; charset=utf-8'
if not isinstance(parts, list): if not isinstance(parts, list):
parts = [parts] parts = [parts]
videos = []
for part in parts: for part in parts:
filepath = part.path filepath = part.path
filename = os.path.basename(filepath) filename = os.path.basename(filepath)
filesize = os.path.getsize(filepath) filesize = os.path.getsize(filepath)
self.files.append(part)
r = self.session.get('https://member.bilibili.com/preupload?' r = self.session.get('https://member.bilibili.com/preupload?'
'os=upos&upcdn=ws&name={name}&size={size}&r=upos&profile=ugcupos%2Fyb&ssl=0' 'os=upos&upcdn=ws&name={name}&size={size}&r=upos&profile=ugcupos%2Fyb&ssl=0'
.format(name=filename, size=filesize)) .format(name=filename, size=filesize))
@ -276,7 +264,7 @@ class Bilibili:
chunks_data, chunks_data,
) )
print('{} : UPLOAD {}/{}'.format(datetime.strftime(datetime.now(), "%y%m%d %H%M"), chunks_index, print('{} : UPLOAD {}/{}'.format(datetime.strftime(datetime.now(), "%y%m%d %H%M"), chunks_index,
chunks_num), r.text) chunks_num), r.text)
# NOT DELETE! Refer to https://github.com/comwrg/bilibiliupload/issues/15#issuecomment-424379769 # NOT DELETE! Refer to https://github.com/comwrg/bilibiliupload/issues/15#issuecomment-424379769
self.session.post('https:{endpoint}/{upos_uri}?' self.session.post('https:{endpoint}/{upos_uri}?'
@ -291,8 +279,8 @@ class Bilibili:
) )
self.videos.append({'filename': upos_uri.replace('upos://ugc/', '').split('.')[0], self.videos.append({'filename': upos_uri.replace('upos://ugc/', '').split('.')[0],
'title': part.title, 'title': part.title,
'desc': part.desc}) 'desc': part.desc})
def finishUpload(self, def finishUpload(self,
title, title,
@ -303,26 +291,144 @@ class Bilibili:
cover='', cover='',
no_reprint=1, no_reprint=1,
): ):
"""
:param title: video's title
:type title: str
:param tid: video type, see: https://member.bilibili.com/x/web/archive/pre
or https://github.com/uupers/BiliSpider/wiki/%E8%A7%86%E9%A2%91%E5%88%86%E5%8C%BA%E5%AF%B9%E5%BA%94%E8%A1%A8
:type tid: int
:param tag: video's tag
:type tag: list<str>
:param desc: video's description
:type desc: str
:param source: (optional) 转载地址
:type source: str
:param cover: (optional) cover's URL, use method *cover_up* to get
:type cover: str
:param no_reprint: (optional) 0=可以转载, 1=禁止转载(default)
:type no_reprint: int
"""
self.session.headers['Content-Type'] = 'application/json; charset=utf-8'
copyright = 2 if source else 1 copyright = 2 if source else 1
r = self.session.post('https://member.bilibili.com/x/vu/web/add?csrf=' + self.csrf, r = self.session.post('https://member.bilibili.com/x/vu/web/add?csrf=' + self.csrf,
json={ json={
"copyright" : copyright, "copyright": copyright,
"source" : source, "source": source,
"title" : title, "title": title,
"tid" : tid, "tid": tid,
"tag" : ','.join(tag), "tag": ','.join(tag),
"no_reprint": no_reprint, "no_reprint": no_reprint,
"desc" : desc, "desc": desc,
"cover" : cover, "cover": cover,
"mission_id": 0, "mission_id": 0,
"order_id" : 0, "order_id": 0,
"videos" : self.videos} "videos": self.videos}
) )
print(r.text) print(r.text)
for _p in self.videos: if config["mv"]:
os.remove(_p.path) for _p in self.files:
shutil.move(_p.path, config["mtd"])
elif config["del"]:
for _p in self.files:
os.remove(_p.path)
def appendUpload(self,
aid,
parts,
title="",
tid="",
tag="",
desc="",
source='',
cover='',
no_reprint=1,
):
"""
:param aid: just aid
:type aid: int
:param parts: e.g. VideoPart('part path', 'part title', 'part desc'), or [VideoPart(...), VideoPart(...)]
:type parts: VideoPart or list<VideoPart>
:param title: video's title
:type title: str
:param tid: video type, see: https://member.bilibili.com/x/web/archive/pre
or https://github.com/uupers/BiliSpider/wiki/%E8%A7%86%E9%A2%91%E5%88%86%E5%8C%BA%E5%AF%B9%E5%BA%94%E8%A1%A8
:type tid: int
:param tag: video's tag
:type tag: list<str>
:param desc: video's description
:type desc: str
:param source: (optional) 转载地址
:type source: str
:param cover: (optional) cover's URL, use method *cover_up* to get
:type cover: str
:param no_reprint: (optional) 0=可以转载, 1=禁止转载(default)
:type no_reprint: int
"""
self.session.headers['Content-Type'] = 'application/json; charset=utf-8'
p = self.session.get("https://member.bilibili.com/x/web/archive/view?aid={}&history=".format(aid))
j = p.json()
if len(self.videos) == 0:
for i in j['data']['videos']:
self.videos.append({'filename': i['filename'],
'title': i["title"],
'desc': i["desc"]})
if (title == ""): title = j["data"]["archive"]['title']
if (tag == ""): tag = j["data"]["archive"]['tag']
if (no_reprint == ""): no_reprint = j["data"]["archive"]['no_reprint']
if (desc == ""): desc = j["data"]["archive"]['desc']
if (source == ""): source = j["data"]["archive"]['source']
if (tid == ""): tid = j["data"]["archive"]['tid']
self.preUpload(parts)
self.editUpload(aid, title, tid, tag, desc, source, cover, no_reprint)
def editUpload(self,
aid,
title,
tid,
tag,
desc,
source='',
cover='',
no_reprint=1,
):
"""
:param aid: just aid
:type aid: int
:param parts: e.g. VideoPart('part path', 'part title', 'part desc'), or [VideoPart(...), VideoPart(...)]
:type parts: VideoPart or list<VideoPart>
:param title: video's title
:type title: str
:param tid: video type, see: https://member.bilibili.com/x/web/archive/pre
or https://github.com/uupers/BiliSpider/wiki/%E8%A7%86%E9%A2%91%E5%88%86%E5%8C%BA%E5%AF%B9%E5%BA%94%E8%A1%A8
:type tid: int
:param tag: video's tag
:type tag: list<str>
:param desc: video's description
:type desc: str
:param source: (optional) 转载地址
:type source: str
:param cover: (optional) cover's URL, use method *cover_up* to get
:type cover: str
:param no_reprint: (optional) 0=可以转载, 1=禁止转载(default)
:type no_reprint: int
"""
copyright = 2 if source else 1
r = self.session.post('https://member.bilibili.com/x/vu/web/edit?csrf=' + self.csrf,
json={
"aid": aid,
"copyright": copyright,
"source": source,
"title": title,
"tid": tid,
"tag": ','.join(tag),
"no_reprint": no_reprint,
"desc": desc,
"cover": cover,
"mission_id": 0,
"order_id": 0,
"videos": self.videos}
)
print(r.text)
def addChannel(self, name, intro=''): def addChannel(self, name, intro=''):
""" """
@ -333,14 +439,14 @@ class Bilibili:
:type intro: str :type intro: str
""" """
r = self.session.post( r = self.session.post(
url='https://space.bilibili.com/ajax/channel/addChannel', url='https://space.bilibili.com/ajax/channel/addChannel',
data={ data={
'name' : name, 'name': name,
'intro': intro, 'intro': intro,
'aids' : '', 'aids': '',
'csrf' : self.csrf, 'csrf': self.csrf,
}, },
# name=123&intro=123&aids=&csrf=565d7ed17cef2cc8ad054210c4e64324&_=1497077610768 # name=123&intro=123&aids=&csrf=565d7ed17cef2cc8ad054210c4e64324&_=1497077610768
) )
# return # return
@ -357,13 +463,13 @@ class Bilibili:
""" """
r = self.session.post( r = self.session.post(
url='https://space.bilibili.com/ajax/channel/addVideo', url='https://space.bilibili.com/ajax/channel/addVideo',
data={ data={
'aids': '%2C'.join(aids), 'aids': '%2C'.join(aids),
'cid' : cid, 'cid': cid,
'csrf': self.csrf 'csrf': self.csrf
} }
# aids=9953555%2C9872953&cid=15814&csrf=565d7ed17cef2cc8ad054210c4e64324&_=1497079332679 # aids=9953555%2C9872953&cid=15814&csrf=565d7ed17cef2cc8ad054210c4e64324&_=1497079332679
) )
print(r.json()) print(r.json())
@ -380,13 +486,12 @@ class Bilibili:
else: else:
f = img f = img
r = self.session.post( r = self.session.post(
url='https://member.bilibili.com/x/vu/web/cover/up', url='https://member.bilibili.com/x/vu/web/cover/up',
data={ data={
'cover': b'data:image/jpeg;base64,' + (base64.b64encode(f.read())), 'cover': b'data:image/jpeg;base64,' + (base64.b64encode(f.read())),
'csrf': self.csrf, 'csrf': self.csrf,
} }
) )
# print(r.text) # print(r.text)
# {"code":0,"data":{"url":"http://i0.hdslb.com/bfs/archive/67db4a6eae398c309244e74f6e85ae8d813bd7c9.jpg"},"message":"","ttl":1} # {"code":0,"data":{"url":"http://i0.hdslb.com/bfs/archive/67db4a6eae398c309244e74f6e85ae8d813bd7c9.jpg"},"message":"","ttl":1}
return r.json()['data']['url'] return r.json()['data']['url']

View File

@ -12,7 +12,7 @@ q = queue.Queue()
base_uri = "" base_uri = ""
isUpload = False isUpload = False
uq = queue.Queue() uq = queue.Queue()
d = datetime.strftime(datetime.now(),"%Y_%m_%d")
class downloader(XiGuaLiveApi): class downloader(XiGuaLiveApi):
files = [] files = []
@ -23,33 +23,44 @@ class downloader(XiGuaLiveApi):
self.updPlayList() self.updPlayList()
def updPlayList(self): def updPlayList(self):
if "playInfo" not in self._rawRoomInfo or "Main" not in self._rawRoomInfo["playInfo"]: if "stream_url" not in self._rawRoomInfo:
if self.playlist is None: if self.playlist is None:
self.apiChangedError("无法获取直播链接") self.apiChangedError("无法获取直播链接")
self.playlist = False self.playlist = False
else: else:
self.playlist = self._rawRoomInfo["playInfo"]["Main"]["1"]["Url"]["HlsUrl"] self.playlist = self._rawRoomInfo["stream_url"]["alternate_pull_url"]
self.playlist = self.playlist.replace("_uhd","").replace("_sd","").replace("_ld","")
def onLike(self, user): def onLike(self, user):
pass pass
def onAd(self, i): def onAd(self, i):
pass pass
def onChat(self, chat): def onChat(self, chat):
pass pass
def onEnter(self, msg): def onEnter(self, msg):
pass pass
def onJoin(self, user): def onJoin(self, user):
pass pass
def onLeave(self, json): def onLeave(self, json):
self.updRoomInfo() self.updRoomInfo()
def onMessage(self, msg): def onMessage(self, msg):
pass pass
def onPresent(self, gift): def onPresent(self, gift):
pass pass
def onPresentEnd(self, gift): def onPresentEnd(self, gift):
pass pass
def onSubscribe(self, user): def onSubscribe(self, user):
pass pass
def preDownload(self): def preDownload(self):
global base_uri global base_uri
if self.playlist: if self.playlist:
@ -63,16 +74,17 @@ class downloader(XiGuaLiveApi):
if i not in self.files: if i not in self.files:
self.files.append(i) self.files.append(i)
print("{} : Add Sequence {}".format(datetime.strftime(datetime.now(), "%y%m%d %H%M"), print("{} : Add Sequence {}".format(datetime.strftime(datetime.now(), "%y%m%d %H%M"),
len(self.files))) len(self.files)))
q.put(i) q.put(i)
self.genNewName() self.genNewName()
def genNewName(self): def genNewName(self):
if len(self.files) > 800: if len(self.files) > 800:
q.put(True) q.put(True)
self.files.clear() self.files.clear()
def download(path=datetime.strftime(datetime.now(),"%Y%m%d_%H%M.ts")): def download(path=datetime.strftime(datetime.now(), "%Y%m%d_%H%M.ts")):
global isUpload global isUpload
print("{} : Download Daemon Starting".format(datetime.strftime(datetime.now(), "%y%m%d %H%M"))) print("{} : Download Daemon Starting".format(datetime.strftime(datetime.now(), "%y%m%d %H%M")))
n = False n = False
@ -84,31 +96,31 @@ def download(path=datetime.strftime(datetime.now(),"%Y%m%d_%H%M.ts")):
break break
print("{} : Download {}".format(datetime.strftime(datetime.now(), "%y%m%d %H%M"), i)) print("{} : Download {}".format(datetime.strftime(datetime.now(), "%y%m%d %H%M"), i))
try: try:
_p = requests.get("{}{}".format(base_uri,i)) _p = requests.get("{}{}".format(base_uri, i))
except: except:
continue continue
f = open(path, "ab") f = open(path, "ab")
f.write(_p.content) f.write(_p.content)
f.close() f.close()
n=True n = True
i = q.get() i = q.get()
if n: if n:
isUpload = True
uq.put(path) uq.put(path)
print("{} : Download Daemon Quiting".format(datetime.strftime(datetime.now(), "%y%m%d %H%M"))) print("{} : Download Daemon Quiting".format(datetime.strftime(datetime.now(), "%y%m%d %H%M")))
isUpload = True
def upload(date=datetime.strftime(datetime.now(), "%Y_%m_%d")):
def upload(date = datetime.strftime(datetime.now(), "%Y_%m_%d")):
print("{} : Upload Daemon Starting".format(datetime.strftime(datetime.now(), "%y%m%d %H%M"))) print("{} : Upload Daemon Starting".format(datetime.strftime(datetime.now(), "%y%m%d %H%M")))
i = uq.get() i = uq.get()
while True: while True:
if isinstance(i, bool): if isinstance(i, bool):
print("{} : Upload Daemon Receive Command {}"
.format(datetime.strftime(datetime.now(), "%y%m%d %H%M"), i))
if i is True: if i is True:
print("自动投稿中,请稍后") print("自动投稿中,请稍后")
b.finishUpload(config["t_t"].format(date),17, config["tag"],config["des"], b.finishUpload(config["t_t"].format(date), 17, config["tag"], config["des"],
source= "https://live.ixigua.com/userlive/97621754276", no_reprint= 0) source=config["src"], no_reprint=0)
print("{} : Upload Daemon Receive Command {}".format(datetime.strftime(datetime.now(), "%y%m%d %H%M"), i))
break break
print("{} : Upload {}".format(datetime.strftime(datetime.now(), "%y%m%d %H%M"), i)) print("{} : Upload {}".format(datetime.strftime(datetime.now(), "%y%m%d %H%M"), i))
try: try:
@ -123,23 +135,21 @@ b = Bilibili()
b.login(config["b_u"], config["b_p"]) b.login(config["b_u"], config["b_p"])
if __name__ == "__main__": if __name__ == "__main__":
room = 97621754276 # 永恒 name = "永恒de草薙"
# room = 75366565294 # room = 75366565294
# room = 83940182312 #Dae # room = 83940182312 #Dae
# room = 5947850784 #⑦ # room = 5947850784 #⑦
# room = 58649240617 #戏 # room = 58649240617 #戏
if len(sys.argv) > 1: if len(sys.argv) > 1:
try: name = sys.argv[1]
room = int(sys.argv[1])
except ValueError:
pass
print("西瓜直播录播助手 by JerryYan") print("西瓜直播录播助手 by JerryYan")
api = downloader(room) api = downloader(name)
print("进入", api.roomLiver, "的直播间") print("进入", api.roomLiver, "的直播间")
if not api.isValidRoom: if not api.isValidRoom:
input("房间不存在") input("房间不存在")
sys.exit() sys.exit()
print("=" * 30) print("=" * 30)
d = datetime.strftime(datetime.now(), "%Y_%m_%d")
_preT = datetime.strftime(datetime.now(), "%Y%m%d_%H%M.ts") _preT = datetime.strftime(datetime.now(), "%Y%m%d_%H%M.ts")
t = threading.Thread(target=download, args=(_preT,)) t = threading.Thread(target=download, args=(_preT,))
ut = threading.Thread(target=upload, args=(d,)) ut = threading.Thread(target=upload, args=(d,))
@ -162,13 +172,15 @@ if __name__ == "__main__":
pass pass
time.sleep(3) time.sleep(3)
else: else:
q.put(False) if d is not None:
q.put(False)
d = None
if isUpload: if isUpload:
uq.put(True) uq.put(True)
isUpload = False isUpload = False
else: else:
pass del config
from config import config
# print("主播未开播等待1分钟后重试") # print("主播未开播等待1分钟后重试")
time.sleep(60) time.sleep(60)
d=None
api.updRoomInfo() api.updRoomInfo()