@@ -410,17 +410,17 @@ def eventTagsSplit(assInfo: dict, changeOnly: bool = True) -> dict:
410
410
lfi = eventfont ['Italic' ]
411
411
lfb = eventfont ['Bold' ]
412
412
# 首先查找蕴含有启用粗体/斜体标记的特效标签
413
- if re .search (r'\{.*?(?:\\b|\\i |\\fn|\\r).*?\}' , eventftext ) is not None :
413
+ if re .search (r'\{.*?(?:\\b[1-9]00 |\\b[0-1]|\\i[0-1] |\\fn|\\r).*?\}' , eventftext ) is not None :
414
414
lastfind = 0
415
415
allfind = re .findall (r'\{.*?\}' , eventftext )
416
416
eventftext2 = eventftext
417
417
# 在所有特效标签中寻找
418
- # 然后分别确认该特效标签的适用范围,以准确将字体子集化
418
+ # 然后分别确认该特效标签的适用范围,以准确将字体子集化b
419
419
for sti in range (0 , len (allfind )):
420
420
st = allfind [sti ]
421
- ibopen = re .search (r'\\b|\\i |\\fn|\\r' , st )
421
+ ibopen = re .search (r'\\b[1-9]00 |\\b[0-1]|\\i[0-1] |\\fn|\\r' , st )
422
422
if ibopen is not None :
423
- stfind = eventftext2 .find (st ) + lastfind
423
+ stfind = eventftext2 .find (st )
424
424
addbold = lfb
425
425
additalic = lfi
426
426
# 不管有没有 \r 标签,先获取了再说
@@ -809,16 +809,16 @@ def assFontList(assInfo: dict, eventSplit: dict) -> dict:
809
809
for i in eventSplit .keys ():
810
810
for l in eventSplit [i ]:
811
811
fn = l ['Fontname' ].lstrip ('@' )
812
- l [ 'Text' ] = re .sub (r'\{.*?\\.*?\}' , '' , l ['Text' ])
812
+ text = re .sub (r'\{.*?\\.*?\}' , '' , l ['Text' ])
813
813
if len (assInfo ['Subset' ]) > 0 and fn in assInfo ['Subset' ]:
814
814
fn = assInfo ['Subset' ][fn ]
815
815
flIndex = (fn , abs (int (l ['Italic' ])), abs (int (l ['Bold' ])))
816
816
if flIndex in fontList :
817
- for char in set (l [ 'Text' ] ):
817
+ for char in set (text ):
818
818
if char not in fontList [flIndex ]:
819
819
fontList [flIndex ] += char
820
820
else :
821
- fontList [flIndex ] = '' .join (set (l [ 'Text' ] ))
821
+ fontList [flIndex ] = '' .join (set (text ))
822
822
823
823
return fontList
824
824
@@ -1138,6 +1138,7 @@ def outputSameLength(s: str) -> str:
1138
1138
1139
1139
1140
1140
# 当前字体缓存版本,小于该版本的字体缓存会被删除重建
1141
+ # Pre24:2
1141
1142
currentFontCacheVer = 2
1142
1143
1143
1144
# font_info 列表结构
@@ -1910,34 +1911,28 @@ def assFontSubset(assfont: dict, fontdir: str, allTTF: bool = False):
1910
1911
else :
1911
1912
subsetarg = [s [0 ], '--glyphs={0}' .format (gfs ), '--output-file={0}' .format (subfontpath ), '--font-number={0}' .format (s [1 ]),
1912
1913
'--passthrough-tables' , '--name-legacy' , '--legacy-cmap' , '--glyph-names' , '--recommended-glyphs' , '--ignore-missing-glyphs' ]
1913
- # else:
1914
- # print('\n\033[0;32m[CHECK] \"{0}\"已通过字符完整性检查\033[0m'.format(s[3]))
1915
1914
1916
1915
try :
1917
1916
subset .main (subsetarg )
1918
- # except PermissionError:
1919
- # print('\n\033[1;31m[ERROR] 文件\"{0}\"访问失败\033[0m'.format(path.basename(subfontpath)))
1920
- # continue
1921
1917
except :
1922
- # print('\033[1;31m[ERROR] 失败字符串: \"{0}\" \033[0m'.format(s[2]))
1918
+
1923
1919
print ('\n \033 [1;31m[ERROR] {0}\033 [0m' .format (sys .exc_info ()))
1924
1920
if errorStop :
1925
1921
print ('\033 [1;31m[WARNING] 字体\" {0}\" 子集化失败,强制终止批量处理\033 [0m' .format (path .basename (s [0 ])))
1926
1922
return None
1927
1923
print ('\033 [1;31m[WARNING] 字体\" {0}\" 子集化失败,将会保留完整字体\033 [0m' .format (path .basename (s [0 ])))
1928
- # crcnewf = ''.join([path.splitext(subfontpath)[0], fontext])
1929
- # shutil.copy(s[0], crcnewf)
1924
+
1930
1925
ttLib .TTFont (s [0 ], lazy = False , fontNumber = int (s [1 ])).save (subfontpath , False )
1931
1926
subfontcrc = None
1927
+
1932
1928
for si in s [5 ]:
1933
1929
for si3 in s [3 ].split ("|" ):
1934
1930
newfont_name [si3 , si [0 ], si [1 ]] = [crcnewf , subfontcrc ]
1935
1931
continue
1936
- # os.system('pyftsubset {0}'.format(' '.join(subsetarg)))
1932
+
1937
1933
if path .exists (subfontpath ):
1938
1934
subfontcrc = hex (zlib .crc32 ((gfs + s [4 ]).encode ('utf-8' , 'replace' )))[2 :].upper ()
1939
1935
if len (subfontcrc ) < 8 : subfontcrc = '0' + subfontcrc
1940
- # print('CRC32: {0} \"{1}\"'.format(subfontcrc, path.basename(s[0])))
1941
1936
1942
1937
rawf = ttLib .TTFont (s [0 ], lazy = True , fontNumber = int (s [1 ]))
1943
1938
newf = ttLib .TTFont (subfontpath , lazy = False )
@@ -2093,11 +2088,10 @@ def assFontChange(newfont_name: dict, asspath: str, assInfo: dict, splitEvents:
2093
2088
2094
2089
if len (splitEvents ) > 0 :
2095
2090
2096
- # print('正在处理fn标签......')
2091
+ # 处理fn标签
2097
2092
# fn_lines: 带有fn标签的行数与该行的完整特效标签,一项一个 [ [行数, { 标签1 : ( ASS内部字体名称, Italic, Bold )}], ... ]
2098
2093
2099
2094
for fnLine in splitEvents .keys ():
2100
- if len (splitEvents [fnLine ]) == 1 : continue
2101
2095
for l in splitEvents [fnLine ]:
2102
2096
fname = l ['Fontname' ].lstrip ('@' )
2103
2097
#if len(fname) > 0 and not used_nf_name[fname.upper()][1] is None:
@@ -2200,7 +2194,7 @@ def ffASFMKV(file: str, outfile: str = '', asslangs: list = [], asspaths: list =
2200
2194
return 4
2201
2195
elif file == '' :
2202
2196
return 4
2203
- elif not path .exists (file ) or not path .isfile (file ):
2197
+ elif ( not path .exists (file ) or not path .isfile (file )) and not makeMKS :
2204
2198
return 4
2205
2199
if outfile is None : outfile = ''
2206
2200
@@ -2310,21 +2304,21 @@ def ffASFMKV(file: str, outfile: str = '', asslangs: list = [], asspaths: list =
2310
2304
try :
2311
2305
shutil .move ('ffreport_cache.log' , '{0}.{1}.log' .format (path .splitext (file )[0 ], datetime .now ().strftime ('%Y-%m%d-%H%M-%S_%f' )))
2312
2306
except :
2313
- print ('\033 [1;33m[ERROR ] \" ffreport_cache.log\" 移动失败\033 [0m' )
2307
+ print ('\033 [1;33m[WARNING ] \" ffreport_cache.log\" 移动失败\033 [0m' )
2314
2308
elif not notfont :
2315
2309
for p in asspaths :
2316
2310
print ('\033 [1;32m封装成功: \033 [1;37m\" {0}\" \033 [0m' .format (p ))
2317
2311
if path .splitext (p )[1 ][1 :].lower () in ['ass' , 'ssa' ]:
2318
2312
try :
2319
2313
os .remove (p )
2320
2314
except :
2321
- print ('\033 [1;33m[ERROR ] 文件\" {0}\" 删除失败\033 [0m' .format (p ))
2315
+ print ('\033 [1;33m[WARNING ] 文件\" {0}\" 删除失败\033 [0m' .format (p ))
2322
2316
for f in fontpaths :
2323
2317
print ('\033 [1;32m封装成功: \033 [1;37m\" {0}\" \033 [0m' .format (f ))
2324
2318
try :
2325
2319
os .remove (f [0 ])
2326
2320
except :
2327
- print ('\033 [1;33m[ERROR ] 文件\" {0}\" 删除失败\033 [0m' .format (f ))
2321
+ print ('\033 [1;33m[WARNING ] 文件\" {0}\" 删除失败\033 [0m' .format (f ))
2328
2322
print ('\033 [1;32m输出成功:\033 [0m \033 [1m\" {0}\" \033 [0m' .format (outfile ))
2329
2323
else :
2330
2324
print ('\033 [1;32m输出成功:\033 [0m \033 [1m\" {0}\" \033 [0m' .format (outfile ))
@@ -2353,7 +2347,7 @@ def ASFMKV(file: str, outfile: str = '', asslangs: dict = {}, asspaths: list = [
2353
2347
return 4
2354
2348
elif file == '' :
2355
2349
return 4
2356
- elif not path .exists (file ) or not path .isfile (file ):
2350
+ elif ( not path .exists (file ) or not path .isfile (file )) and not makeMKS :
2357
2351
return 4
2358
2352
if outfile is None : outfile = ''
2359
2353
@@ -2846,7 +2840,7 @@ def namePosition(files: list):
2846
2840
2847
2841
2848
2842
def main (font_info : list , asspath : list , outdir : list = ['' , '' , '' ], mux : bool = False , vpath : str = '' ,
2849
- asslangs : dict = {}, FFmuxer : int = 0 , fontline : int = - 1 , forceSubTrack : str = '?' , makeMKS : bool = False ):
2843
+ asslangs : dict = {}, FFmuxer : int = 0 , forceSubTrack : str = '?' , makeMKS : bool = False ):
2850
2844
"""
2851
2845
主函数,负责调用各函数走完完整的处理流程
2852
2846
@@ -3653,6 +3647,10 @@ def cFontSubset(font_info):
3653
3647
''' )
3654
3648
work = os .system (f'choice /M 请输入 /C AC1234567890UVWXYZLB{ showFFKey } ' )
3655
3649
3650
+ # 01:mkvmerge 封装
3651
+ # 20:ASS/SSA 内嵌
3652
+ # 21:FFmpeg 封装
3653
+
3656
3654
if work == 2 and (no_mkvm and not insteadFF ):
3657
3655
3658
3656
print ('[ERROR] 在您的系统中找不到 mkvmerge 或 ffmpeg, 该功能不可用' )
@@ -3759,6 +3757,7 @@ def cFontSubset(font_info):
3759
3757
directout = False
3760
3758
subonly = False
3761
3759
subonlyp = []
3760
+ subonlyv = ''
3762
3761
while not path .exists (cpath ) and not directout :
3763
3762
directout = True
3764
3763
cpath = input ('不输入任何值 直接回车回到上一页面\n 请输入文件或目录路径: ' ).strip ('\" ' )
@@ -3783,29 +3782,66 @@ def cFontSubset(font_info):
3783
3782
directout = False
3784
3783
# print(directout)
3785
3784
medias = []
3785
+ makeMKSq = False
3786
3786
if not directout :
3787
+
3787
3788
if path .isfile (cpath ):
3788
3789
if not subonly :
3789
3790
medias = [[path .splitext (path .basename (cpath ))[0 ], cpath ]]
3790
3791
else :
3791
3792
subonlyp = [(path .splitext (path .basename (cpath ))[0 ], cpath )]
3792
3793
cpath = path .dirname (cpath )
3793
3794
else :
3795
+
3794
3796
if work != 20 : medias = getFileList (cpath , extlist , v_subdir )
3795
3797
else : medias = []
3798
+
3796
3799
if len (medias ) == 0 :
3797
3800
subonlyp = getFileList (cpath , ['ass' , 'ssa' ], s_subdir )
3798
3801
if work == 20 :
3799
3802
subonly = True
3800
3803
elif len (subonlyp ) > 0 :
3801
3804
cls ()
3802
3805
print ('\033 [1;33m[WARNING]\033 [0m' )
3803
- print ('您输入的目录下只有字幕而无视频,每个字幕都将被当做单独对象处理\n 若是同一话有多个字幕,这话将会有多套子集化字体。' )
3804
- if os .system ('choice /M \" 即便如此,您仍要继续吗?\" ' ) == 1 :
3805
- subonly = True
3806
- else :
3807
- print ('\n 已终止运行' )
3808
- directout = True
3806
+ print (
3807
+ '''您输入的目录下只有字幕而无视频,需要输入文件名规则才可进行下一步。
3808
+ 请将字幕对应的视频文件名中不统一的部分替换为通配符\" \033 [1;33m*\033 [0m\" ,以便匹配视频文件名
3809
+ 例如字幕:\" [dmhy][ARIA_The_ANIMATION][\033 [1;33m01\033 [0m][DVDRIP][AVC_AC3][\033 [1;33mF49E85D5\033 [0m].sc.ass\"
3810
+ 需要输入:\" [dmhy][ARIA_The_ANIMATION][\033 [1;33m*\033 [0m][DVDRIP][AVC_AC3][\033 [1;33m*\033 [0m]\" ''' )
3811
+
3812
+ trying = 0
3813
+ while (len (subonlyv ) == 0 ):
3814
+ subonlyv = input ('视频文件名规则: ' ).strip (' ' )
3815
+ if len (subonlyv ) == 0 :
3816
+ trying += 1
3817
+ else :
3818
+ if os .system ('choice /M \" 确定吗?\" ' ) != 1 :
3819
+ subonly = True
3820
+ directout = True
3821
+ else :
3822
+ subonlyv = re .escape (subonlyv ).replace ('\*' , '.*?' )
3823
+ subonlyv_re = re .compile (subonlyv )
3824
+
3825
+ svNameFound = {}
3826
+ for fn , fp in subonlyp :
3827
+ svName = re .search (subonlyv_re , fn ).group ()
3828
+ if svName :
3829
+ mediaTuple = (svName , path .join (path .dirname (fp ), svName + '.mp4' ))
3830
+ if not mediaTuple in svNameFound :
3831
+ svNameFound [mediaTuple ] = True
3832
+ medias .append (mediaTuple )
3833
+ svNameFound .clear ()
3834
+
3835
+ if len (medias ) > 0 :
3836
+ subonlyp .clear ()
3837
+ subonly = False
3838
+ makeMKSq = True
3839
+ else :
3840
+ print ('\033 [1;31m[ERROR] 文件名规则有误:匹配失败\033 [0m' )
3841
+ directout = True
3842
+
3843
+ if trying >= 3 :
3844
+ directout = True
3809
3845
else :
3810
3846
print ('\033 [1;31m[ERROR] 路径下找不到字幕\033 [0m' )
3811
3847
directout = True
@@ -3835,12 +3871,13 @@ def cFontSubset(font_info):
3835
3871
if work in [2 , 21 ]: domux = True
3836
3872
3837
3873
if len (medias ) > 0 :
3874
+
3838
3875
media_ass = getSubtitles (cpath , medias )
3839
- if len (media_ass .values ()) > 0 :
3876
+
3877
+ if len (media_ass ) > 0 :
3840
3878
sublangs = None
3841
3879
sublangs = {}
3842
3880
forceSubTrack = '?'
3843
- makeMKSq = False
3844
3881
muxer = 0
3845
3882
cls ()
3846
3883
if domux :
@@ -3851,10 +3888,11 @@ def cFontSubset(font_info):
3851
3888
cls ()
3852
3889
forceSubTrack = getForceSub (media_ass )
3853
3890
3854
- cls ()
3855
- print ('您要封装为外置MKS文件吗?' )
3856
- if os .system ('choice' ) == 1 :
3857
- makeMKSq = True
3891
+ if not makeMKSq :
3892
+ cls ()
3893
+ print ('您要封装为外置MKS文件吗?' )
3894
+ if os .system ('choice' ) == 1 :
3895
+ makeMKSq = True
3858
3896
# print(media_ass)
3859
3897
if work == 21 or (work == 2 and no_mkvm ):
3860
3898
muxer = 1
0 commit comments