|
@@ -0,0 +1,83 @@
|
|
|
+
|
|
|
+from chat_downloader import ChatDownloader
|
|
|
+import sys
|
|
|
+import math
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+def sec2hms(sec):
|
|
|
+ hms = str(int(sec//3600)).zfill(2)+':' + \
|
|
|
+ str(int((sec % 3600)//60)).zfill(2)+':'+str(round(sec % 60, 2))
|
|
|
+ return hms
|
|
|
+
|
|
|
+url = 'youtu.be/'+sys.argv[1]
|
|
|
+chat = ChatDownloader().get_chat(url,message_groups=['messages','superchat'])
|
|
|
+name = 'DIALOGUE Official Channel'
|
|
|
+
|
|
|
+limitLineAmount = 12
|
|
|
+danmakuPassageway = []
|
|
|
+for i in range(limitLineAmount):
|
|
|
+ danmakuPassageway.append(0)
|
|
|
+fontName = 'Source Han Sans JP'
|
|
|
+videoWidth = 1280
|
|
|
+videoHeight = 720
|
|
|
+OfficeBgHeight = 72
|
|
|
+OfficeSize = 36
|
|
|
+fontSize = 58
|
|
|
+head = '[Script Info]\n\
|
|
|
+; Script generated by Aegisub 3.2.2\n\
|
|
|
+; http://www.aegisub.org/\n\
|
|
|
+ScriptType: v4.00+\n\
|
|
|
+PlayResX: 1280\n\
|
|
|
+PlayResY: 720\n\
|
|
|
+\n\
|
|
|
+[V4+ Styles]\n\
|
|
|
+Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, marginL, marginR, marginV, Encoding\n\
|
|
|
+Style: Default,微软雅黑,54,&H00FFFFFF,&H00FFFFFF,&H00000000,&H00000000,0,0,0,0,100,100,0,0,1,2,0,2,0,0,0,0\n\
|
|
|
+Style: Alternate,微软雅黑,36,&H00FFFFFF,&H00FFFFFF,&H00000000,&H00000000,0,0,0,0,100,100,0,0,1,2,0,2,0,0,0,0\n\
|
|
|
+Style: Office,'+fontName+','+str(OfficeSize)+',&H0FFFFFF,&H00FFFFFF,&H00000000,&H00000000,-1,0,0,0,100,100,2,0,1,1.5,0,2,0,0,10,0\n\
|
|
|
+Style: Danmaku,'+fontName+','+str(fontSize)+',&H00FFFFFF,&H00FFFFFF,&H00000000,&H00000000,-1,0,0,0,100,100,2,0,1,1.5,0,2,0,0,10,0\n\n\
|
|
|
+[Events]\n\
|
|
|
+Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\n'
|
|
|
+
|
|
|
+f = open(sys.argv[1]+'.ass','w',encoding='utf-8-sig')
|
|
|
+f.write(head)
|
|
|
+for message in chat:
|
|
|
+ if message['time_in_seconds'] > 0:
|
|
|
+ vpos = message['time_in_seconds']
|
|
|
+ vpos_end = vpos+8
|
|
|
+ else:
|
|
|
+
|
|
|
+ continue
|
|
|
+ if 'money' in message.keys():
|
|
|
+ text = '('+str(message['money']['amount'])+message['money']['currency']+')'
|
|
|
+ if 'message' in message.keys():
|
|
|
+ text += message['message']
|
|
|
+ vpos_end += 2
|
|
|
+ else:
|
|
|
+ text=message['author']['name']+': '+message['message'] if message['author']['name'] == name else message['message']
|
|
|
+
|
|
|
+ if message['author']['name'] == name:
|
|
|
+ f.write('Dialogue: 4,'+sec2hms(vpos)+','+sec2hms(vpos_end)+',Office,,0,0,0,,{\\an5\\p1\\pos('+str(videoWidth/2)+','+str(math.floor(OfficeBgHeight/2))+')\\bord0\\1c&H000000&\\1a&H78&}'+'m 0 0 l '+str(videoWidth)+' 0 l '+str(videoWidth) + ' '+str(OfficeBgHeight)+' l 0 '+str(OfficeBgHeight)+'\n')
|
|
|
+ f.write('Dialogue: 5,'+sec2hms(vpos)+','+sec2hms(vpos_end)+',Office,,0,0,0,,{\\an5\\pos('+str(videoWidth/2)+','+str(math.floor(OfficeBgHeight/2))+')\\bord0\\fsp0}'+text+'\n')
|
|
|
+ else:
|
|
|
+ vpos_next_min = float('inf')
|
|
|
+ vpos_next = vpos+1280/(len(text)*60+1280) * 8
|
|
|
+ for i in range(limitLineAmount):
|
|
|
+ if vpos_next >= danmakuPassageway[i]:
|
|
|
+ passageway_index = i
|
|
|
+ danmakuPassageway[i] = vpos+8
|
|
|
+ break
|
|
|
+ elif danmakuPassageway[i] < vpos_next_min:
|
|
|
+ vpos_next_min = danmakuPassageway[i]
|
|
|
+ Passageway_min = i
|
|
|
+ if i == limitLineAmount-1 and vpos_next < vpos_next_min:
|
|
|
+ passageway_index = Passageway_min
|
|
|
+ danmakuPassageway[Passageway_min] = vpos+8
|
|
|
+
|
|
|
+ sx = videoWidth
|
|
|
+ sy = fontSize*(passageway_index)
|
|
|
+ ex = 0-len(text)*60
|
|
|
+ ey = fontSize*(passageway_index)
|
|
|
+ f.write('Dialogue: 0,'+sec2hms(vpos)+','+ sec2hms(vpos_end) + ',Danmaku,'+message['author']['name'].replace(',','')+',0,0,0,,{\\an7\\move('+str(sx)+','+str(sy)+','+str(ex)+','+str(ey)+')}'+text+'\n')
|
|
|
+f.close()
|