3 from tempfile import NamedTemporaryFile
 
   6 def video_from_image(img_path, duration, fps=25):
 
   7     tmp = NamedTemporaryFile(prefix='image', suffix='.mkv', delete=False)
 
  10         ['ffmpeg', '-y', '-loop', '1', '-t', str(duration), '-i', img_path, '-c:v', 'libx264', '-vf', f'fps={fps},format=yuv420p', tmp.name], check=True)
 
  14 def cut_video(video_path, duration):
 
  15     tmp = NamedTemporaryFile(prefix='cut', suffix='.mkv', delete=False)
 
  18         ['ffmpeg', '-y', '-i', video_path, '-t', str(duration), tmp.name], check=True)
 
  22 def ffmpeg_concat(paths, suffix):
 
  23     filelist = NamedTemporaryFile(prefix='concat', suffix='.txt')
 
  25         filelist.write(f"file '{path}'\n".encode('utf-8'))
 
  28     output = NamedTemporaryFile(prefix='concat', suffix=suffix, delete=False)
 
  32         ['ffmpeg', '-y', '-safe', '0', '-f', 'concat', '-i', filelist.name, '-c', 'copy', output.name],
 
  39 def concat_videos(paths):
 
  40     return ffmpeg_concat(paths, '.mkv')
 
  42 def concat_audio(paths):
 
  47     output = ffmpeg_concat(std_paths, '.flac')
 
  52 def standardize_audio(p):
 
  53     output = NamedTemporaryFile(prefix='standarize', suffix='.flac', delete=False)
 
  56         ['ffmpeg', '-y', '-i', p, '-sample_fmt', 's16', '-acodec', 'flac', '-ac', '2', '-ar', '44100', output.name],
 
  60 def standardize_video(p):
 
  61     output = NamedTemporaryFile(prefix='standarize', suffix='.mkv', delete=False)
 
  64         ['ffmpeg', '-y', '-i', p, output.name],
 
  70 def mux(channels, output_path=None):
 
  72         output = NamedTemporaryFile(prefix='concat', suffix='.mkv', delete=False)
 
  74         output_path = output.name
 
  77         args.extend(['-i', c])
 
  80     subprocess.run(args, check=True)
 
  84 def get_duration(path):
 
 105 def get_framerate(path):
 
 106     rates = subprocess.run(
 
 112                 "stream=r_frame_rate",
 
 121         ).stdout.strip().split('\n')
 
 123         a, b = rate.split('/')