This repository has been archived on 2022-05-30. You can view files and clone it, but cannot push or open issues or pull requests.
Jerry Yan 6719164b4e Initial Commit
XiguaLiveDanmakuHelper
2019-01-15 18:24:59 +08:00

337 lines
11 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import sys
import requests
import time
import ctypes
import os
class UserStruct:
ID = 0
name = ""
brand= ""
level= 0
type = 0
def __init__(self, json=None):
if json:
self.parse(json)
def parse(self, json):
if "Msg" in json:
if "user" in json["Msg"]:
self.ID = json["Msg"]['user']['user_id']
self.name = json["Msg"]['user']['name']
self.type = json["Msg"]['user']['user_type']
if "discipulus_info" in json["Msg"]:
self.level = json["Msg"]["discipulus_info"]["level"]
self.brand = json["Msg"]["discipulus_info"]["discipulus_group_title"]
if self.type is None:
self.type = 0
def __str__(self):
if self.level == 0:
if self.type != 0:
return "[]{}".format(self.name)
return "{}".format(self.name)
else:
if self.type != 0:
return "[{}{}]{}".format(self.brand, self.level, self.name)
return "<{}{}>{}".format(self.brand,self.level,self.name)
def __unicode__(self):
return self.__str__()
class GiftStruct:
ID = 0
count = 0
def __init__(self, json=None):
if json:
self.parse(json)
def parse(self, json):
if "Msg" in json:
if "present_end_info" in json["Msg"]:
self.ID = json["Msg"]['present_end_info']['id']
self.count = json["Msg"]['present_end_info']['count']
elif "present_info" in json["Msg"]:
self.ID = json["Msg"]['present_info']['id']
self.count = json["Msg"]['present_info']['repeat_count']
def readInput(caption, default, timeout=5):
start_time = time.time()
print('{}({})\r\n>'.format(caption,default), end="")
input = ''
while True:
if msvcrt.kbhit():
chr = msvcrt.getche()
if ord(chr) == 13: # enter_key
break
elif ord(chr) == 27:
break
elif ord(chr) >= 32: # space_char
input += str(chr)
if len(input) == 0 and (time.time() - start_time) > timeout:
break
if len(input) > 0:
print()
return input
else:
print("使用默认值")
return default
STD_INPUT_HANDLE = -10
STD_OUTPUT_HANDLE = -11
STD_ERROR_HANDLE = -12
std_out_handle = ctypes.windll.kernel32.GetStdHandle(STD_OUTPUT_HANDLE)
# 字体颜色定义 ,关键在于颜色编码由2位十六进制组成分别取0~f前一位指的是背景色后一位指的是字体色
#由于该函数的限制应该是只有这16种可以前景色与背景色组合。也可以几种颜色通过或运算组合组合后还是在这16种颜色中
# Windows CMD命令行 字体颜色定义 text colors
FOREGROUND_BLACK = 0x00 # black.
FOREGROUND_DARKBLUE = 0x01 # dark blue.
FOREGROUND_DARKGREEN = 0x02 # dark green.
FOREGROUND_DARKSKYBLUE = 0x03 # dark skyblue.
FOREGROUND_DARKRED = 0x04 # dark red.
FOREGROUND_DARKPINK = 0x05 # dark pink.
FOREGROUND_DARKYELLOW = 0x06 # dark yellow.
FOREGROUND_DARKWHITE = 0x07 # dark white.
FOREGROUND_DARKGRAY = 0x08 # dark gray.
FOREGROUND_BLUE = 0x09 # blue.
FOREGROUND_GREEN = 0x0a # green.
FOREGROUND_SKYBLUE = 0x0b # skyblue.
FOREGROUND_RED = 0x0c # red.
FOREGROUND_PINK = 0x0d # pink.
FOREGROUND_YELLOW = 0x0e # yellow.
FOREGROUND_WHITE = 0x0f # white.
# Windows CMD命令行 背景颜色定义 background colors
BACKGROUND_BLUE = 0x10 # dark blue.
BACKGROUND_GREEN = 0x20 # dark green.
BACKGROUND_DARKSKYBLUE = 0x30 # dark skyblue.
BACKGROUND_DARKRED = 0x40 # dark red.
BACKGROUND_DARKPINK = 0x50 # dark pink.
BACKGROUND_DARKYELLOW = 0x60 # dark yellow.
BACKGROUND_DARKWHITE = 0x70 # dark white.
BACKGROUND_DARKGRAY = 0x80 # dark gray.
BACKGROUND_BLUE = 0x90 # blue.
BACKGROUND_GREEN = 0xa0 # green.
BACKGROUND_SKYBLUE = 0xb0 # skyblue.
BACKGROUND_RED = 0xc0 # red.
BACKGROUND_PINK = 0xd0 # pink.
BACKGROUND_YELLOW = 0xe0 # yellow.
BACKGROUND_WHITE = 0xf0 # white.
s = requests.Session()
def set_cmd_text_color(color, handle=std_out_handle):
Bool = ctypes.windll.kernel32.SetConsoleTextAttribute(handle, color)
return Bool
def resetColor():
set_cmd_text_color(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE)
class XiGuaLiveApi:
isLive = False
roomInfo = {}
roomID = 0
cursor = ""
giftList = {10001:"西瓜"}
def __init__(self, room: int):
self.room = room
self.updRoomInfo()
self.updGiftList()
def notLiveError(self):
print("主播未开播")
def apiChangedError(self, msg:str):
print(msg)
def onPresent(self, user:UserStruct, gift:GiftStruct):
if gift.ID not in self.giftList:
giftN = "未知礼物:{}".format(gift.ID)
else:
giftN = self.giftList[gift.ID]
return
print("礼物连击:", user, giftN, "x", gift.count)
def onPresentEnd(self, user:UserStruct, gift:GiftStruct):
if gift.ID not in self.giftList:
self.updGiftList()
giftN = "未知礼物:{}".format(gift.ID)
else:
giftN = self.giftList[gift.ID]
set_cmd_text_color(BACKGROUND_WHITE | FOREGROUND_BLACK)
print("感谢", user, "送出的", giftN, "x", gift.count)
resetColor()
def onAd(self, i):
# print(i)
pass
def onChat(self, user:UserStruct, content:str):
print(user, "", content)
# pass
def onEnter(self, user:UserStruct, content:str == ""):
if content == "":
if user.name == "三国空白" or user.name == "四维v":
set_cmd_text_color(FOREGROUND_DARKGRAY)
print("消息:", user, "进入直播间")
resetColor()
else:
set_cmd_text_color(FOREGROUND_DARKGRAY)
print("消息:", content.format(user))
resetColor()
def onSubscribe(self, user:UserStruct):
if user.level >= 6 and user.brand == "永恒":
set_cmd_text_color(FOREGROUND_DARKGRAY)
print("消息:", user, "关注了主播")
resetColor()
def onJoin(self, user:UserStruct):
set_cmd_text_color(BACKGROUND_WHITE | FOREGROUND_BLACK)
print("感谢", user, "加入了粉丝团")
resetColor()
def onMessage(self, msg:str):
set_cmd_text_color(FOREGROUND_DARKGRAY)
print("消息:", msg)
resetColor()
def onLike(self, user:UserStruct):
return
# set_cmd_text_color(FOREGROUND_DARKGRAY)
# print("用户", user, "点了喜欢")
# resetColor()
def onLeave(self, json:any):
print("消息:", "主播离开一小会")
self.debug(json)
return
def updGiftList(self):
p = s.get("https://live.ixigua.com/api/gifts/{roomID}".format(roomID=self.roomID))
d = p.json()
self.debug(d)
if "data" not in d:
self.warning("Warning: Api Has Changed")
return
for i in d["data"]:
self.debug(i["ID"], i["Name"])
self.giftList[i["ID"]] = i["Name"]
def warning(self, *args):
print(args)
def debug(self, *args):
# print(args)
pass
def enterRoom(self):
p = s.post("https://live.ixigua.com/api/room/enter/{roomID}".format(roomID=self.roomID))
self.debug(p.json())
def updRoomInfo(self):
p = s.get("https://live.ixigua.com/api/room/{room}".format(room=self.room))
d = p.json()
self.debug(d)
if "data" not in d:
self.apiChangedError("数据结构改变,请与我联系")
self.debug(d)
return
self.roomInfo = d["data"]
print("进入", self.roomInfo["anchorInfo"]["name"], "的直播间")
if "Id" in d["data"]:
self.roomID = d["data"]["Id"]
else:
self.warning("无法获取RoomID请与我联系")
if "FinishTime" in d["data"]:
self.isLive = False
self.notLiveError()
else:
self.isLive = True
def getDanmaku(self):
p = s.get("https://live.ixigua.com/api/msg/list/{roomID}?AnchorID={room}&Cursor={cursor}".format(
roomID=self.roomID,
room=self.room,
cursor=self.cursor
))
d = p.json()
self.debug(d)
if "data" not in d:
self.apiChangedError("数据结构改变,请与我联系")
self.debug(d)
return
if "Extra" not in d["data"]:
self.apiChangedError("数据结构改变,请与我联系")
self.debug(d["data"])
return
if "Cursor" not in d["data"]["Extra"]:
self.apiChangedError("数据结构改变,请与我联系")
self.debug(d["data"])
return
else:
self.cursor = d["data"]["Extra"]["Cursor"]
if "LiveMsgs" not in d["data"]:
return
for i in d['data']['LiveMsgs']:
if i['Method'] == "VideoLivePresentMessage":
self.onPresent(UserStruct(i), GiftStruct(i))
elif i['Method'] == "VideoLivePresentEndTipMessage":
self.onPresentEnd(UserStruct(i), GiftStruct(i))
elif i['Method'] == "VideoLiveRoomAdMessage":
self.onAd(i)
elif i['Method'] == "VideoLiveChatMessage":
self.onChat(UserStruct(i), i["Msg"]['content'])
elif i['Method'] == "VideoLiveMemberMessage":
self.onEnter(UserStruct(i), i["Msg"]["content"])
elif i['Method'] == "VideoLiveSocialMessage":
self.onSubscribe(UserStruct(i))
elif i['Method'] == "VideoLiveJoinDiscipulusMessage":
self.onJoin(UserStruct(i))
elif i['Method'] == "VideoLiveControlMessage":
print("消息:", "主播离开一小会")
elif i['Method'] == "VideoLiveDiggMessage":
self.onLike(UserStruct(i))
else:
self.debug(i)
if __name__ == "__main__":
room = 97621754276 #永恒
# room = 75366565294
# room = 83940182312 #Dae
if len(sys.argv)>1:
room = int(sys.argv[1])
resetColor()
print("西瓜直播弹幕助手 by JerryYan")
print("正在进入房间", room)
api = XiGuaLiveApi(room)
os.system("title {} {}".format(api.roomInfo["anchorInfo"]["name"],"的直播间 --西瓜直播弹幕助手 by JerryYan"))
api.enterRoom()
print("="*30)
while True:
if api.isLive:
try:
api.getDanmaku()
except Exception as e:
api.warning(e)
time.sleep(1)
else:
print("主播未开播等待1分钟后重试")
time.sleep(60)
api.updRoomInfo()