Реверс видео любой длительности

  1. #!/usr/bin/python
  2. import sys, os, glob, re, subprocess
  3.  
  4. def show_process(args):
  5.     print(subprocess.check_output(args))
  6.  
  7. def main(argv):
  8.     if len(argv) != 2:
  9.         print('Usage: reverse.py input_file parts_count')
  10.         sys.exit(2)
  11.  
  12.     input_file = argv[0]
  13.     parts_count = int(argv[1])
  14.     if parts_count <= 0:
  15.         print('parts_count must be greater than zero')
  16.         sys.exit(2)
  17.  
  18.     # Get duration
  19.     output = subprocess.check_output([
  20.         "ffprobe",
  21.         "-v", "error",
  22.         "-show_entries", "format=duration",
  23.         "-of", "default=nw=1:nk=1",
  24.         input_file
  25.     ])
  26.     duration = float(output)
  27.     duration_per_part = duration / parts_count
  28.  
  29.     # Split input video
  30.     print("Split video into segments")
  31.     show_process([
  32.         "ffmpeg", "-y",
  33.         "-v", "error", "-stats",
  34.         "-i", input_file,
  35.         "-c:v", "copy",
  36.         "-an",
  37.         "-f", "segment",
  38.         "-segment_time", str(duration_per_part),
  39.         '-reset_timestamps', "1",
  40.         "tmp_part_i%5d.mp4"
  41.     ])
  42.  
  43.     # Reverse video parts
  44.     tmp_files = glob.glob('tmp_part_i*.mp4')
  45.     parts_count = len(tmp_files)
  46.     reversed_files = [None] * parts_count
  47.     i = 0
  48.     for filename in tmp_files:
  49.         i += 1
  50.         print("Reverse {}/{}".format(i, parts_count))
  51.         num = int(re.search('tmp_part_i(.+?)\.mp4', filename).group(1))
  52.         result_index = parts_count - num - 1
  53.         reversed_file = "tmp_part_r{}.mp4".format(result_index)
  54.         show_process([
  55.             "ffmpeg", "-y",
  56.             "-v", "error", "-stats",
  57.             "-i", filename,
  58.             "-vf", "reverse",
  59.             reversed_file
  60.         ])
  61.         os.remove(filename)
  62.         reversed_files[result_index] = reversed_file
  63.  
  64.     # Reverse audio
  65.     print("Reverse audio")
  66.     show_process([
  67.         "ffmpeg", "-y",
  68.         "-v", "error", "-stats",
  69.         "-i", input_file,
  70.         "-af", "areverse",
  71.         "tmp_audio.mp3"
  72.     ])
  73.  
  74.     # Join video parts and audio
  75.     print("Join {} parts".format(parts_count))
  76.     with open(input_file + '.list', 'w') as listfile:
  77.         for filename in reversed_files:
  78.             listfile.write("file '{}'\n".format(filename))
  79.     show_process([
  80.         "ffmpeg", "-y",
  81.         "-v", "error", "-stats",
  82.         "-f", "concat",
  83.         "-i", input_file + '.list',
  84.         "-i", "tmp_audio.mp3",
  85.         # Uncomment for quick but rough result
  86.         #"-c", "copy",
  87.         input_file + '_rev.mp4'
  88.     ])
  89.  
  90.     # Clean up
  91.     for filename in glob.glob('tmp_part_r*.mp4'):
  92.         os.remove(filename)
  93.     os.remove('tmp_audio.mp3')
  94.     os.remove(input_file + '.list')
  95.  
  96.  
  97. if __name__ == "__main__":
  98.     main(sys.argv[1:])
ffmpeg для реверса видео и аудио (фильтры -vf reverse и -af areverse) загружает файл в оперативную память целиком. Большие видео таким образом не обработать, так что этот скрипт поможет в работе.
Он разбивает видео на части и делает их реверс, после чего объединяет в один.
Использование:
  1. ./reverse py video.mp4 10
где 10 - примерное количество частей, на которые нужно разбить видео.

Реклама

Мы в соцсетях

tw tg yt gt