@@ -46,27 +46,27 @@ def __init__(self):
4646 self ._text = ""
4747
4848 def write_comment_special (self , comment : Comment , width , height , styleid ):
49- # BiliPlayerSize = (512, 384) # Bilibili player version 2010
50- # BiliPlayerSize = (540, 384) # Bilibili player version 2012
51- # BiliPlayerSize = (672, 438) # Bilibili player version 2014
52- BiliPlayerSize = (891 , 589 ) # Bilibili player version 2021 (flex)
53- ZoomFactor = get_zoom_factor (BiliPlayerSize , (width , height ))
49+ # BILI_PLACYER_SIZE = (512, 384) # Bilibili player version 2010
50+ # BILI_PLACYER_SIZE = (540, 384) # Bilibili player version 2012
51+ # BILI_PLACYER_SIZE = (672, 438) # Bilibili player version 2014
52+ BILI_PLACYER_SIZE = (891 , 589 ) # Bilibili player version 2021 (flex)
53+ zoom_factor = get_zoom_factor (BILI_PLACYER_SIZE , (width , height ))
5454
55- def get_position (InputPos , isHeight ):
56- isHeight = int (isHeight ) # True -> 1
57- if isinstance (InputPos , int ):
58- return ZoomFactor [0 ] * InputPos + ZoomFactor [ isHeight + 1 ]
59- elif isinstance (InputPos , float ):
60- if InputPos > 1 :
61- return ZoomFactor [0 ] * InputPos + ZoomFactor [ isHeight + 1 ]
55+ def get_position (input_pos , is_height ):
56+ is_height = int (is_height ) # True -> 1
57+ if isinstance (input_pos , int ):
58+ return zoom_factor [0 ] * input_pos + zoom_factor [ is_height + 1 ]
59+ elif isinstance (input_pos , float ):
60+ if input_pos > 1 :
61+ return zoom_factor [0 ] * input_pos + zoom_factor [ is_height + 1 ]
6262 else :
63- return BiliPlayerSize [ isHeight ] * ZoomFactor [0 ] * InputPos + ZoomFactor [ isHeight + 1 ]
63+ return BILI_PLACYER_SIZE [ is_height ] * zoom_factor [0 ] * input_pos + zoom_factor [ is_height + 1 ]
6464 else :
6565 try :
66- InputPos = int (InputPos )
66+ input_pos = int (input_pos )
6767 except ValueError :
68- InputPos = float (InputPos )
69- return get_position (InputPos , isHeight )
68+ input_pos = float (input_pos )
69+ return get_position (input_pos , is_height )
7070
7171 try :
7272 special_comment_data = json .loads (comment .comment )
@@ -92,50 +92,30 @@ def get_position(InputPos, isHeight):
9292 lifetime = float (wrap_default (comment_args .get (3 , 4500 ), 4500 ))
9393 duration = int (comment_args .get (9 , lifetime * 1000 )) # pyright: ignore
9494 delay = int (comment_args .get (10 , 0 )) # pyright: ignore
95- fontface = comment_args .get (12 )
96- isborder = comment_args .get (11 , "true" )
97- from_rotarg = convert_flash_rotation (rotate_y , rotate_z , from_x , from_y , width , height )
98- to_rotarg = convert_flash_rotation (rotate_y , rotate_z , to_x , to_y , width , height )
99- styles = ["\\ org(%d, %d)" % (width / 2 , height / 2 )]
100- if from_rotarg [0 :2 ] == to_rotarg [0 :2 ]:
101- styles .append ("\\ pos({:.0f}, {:.0f})" .format (* from_rotarg [0 :2 ]))
102- else :
103- styles .append (
104- "\\ move({:.0f}, {:.0f}, {:.0f}, {:.0f}, {:.0f}, {:.0f})" .format (
105- * (from_rotarg [0 :2 ] + to_rotarg [0 :2 ] + (delay , delay + duration ))
106- )
107- )
108- styles .append ("\\ frx{:.0f}\\ fry{:.0f}\\ frz{:.0f}\\ fscx{:.0f}\\ fscy{:.0f}" .format (* from_rotarg [2 :7 ]))
109- if (from_x , from_y ) != (to_x , to_y ):
110- styles .append (f"\\ t({ delay :d} , { delay + duration :d} , " )
111- styles .append ("\\ frx{:.0f}\\ fry{:.0f}\\ frz{:.0f}\\ fscx{:.0f}\\ fscy{:.0f}" .format (* to_rotarg [2 :7 ]))
112- styles .append (")" )
113- if fontface :
114- styles .append (f"\\ fn{ ass_escape (fontface )} " )
115- styles .append ("\\ fs%.0f" % (comment .size * ZoomFactor [0 ]))
116- if comment .color != 0xFFFFFF :
117- styles .append (f"\\ c&H{ convert_color (comment .color )} &" )
118- if comment .color == 0x000000 :
119- styles .append ("\\ 3c&HFFFFFF&" )
120- if from_alpha == to_alpha :
121- styles .append (f"\\ alpha&H{ from_alpha :02X} " )
122- elif (from_alpha , to_alpha ) == (255 , 0 ):
123- styles .append (f"\\ fad({ lifetime * 1000 :.0f} ,0)" )
124- elif (from_alpha , to_alpha ) == (0 , 255 ):
125- styles .append (f"\\ fad(0, { lifetime * 1000 :.0f} )" )
126- else :
127- styles .append (
128- f"\\ fade({ from_alpha :d} , { to_alpha :d} , { to_alpha :d} , 0, { lifetime * 1000 :.0f} , { lifetime * 1000 :.0f} , { lifetime * 1000 :.0f} )"
129- )
130- if isborder == "false" :
131- styles .append ("\\ bord0" )
132- self ._text += "Dialogue: -1,{start},{end},{styleid},,0,0,0,,{{{styles}}}{text}\n " .format (
133- start = convert_timestamp (comment .timeline ),
134- end = convert_timestamp (comment .timeline + lifetime ),
135- styles = "" .join (styles ),
136- text = text ,
137- styleid = styleid ,
95+ fontface : str = comment_args .get (12 ) # pyright: ignore
96+ is_border = comment_args .get (11 , "true" ) != "false"
97+ self .write_comment_with_animation (
98+ comment ,
99+ width ,
100+ height ,
101+ rotate_y ,
102+ rotate_z ,
103+ from_x ,
104+ from_y ,
105+ to_x ,
106+ to_y ,
107+ from_alpha ,
108+ to_alpha ,
109+ text ,
110+ delay ,
111+ lifetime ,
112+ duration ,
113+ fontface ,
114+ is_border ,
115+ styleid ,
116+ zoom_factor ,
138117 )
118+
139119 except (IndexError , ValueError ):
140120 try :
141121 logging .warning (f"Invalid comment: { comment .comment !r} " )
@@ -171,6 +151,71 @@ def write_normal_comment(
171151 reduced ,
172152 )
173153
154+ def write_comment_with_animation (
155+ self ,
156+ comment : Comment ,
157+ width : int ,
158+ height : int ,
159+ rotate_y : float ,
160+ rotate_z : float ,
161+ from_x : float ,
162+ from_y : float ,
163+ to_x : float ,
164+ to_y : float ,
165+ from_alpha : int ,
166+ to_alpha : int ,
167+ text : str ,
168+ delay : float ,
169+ lifetime : float ,
170+ duration : float ,
171+ fontface : str ,
172+ is_border : bool ,
173+ styleid : str ,
174+ zoom_factor : tuple [float , float , float ],
175+ ) -> None :
176+ from_rotarg = convert_flash_rotation (rotate_y , rotate_z , from_x , from_y , width , height )
177+ to_rotarg = convert_flash_rotation (rotate_y , rotate_z , to_x , to_y , width , height )
178+ styles = ["\\ org(%d, %d)" % (width / 2 , height / 2 )]
179+ if from_rotarg [0 :2 ] == to_rotarg [0 :2 ]:
180+ styles .append ("\\ pos({:.0f}, {:.0f})" .format (* from_rotarg [0 :2 ]))
181+ else :
182+ styles .append (
183+ "\\ move({:.0f}, {:.0f}, {:.0f}, {:.0f}, {:.0f}, {:.0f})" .format (
184+ * (from_rotarg [0 :2 ] + to_rotarg [0 :2 ] + (delay , delay + duration ))
185+ )
186+ )
187+ styles .append ("\\ frx{:.0f}\\ fry{:.0f}\\ frz{:.0f}\\ fscx{:.0f}\\ fscy{:.0f}" .format (* from_rotarg [2 :7 ]))
188+ if (from_x , from_y ) != (to_x , to_y ):
189+ styles .append (f"\\ t({ delay :d} , { delay + duration :d} , " )
190+ styles .append ("\\ frx{:.0f}\\ fry{:.0f}\\ frz{:.0f}\\ fscx{:.0f}\\ fscy{:.0f}" .format (* to_rotarg [2 :7 ]))
191+ styles .append (")" )
192+ if fontface :
193+ styles .append (f"\\ fn{ ass_escape (fontface )} " )
194+ styles .append ("\\ fs%.0f" % (comment .size * zoom_factor [0 ]))
195+ if comment .color != 0xFFFFFF :
196+ styles .append (f"\\ c&H{ convert_color (comment .color )} &" )
197+ if comment .color == 0x000000 :
198+ styles .append ("\\ 3c&HFFFFFF&" )
199+ if from_alpha == to_alpha :
200+ styles .append (f"\\ alpha&H{ from_alpha :02X} " )
201+ elif (from_alpha , to_alpha ) == (255 , 0 ):
202+ styles .append (f"\\ fad({ lifetime * 1000 :.0f} ,0)" )
203+ elif (from_alpha , to_alpha ) == (0 , 255 ):
204+ styles .append (f"\\ fad(0, { lifetime * 1000 :.0f} )" )
205+ else :
206+ styles .append (
207+ f"\\ fade({ from_alpha :d} , { to_alpha :d} , { to_alpha :d} , 0, { lifetime * 1000 :.0f} , { lifetime * 1000 :.0f} , { lifetime * 1000 :.0f} )"
208+ )
209+ if not is_border :
210+ styles .append ("\\ bord0" )
211+ self ._text += "Dialogue: -1,{start},{end},{styleid},,0,0,0,,{{{styles}}}{text}\n " .format (
212+ start = convert_timestamp (comment .timeline ),
213+ end = convert_timestamp (comment .timeline + lifetime ),
214+ styles = "" .join (styles ),
215+ text = text ,
216+ styleid = styleid ,
217+ )
218+
174219 def to_string (self ):
175220 return self ._text
176221
0 commit comments