kuma %!s(int64=3) %!d(string=hai) anos
pai
achega
2601f388e8
Modificáronse 2 ficheiros con 96 adicións e 1 borrados
  1. 13 1
      README.md
  2. 83 0
      ytbchat2ass.py

+ 13 - 1
README.md

@@ -1 +1,13 @@
-# ytbchat2ass
+# README
+## 环境
+Python 3.x  
+## 用例
+For youtu.be/nP-9Nuvi9rw :
+```sh
+python ytbchat2ass.py nP-9Nuvi9rw
+```
+## 其它
+第一次使用前请pip install chat-downloader  
+基本上就是把评论拉出来套上nico弹幕的样式,体现的就是一个懒(x
+## 致谢
+[chat-downloader@xenova](https://github.com/xenova/chat-downloader)

+ 83 - 0
ytbchat2ass.py

@@ -0,0 +1,83 @@
+# -*- coding:utf-8 -*-
+from chat_downloader import ChatDownloader
+import sys
+import math
+
+# 目前仅支持开启了chat的回放,看不懂chat-downloader的源代码,甚至不想把直播安排进todo
+
+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']) #默认普通评论和sc
+name = 'DIALOGUE Official Channel' #挑出来摆在上面的人,默认d+官号,自己改
+
+limitLineAmount = 12  # 屏上弹幕行数限制
+danmakuPassageway = []  # 塞弹幕用,记录每行上一条弹幕的消失时间
+for i in range(limitLineAmount):
+    danmakuPassageway.append(0)
+fontName = 'Source Han Sans JP'  # 字体自己换
+videoWidth = 1280  # 视频宽度,按720P处理了后面的内容,不建议改
+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 # 普通弹幕的时长,默认8秒
+    else:
+        #vpos = 0
+        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 # 打钱的多给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()