mirror of https://github.com/ekimekim/wubloader
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
75 lines
2.0 KiB
Python
75 lines
2.0 KiB
Python
|
|
import json
|
|
import sys
|
|
|
|
import argh
|
|
|
|
CHAT_BOX = (1220, 100, 1910, 810)
|
|
|
|
def encode_time(time):
|
|
hours, time = divmod(time, 3600)
|
|
mins, secs = divmod(time, 60)
|
|
return f"{int(hours)}:{int(mins):02d}:{secs:05.2f}"
|
|
|
|
def encode_dialogue(start, end, text):
|
|
return f"Dialogue: {encode_time(start)}, {encode_time(end)}, Chat, {text}"
|
|
|
|
def message_to_line(message, time_base):
|
|
time = message["time"] - time_base
|
|
tags = message.get("tags", {})
|
|
|
|
sender = tags.get("display-name")
|
|
if sender is None:
|
|
sender = message["sender"]
|
|
|
|
content = message["params"][1]
|
|
if content.startswith("\x01"):
|
|
content = content[1:-1].split(" ", 1)[1]
|
|
text = f"{sender} {content}"
|
|
else:
|
|
text = f"{sender}: {content}"
|
|
|
|
color = tags.get("color")
|
|
if color is None:
|
|
color = "FFFFFF"
|
|
else:
|
|
color = color.lstrip("#")
|
|
text = f"{{ \\c&H{color}& }}" + text
|
|
return time, text
|
|
|
|
def lines_to_dialogue(start, end, lines):
|
|
lines = "\\N".join([text for start, text in lines][::-1])
|
|
clip_args = ",".join(map(str, CHAT_BOX))
|
|
text = f"{{ \\clip({clip_args}) }}" + lines
|
|
return encode_dialogue(start, end, text)
|
|
|
|
def gen_dialogues(messages, time_base, message_ttl=10):
|
|
window = []
|
|
prev_start = None
|
|
for message in messages:
|
|
next_start, text = message_to_line(message, time_base)
|
|
while window and window[0][0] + message_ttl < next_start:
|
|
end = window[0][0] + message_ttl
|
|
yield lines_to_dialogue(prev_start, end, window)
|
|
window.pop(0)
|
|
prev_start = end
|
|
window.append((next_start, text))
|
|
if prev_start is not None:
|
|
yield lines_to_dialogue(prev_start, next_start, window)
|
|
prev_start = next_start
|
|
# flush remaining messages
|
|
while window:
|
|
end = window[0][0] + message_ttl
|
|
yield lines_to_dialogue(prev_start, end, window)
|
|
window.pop(0)
|
|
prev_start = end
|
|
|
|
def main(time_base=0):
|
|
messages = sys.stdin.read().strip().split("\n")
|
|
messages = [json.loads(line) for line in messages]
|
|
for dialogue in gen_dialogues(messages, time_base):
|
|
print(dialogue)
|
|
|
|
if __name__ == '__main__':
|
|
argh.dispatch_command(main)
|