Compare commits

..

No commits in common. "7453e571fc4ad5835634e6031f93085b6fdb150e" and "3dd20e41ea808b7f1954e92149dc65cac86c5d39" have entirely different histories.

3 changed files with 16 additions and 55 deletions

View file

@ -19,7 +19,7 @@ all:
install: install:
$(MKDIR) "$(DESTDIR)$(PREFIX)/share/danmaku2ass" $(MKDIR) "$(DESTDIR)$(PREFIX)/share/danmaku2ass"
$(INSTALL) -m0755 danmaku2ass.py "$(DESTDIR)$(PREFIX)/share/danmaku2ass/danmaku2ass.py" $(INSTALL) -Dm0755 danmaku2ass.py "$(DESTDIR)$(PREFIX)/share/danmaku2ass/danmaku2ass.py"
for locale in en ja zh_CN zh_TW; do \ for locale in en ja zh_CN zh_TW; do \
$(MKDIR) "$(DESTDIR)$(PREFIX)/share/locale/$$locale/LC_MESSAGES" ; \ $(MKDIR) "$(DESTDIR)$(PREFIX)/share/locale/$$locale/LC_MESSAGES" ; \
$(CP) "po/$$locale.mo" "$(DESTDIR)$(PREFIX)/share/locale/$$locale/LC_MESSAGES/danmaku2ass.mo" ; \ $(CP) "po/$$locale.mo" "$(DESTDIR)$(PREFIX)/share/locale/$$locale/LC_MESSAGES/danmaku2ass.mo" ; \

View file

@ -97,8 +97,6 @@ optional arguments:
Duration of still comment display [default: 5] Duration of still comment display [default: 5]
-fl FILTER, --filter FILTER -fl FILTER, --filter FILTER
Regular expression to filter comments Regular expression to filter comments
-flf FILTER_FILE, --filter-file FILTER_FILE
Regular expressions from file (one line one regex) to filter comments
-p HEIGHT, --protect HEIGHT -p HEIGHT, --protect HEIGHT
Reserve blank on the bottom of the stage Reserve blank on the bottom of the stage
-r, --reduce Reduce the amount of comments if stage is full -r, --reduce Reduce the amount of comments if stage is full

View file

@ -74,8 +74,6 @@ def ProbeCommentFormat(f):
return 'Niconico' return 'Niconico'
elif tmp == 'xml version="1.0" encoding="UTF-8"?><i': elif tmp == 'xml version="1.0" encoding="UTF-8"?><i':
return 'Bilibili' return 'Bilibili'
elif tmp == 'xml version="2.0" encoding="UTF-8"?><i':
return 'Bilibili2'
elif tmp == 'xml version="1.0" encoding="utf-8"?><i': elif tmp == 'xml version="1.0" encoding="utf-8"?><i':
return 'Bilibili' # tucao.cc, with the same file format as Bilibili return 'Bilibili' # tucao.cc, with the same file format as Bilibili
elif tmp == 'xml version="1.0" encoding="Utf-8"?>\n<': elif tmp == 'xml version="1.0" encoding="Utf-8"?>\n<':
@ -144,7 +142,7 @@ def ReadCommentsNiconico(f, fontsize):
size = fontsize * 0.64 size = fontsize * 0.64
elif mailstyle in NiconicoColorMap: elif mailstyle in NiconicoColorMap:
color = NiconicoColorMap[mailstyle] color = NiconicoColorMap[mailstyle]
yield (max(int(comment.getAttribute('vpos')), 0) * 0.01, int(comment.getAttribute('date')), 0, c, pos, color, size, (c.count('\n') + 1) * size, CalculateLength(c) * size) yield (max(int(comment.getAttribute('vpos')), 0) * 0.01, int(comment.getAttribute('date')), int(comment.getAttribute('no')), c, pos, color, size, (c.count('\n') + 1) * size, CalculateLength(c) * size)
except (AssertionError, AttributeError, IndexError, TypeError, ValueError): except (AssertionError, AttributeError, IndexError, TypeError, ValueError):
logging.warning(_('Invalid comment: %s') % comment.toxml()) logging.warning(_('Invalid comment: %s') % comment.toxml())
continue continue
@ -196,30 +194,6 @@ def ReadCommentsBilibili(f, fontsize):
continue continue
def ReadCommentsBilibili2(f, fontsize):
dom = xml.dom.minidom.parse(f)
comment_element = dom.getElementsByTagName('d')
for i, comment in enumerate(comment_element):
try:
p = str(comment.getAttribute('p')).split(',')
assert len(p) >= 7
assert p[3] in ('1', '4', '5', '6', '7', '8')
if comment.childNodes.length > 0:
time = float(p[2]) / 1000.0
if p[3] in ('1', '4', '5', '6'):
c = str(comment.childNodes[0].wholeText).replace('/n', '\n')
size = int(p[4]) * fontsize / 25.0
yield (time, int(p[6]), i, c, {'1': 0, '4': 2, '5': 1, '6': 3}[p[3]], int(p[5]), size, (c.count('\n') + 1) * size, CalculateLength(c) * size)
elif p[3] == '7': # positioned comment
c = str(comment.childNodes[0].wholeText)
yield (time, int(p[6]), i, c, 'bilipos', int(p[5]), int(p[4]), 0, 0)
elif p[3] == '8':
pass # ignore scripted comment
except (AssertionError, AttributeError, IndexError, TypeError, ValueError):
logging.warning(_('Invalid comment: %s') % comment.toxml())
continue
def ReadCommentsTudou(f, fontsize): def ReadCommentsTudou(f, fontsize):
comment_element = json.load(f) comment_element = json.load(f)
for i, comment in enumerate(comment_element['comment_list']): for i, comment in enumerate(comment_element['comment_list']):
@ -270,7 +244,7 @@ def ReadCommentsMioMio(f, fontsize):
continue continue
CommentFormatMap = {'Niconico': ReadCommentsNiconico, 'Acfun': ReadCommentsAcfun, 'Bilibili': ReadCommentsBilibili, 'Bilibili2': ReadCommentsBilibili2, 'Tudou': ReadCommentsTudou, 'Tudou2': ReadCommentsTudou2, 'MioMio': ReadCommentsMioMio} CommentFormatMap = {'Niconico': ReadCommentsNiconico, 'Acfun': ReadCommentsAcfun, 'Bilibili': ReadCommentsBilibili, 'Tudou': ReadCommentsTudou, 'Tudou2': ReadCommentsTudou2, 'MioMio': ReadCommentsMioMio}
def WriteCommentBilibiliPositioned(f, c, width, height, styleid): def WriteCommentBilibiliPositioned(f, c, width, height, styleid):
@ -397,7 +371,7 @@ def WriteCommentAcfunPositioned(f, c, width, height, styleid):
try: try:
comment_args = c[3] comment_args = c[3]
text = ASSEscape(str(comment_args['n']).replace('\r', '\n')) text = ASSEscape(str(comment_args['n']).replace('\r', '\n'))
common_styles = ['\\org(%d, %d)' % (width / 2, height / 2)] common_styles = ['\org(%d, %d)' % (width / 2, height / 2)]
anchor = {0: 7, 1: 8, 2: 9, 3: 4, 4: 5, 5: 6, 6: 1, 7: 2, 8: 3}.get(comment_args.get('c', 0), 7) anchor = {0: 7, 1: 8, 2: 9, 3: 4, 4: 5, 5: 6, 6: 1, 7: 2, 8: 3}.get(comment_args.get('c', 0), 7)
if anchor != 7: if anchor != 7:
common_styles.append('\\an%s' % anchor) common_styles.append('\\an%s' % anchor)
@ -538,7 +512,7 @@ def ConvertFlashRotation(rotY, rotZ, X, Y, width, height):
return (trX, trY, WrapAngle(outX), WrapAngle(outY), WrapAngle(outZ), scaleXY * 100, scaleXY * 100) return (trX, trY, WrapAngle(outX), WrapAngle(outY), WrapAngle(outZ), scaleXY * 100, scaleXY * 100)
def ProcessComments(comments, f, width, height, bottomReserved, fontface, fontsize, alpha, duration_marquee, duration_still, filters_regex, reduced, progress_callback): def ProcessComments(comments, f, width, height, bottomReserved, fontface, fontsize, alpha, duration_marquee, duration_still, filter_regex, reduced, progress_callback):
styleid = 'Danmaku2ASS_%04x' % random.randint(0, 0xffff) styleid = 'Danmaku2ASS_%04x' % random.randint(0, 0xffff)
WriteASSHead(f, width, height, fontface, fontsize, alpha, styleid) WriteASSHead(f, width, height, fontface, fontsize, alpha, styleid)
rows = [[None] * (height - bottomReserved + 1) for i in range(4)] rows = [[None] * (height - bottomReserved + 1) for i in range(4)]
@ -546,12 +520,7 @@ def ProcessComments(comments, f, width, height, bottomReserved, fontface, fontsi
if progress_callback and idx % 1000 == 0: if progress_callback and idx % 1000 == 0:
progress_callback(idx, len(comments)) progress_callback(idx, len(comments))
if isinstance(i[4], int): if isinstance(i[4], int):
skip = False if filter_regex and filter_regex.search(i[3]):
for filter_regex in filters_regex:
if filter_regex and filter_regex.search(i[3]):
skip = True
break
if skip:
continue continue
row = 0 row = 0
rowmax = height - bottomReserved - i[7] rowmax = height - bottomReserved - i[7]
@ -757,19 +726,14 @@ def export(func):
@export @export
def Danmaku2ASS(input_files, input_format, output_file, stage_width, stage_height, reserve_blank=0, font_face=_('(FONT) sans-serif')[7:], font_size=25.0, text_opacity=1.0, duration_marquee=5.0, duration_still=5.0, comment_filter=None, comment_filters_file=None, is_reduce_comments=False, progress_callback=None): def Danmaku2ASS(input_files, input_format, output_file, stage_width, stage_height, reserve_blank=0, font_face=_('(FONT) sans-serif')[7:], font_size=25.0, text_opacity=1.0, duration_marquee=5.0, duration_still=5.0, comment_filter=None, is_reduce_comments=False, progress_callback=None):
comment_filters = [comment_filter] try:
if comment_filters_file: if comment_filter:
with open(comment_filters_file, 'r') as f: filter_regex = re.compile(comment_filter)
d = f.readlines() else:
comment_filters.extend([i.strip() for i in d]) filter_regex = None
filters_regex = [] except:
for comment_filter in comment_filters: raise ValueError(_('Invalid regular expression: %s') % comment_filter)
try:
if comment_filter:
filters_regex.append(re.compile(comment_filter))
except:
raise ValueError(_('Invalid regular expression: %s') % comment_filter)
fo = None fo = None
comments = ReadComments(input_files, input_format, font_size) comments = ReadComments(input_files, input_format, font_size)
try: try:
@ -777,7 +741,7 @@ def Danmaku2ASS(input_files, input_format, output_file, stage_width, stage_heigh
fo = ConvertToFile(output_file, 'w', encoding='utf-8-sig', errors='replace', newline='\r\n') fo = ConvertToFile(output_file, 'w', encoding='utf-8-sig', errors='replace', newline='\r\n')
else: else:
fo = sys.stdout fo = sys.stdout
ProcessComments(comments, fo, stage_width, stage_height, reserve_blank, font_face, font_size, text_opacity, duration_marquee, duration_still, filters_regex, is_reduce_comments, progress_callback) ProcessComments(comments, fo, stage_width, stage_height, reserve_blank, font_face, font_size, text_opacity, duration_marquee, duration_still, filter_regex, is_reduce_comments, progress_callback)
finally: finally:
if output_file and fo != output_file: if output_file and fo != output_file:
fo.close() fo.close()
@ -836,7 +800,6 @@ def main():
parser.add_argument('-dm', '--duration-marquee', metavar=_('SECONDS'), help=_('Duration of scrolling comment display [default: %s]') % 5, type=float, default=5.0) parser.add_argument('-dm', '--duration-marquee', metavar=_('SECONDS'), help=_('Duration of scrolling comment display [default: %s]') % 5, type=float, default=5.0)
parser.add_argument('-ds', '--duration-still', metavar=_('SECONDS'), help=_('Duration of still comment display [default: %s]') % 5, type=float, default=5.0) parser.add_argument('-ds', '--duration-still', metavar=_('SECONDS'), help=_('Duration of still comment display [default: %s]') % 5, type=float, default=5.0)
parser.add_argument('-fl', '--filter', help=_('Regular expression to filter comments')) parser.add_argument('-fl', '--filter', help=_('Regular expression to filter comments'))
parser.add_argument('-flf', '--filter-file', help=_('Regular expressions from file (one line one regex) to filter comments'))
parser.add_argument('-p', '--protect', metavar=_('HEIGHT'), help=_('Reserve blank on the bottom of the stage'), type=int, default=0) parser.add_argument('-p', '--protect', metavar=_('HEIGHT'), help=_('Reserve blank on the bottom of the stage'), type=int, default=0)
parser.add_argument('-r', '--reduce', action='store_true', help=_('Reduce the amount of comments if stage is full')) parser.add_argument('-r', '--reduce', action='store_true', help=_('Reduce the amount of comments if stage is full'))
parser.add_argument('file', metavar=_('FILE'), nargs='+', help=_('Comment file to be processed')) parser.add_argument('file', metavar=_('FILE'), nargs='+', help=_('Comment file to be processed'))
@ -847,7 +810,7 @@ def main():
height = int(height) height = int(height)
except ValueError: except ValueError:
raise ValueError(_('Invalid stage size: %r') % args.size) raise ValueError(_('Invalid stage size: %r') % args.size)
Danmaku2ASS(args.file, args.format, args.output, width, height, args.protect, args.font, args.fontsize, args.alpha, args.duration_marquee, args.duration_still, args.filter, args.filter_file, args.reduce) Danmaku2ASS(args.file, args.format, args.output, width, height, args.protect, args.font, args.fontsize, args.alpha, args.duration_marquee, args.duration_still, args.filter, args.reduce)
if __name__ == '__main__': if __name__ == '__main__':