pavelpantyukhin

bdn_render.py

Jul 27th, 2018
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.84 KB | None | 0 0
  1. #!/usr/local/bin/python3
  2.  
  3. # -*- coding: utf-8 -*-
  4.  
  5. '''Render ASS to PGS/Blu-ray Subtitles'''
  6.  
  7. import os
  8. import sys
  9. from colorama import init, Fore, Style
  10. from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter
  11. import shutil
  12. import tempfile
  13. import subprocess
  14. import pysubs2
  15.  
  16. ALLOWED_VF  = ('1080p', '1080i', '720p', '576i', '480p', '480i')
  17. ALLOWED_FPS = ('23.976', '24', '25', '29.97', '50', '59.94')
  18.  
  19. def winepath(path):
  20.     return subprocess.check_output(['winepath', '-w', path]).decode().replace('\n', '')
  21.  
  22. def main():
  23.     init(autoreset=True)
  24.     parser = ArgumentParser(description=__doc__, formatter_class=ArgumentDefaultsHelpFormatter)
  25.     parser.add_argument('input', help='Input ass')
  26.     parser.add_argument('-o', '--output', required=True, help='Output dir')
  27.     parser.add_argument('--fps', default='23.976', help='Target framerate')
  28.     parser.add_argument('--video-format', default='1080p', help='Output subtitles format')
  29.     parser.add_argument('--lang', default='rus', help='Output language code for subtitles')
  30.     parser.add_argument('--sup', action='store_true', help='Addionatinly output PGS/SUP file')
  31.     args = parser.parse_args()
  32.  
  33.     if os.path.isfile(args.input):
  34.         filename = os.path.basename(args.input)
  35.         if os.path.splitext(filename)[-1].lower() == '.ass':
  36.             ass = args.input
  37.         else:
  38.             sys.exit(f'{Fore.RED}{Style.BRIGHT}Not an ass file')
  39.     else:
  40.         sys.exit(f'{Fore.RED}{Style.BRIGHT}ASS file not found')
  41.  
  42.     if not os.path.isdir(args.output):
  43.         sys.exit(f'{Fore.RED}{Style.BRIGHT}Output dir not specified')
  44.  
  45.     if args.video_format not in ALLOWED_VF:
  46.         sys.exit(f'{Fore.RED}{Style.BRIGHT}{args.video_format} not allowed')
  47.  
  48.     if args.fps not in ALLOWED_FPS:
  49.         sys.exit(f'{Fore.RED}{Style.BRIGHT}{args.fps} not allowed')
  50.  
  51.     subs = pysubs2.load(ass)
  52.     subs.sort()
  53.     duration = pysubs2.time.ms_to_frames(subs[-1].end, float(args.fps)) + 20
  54.  
  55.     if duration < 10:
  56.         sys.exit(f'{Fore.RED}{Style.BRIGHT}Duration of subtitles is lower than 10 frames. Abort')
  57.  
  58.     basename   = os.path.splitext(os.path.basename(ass))[0]
  59.     output_dir = os.path.join(args.output, os.path.splitext(os.path.basename(ass))[0])
  60.     output_xml = os.path.join(output_dir, basename) + '.xml'
  61.     output_sup = os.path.join(args.output, basename) + '.sup'
  62.  
  63.     if os.path.exists(output_dir):
  64.         shutil.rmtree(output_dir)
  65.     if os.path.exists(output_sup):
  66.             os.remove(output_sup)
  67.     os.mkdir(output_dir)
  68.  
  69.     avs_temp = tempfile.mkstemp(suffix='.avs', dir=output_dir)[-1]
  70.  
  71.     with open(avs_temp, 'w') as avs:
  72.         print('Loadplugin("C:\\Program Files (x86)\\AviSynth+\\plugins+\\VSFilter.dll")', file=avs)
  73.         print(f'MaskSub(\"{winepath(args.input)}\", 1920, 1080, {args.fps}, {duration})', file=avs)
  74.  
  75.     render = ['wine', 'avs2bdnxml', '--trackname', basename,
  76.             '--language', f'{args.lang}', '--video-format', f'{args.video_format}', '--fps', f'{args.fps}',
  77.             '--autocrop', '1', '--palette', '1', '--buffer-opt', '0', '--min-split', '3',
  78.             '--ugly', '0', '--even-y', '0', '--null-xml', '0', '--stricter', '0',
  79.             '--output', output_xml
  80.         ]
  81.  
  82.     if args.sup:
  83.         if os.path.exists(output_sup):
  84.             os.remove(output_sup)
  85.         render.extend(('--output', output_sup))
  86.     render.append(avs_temp)
  87.    
  88.     try:
  89.         subprocess.run(render, check=True)
  90.     except subprocess.CalledProcessError:
  91.         try:
  92.             shutil.rmtree(output_dir)
  93.             os.remove(output_sup)
  94.         except:
  95.             pass
  96.         sys.exit(f'{Fore.RED}{Style.BRIGHT}Error occurred during rendering')
  97.     else:
  98.         print(f'{Fore.GREEN}{Style.BRIGHT}Done')
  99.  
  100.     try:
  101.         os.remove(avs_temp)
  102.     except:
  103.         pass
  104.  
  105. if __name__ == "__main__":
  106.     main()
Add Comment
Please, Sign In to add comment