Skip to content

Commit b83ebe3

Browse files
committed
fix effect tags problem. support subtitle only MKS.
1 parent 8ce8ff8 commit b83ebe3

File tree

1 file changed

+75
-37
lines changed

1 file changed

+75
-37
lines changed

ASFMKV_dev.py

Lines changed: 75 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -410,17 +410,17 @@ def eventTagsSplit(assInfo: dict, changeOnly: bool = True) -> dict:
410410
lfi = eventfont['Italic']
411411
lfb = eventfont['Bold']
412412
# 首先查找蕴含有启用粗体/斜体标记的特效标签
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:
414414
lastfind = 0
415415
allfind = re.findall(r'\{.*?\}', eventftext)
416416
eventftext2 = eventftext
417417
# 在所有特效标签中寻找
418-
# 然后分别确认该特效标签的适用范围,以准确将字体子集化
418+
# 然后分别确认该特效标签的适用范围,以准确将字体子集化b
419419
for sti in range(0, len(allfind)):
420420
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)
422422
if ibopen is not None:
423-
stfind = eventftext2.find(st) + lastfind
423+
stfind = eventftext2.find(st)
424424
addbold = lfb
425425
additalic = lfi
426426
# 不管有没有 \r 标签,先获取了再说
@@ -809,16 +809,16 @@ def assFontList(assInfo: dict, eventSplit: dict) -> dict:
809809
for i in eventSplit.keys():
810810
for l in eventSplit[i]:
811811
fn = l['Fontname'].lstrip('@')
812-
l['Text'] = re.sub(r'\{.*?\\.*?\}', '', l['Text'])
812+
text = re.sub(r'\{.*?\\.*?\}', '', l['Text'])
813813
if len(assInfo['Subset']) > 0 and fn in assInfo['Subset']:
814814
fn = assInfo['Subset'][fn]
815815
flIndex = (fn, abs(int(l['Italic'])), abs(int(l['Bold'])))
816816
if flIndex in fontList:
817-
for char in set(l['Text']):
817+
for char in set(text):
818818
if char not in fontList[flIndex]:
819819
fontList[flIndex] += char
820820
else:
821-
fontList[flIndex] = ''.join(set(l['Text']))
821+
fontList[flIndex] = ''.join(set(text))
822822

823823
return fontList
824824

@@ -1138,6 +1138,7 @@ def outputSameLength(s: str) -> str:
11381138

11391139

11401140
# 当前字体缓存版本,小于该版本的字体缓存会被删除重建
1141+
# Pre24:2
11411142
currentFontCacheVer = 2
11421143

11431144
# font_info 列表结构
@@ -1910,34 +1911,28 @@ def assFontSubset(assfont: dict, fontdir: str, allTTF: bool = False):
19101911
else:
19111912
subsetarg = [s[0], '--glyphs={0}'.format(gfs), '--output-file={0}'.format(subfontpath), '--font-number={0}'.format(s[1]),
19121913
'--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]))
19151914

19161915
try:
19171916
subset.main(subsetarg)
1918-
# except PermissionError:
1919-
# print('\n\033[1;31m[ERROR] 文件\"{0}\"访问失败\033[0m'.format(path.basename(subfontpath)))
1920-
# continue
19211917
except:
1922-
# print('\033[1;31m[ERROR] 失败字符串: \"{0}\" \033[0m'.format(s[2]))
1918+
19231919
print('\n\033[1;31m[ERROR] {0}\033[0m'.format(sys.exc_info()))
19241920
if errorStop:
19251921
print('\033[1;31m[WARNING] 字体\"{0}\"子集化失败,强制终止批量处理\033[0m'.format(path.basename(s[0])))
19261922
return None
19271923
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+
19301925
ttLib.TTFont(s[0], lazy=False, fontNumber=int(s[1])).save(subfontpath, False)
19311926
subfontcrc = None
1927+
19321928
for si in s[5]:
19331929
for si3 in s[3].split("|"):
19341930
newfont_name[si3, si[0], si[1]] = [crcnewf, subfontcrc]
19351931
continue
1936-
# os.system('pyftsubset {0}'.format(' '.join(subsetarg)))
1932+
19371933
if path.exists(subfontpath):
19381934
subfontcrc = hex(zlib.crc32((gfs + s[4]).encode('utf-8', 'replace')))[2:].upper()
19391935
if len(subfontcrc) < 8: subfontcrc = '0' + subfontcrc
1940-
# print('CRC32: {0} \"{1}\"'.format(subfontcrc, path.basename(s[0])))
19411936

19421937
rawf = ttLib.TTFont(s[0], lazy=True, fontNumber=int(s[1]))
19431938
newf = ttLib.TTFont(subfontpath, lazy=False)
@@ -2093,11 +2088,10 @@ def assFontChange(newfont_name: dict, asspath: str, assInfo: dict, splitEvents:
20932088

20942089
if len(splitEvents) > 0:
20952090

2096-
# print('正在处理fn标签......')
2091+
# 处理fn标签
20972092
# fn_lines: 带有fn标签的行数与该行的完整特效标签,一项一个 [ [行数, { 标签1 : ( ASS内部字体名称, Italic, Bold )}], ... ]
20982093

20992094
for fnLine in splitEvents.keys():
2100-
if len(splitEvents[fnLine]) == 1: continue
21012095
for l in splitEvents[fnLine]:
21022096
fname = l['Fontname'].lstrip('@')
21032097
#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 =
22002194
return 4
22012195
elif file == '':
22022196
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:
22042198
return 4
22052199
if outfile is None: outfile = ''
22062200

@@ -2310,21 +2304,21 @@ def ffASFMKV(file: str, outfile: str = '', asslangs: list = [], asspaths: list =
23102304
try:
23112305
shutil.move('ffreport_cache.log', '{0}.{1}.log'.format(path.splitext(file)[0], datetime.now().strftime('%Y-%m%d-%H%M-%S_%f')))
23122306
except:
2313-
print('\033[1;33m[ERROR] \"ffreport_cache.log\"移动失败\033[0m')
2307+
print('\033[1;33m[WARNING] \"ffreport_cache.log\"移动失败\033[0m')
23142308
elif not notfont:
23152309
for p in asspaths:
23162310
print('\033[1;32m封装成功: \033[1;37m\"{0}\"\033[0m'.format(p))
23172311
if path.splitext(p)[1][1:].lower() in ['ass', 'ssa']:
23182312
try:
23192313
os.remove(p)
23202314
except:
2321-
print('\033[1;33m[ERROR] 文件\"{0}\"删除失败\033[0m'.format(p))
2315+
print('\033[1;33m[WARNING] 文件\"{0}\"删除失败\033[0m'.format(p))
23222316
for f in fontpaths:
23232317
print('\033[1;32m封装成功: \033[1;37m\"{0}\"\033[0m'.format(f))
23242318
try:
23252319
os.remove(f[0])
23262320
except:
2327-
print('\033[1;33m[ERROR] 文件\"{0}\"删除失败\033[0m'.format(f))
2321+
print('\033[1;33m[WARNING] 文件\"{0}\"删除失败\033[0m'.format(f))
23282322
print('\033[1;32m输出成功:\033[0m \033[1m\"{0}\"\033[0m'.format(outfile))
23292323
else:
23302324
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 = [
23532347
return 4
23542348
elif file == '':
23552349
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:
23572351
return 4
23582352
if outfile is None: outfile = ''
23592353

@@ -2846,7 +2840,7 @@ def namePosition(files: list):
28462840

28472841

28482842
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):
28502844
"""
28512845
主函数,负责调用各函数走完完整的处理流程
28522846
@@ -3653,6 +3647,10 @@ def cFontSubset(font_info):
36533647
''')
36543648
work = os.system(f'choice /M 请输入 /C AC1234567890UVWXYZLB{showFFKey}')
36553649

3650+
# 01:mkvmerge 封装
3651+
# 20:ASS/SSA 内嵌
3652+
# 21:FFmpeg 封装
3653+
36563654
if work == 2 and (no_mkvm and not insteadFF):
36573655

36583656
print('[ERROR] 在您的系统中找不到 mkvmerge 或 ffmpeg, 该功能不可用')
@@ -3759,6 +3757,7 @@ def cFontSubset(font_info):
37593757
directout = False
37603758
subonly = False
37613759
subonlyp = []
3760+
subonlyv = ''
37623761
while not path.exists(cpath) and not directout:
37633762
directout = True
37643763
cpath = input('不输入任何值 直接回车回到上一页面\n请输入文件或目录路径: ').strip('\" ')
@@ -3783,29 +3782,66 @@ def cFontSubset(font_info):
37833782
directout = False
37843783
# print(directout)
37853784
medias = []
3785+
makeMKSq = False
37863786
if not directout:
3787+
37873788
if path.isfile(cpath):
37883789
if not subonly:
37893790
medias = [[path.splitext(path.basename(cpath))[0], cpath]]
37903791
else:
37913792
subonlyp = [(path.splitext(path.basename(cpath))[0], cpath)]
37923793
cpath = path.dirname(cpath)
37933794
else:
3795+
37943796
if work != 20: medias = getFileList(cpath, extlist, v_subdir)
37953797
else: medias = []
3798+
37963799
if len(medias) == 0:
37973800
subonlyp = getFileList(cpath, ['ass', 'ssa'], s_subdir)
37983801
if work == 20:
37993802
subonly = True
38003803
elif len(subonlyp) > 0:
38013804
cls()
38023805
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
38093845
else:
38103846
print('\033[1;31m[ERROR] 路径下找不到字幕\033[0m')
38113847
directout = True
@@ -3835,12 +3871,13 @@ def cFontSubset(font_info):
38353871
if work in [2, 21]: domux = True
38363872

38373873
if len(medias) > 0:
3874+
38383875
media_ass = getSubtitles(cpath, medias)
3839-
if len(media_ass.values()) > 0:
3876+
3877+
if len(media_ass) > 0:
38403878
sublangs = None
38413879
sublangs = {}
38423880
forceSubTrack = '?'
3843-
makeMKSq = False
38443881
muxer = 0
38453882
cls()
38463883
if domux:
@@ -3851,10 +3888,11 @@ def cFontSubset(font_info):
38513888
cls()
38523889
forceSubTrack = getForceSub(media_ass)
38533890

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
38583896
# print(media_ass)
38593897
if work == 21 or (work == 2 and no_mkvm):
38603898
muxer = 1

0 commit comments

Comments
 (0)