Python script for splitting videos into tiles with ffmpeg
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

87 lines
2.4 KiB

  1. import os
  2. import sys
  3. import json
  4. import ffmpeg
  5. if sys.argv[1] == 'grid' or sys.argv[1] == 'file':
  6. mode = sys.argv[1]
  7. if (mode == 'grid'):
  8. cols = sys.argv[2]
  9. rows = sys.argv[3]
  10. inputpath = os.path.abspath(sys.argv[4])
  11. outputdir = os.path.abspath(sys.argv[5])
  12. if (mode == 'file'):
  13. layoutpath = os.path.abspath(sys.argv[2])
  14. inputpath = os.path.abspath(sys.argv[3])
  15. outputdir = os.path.abspath(sys.argv[4])
  16. else:
  17. print('Videoshredder splits a video into multiple tiles')
  18. print('There are two layout input modes available: grid and file')
  19. print('')
  20. print('Examples:')
  21. print('')
  22. print('./video-shredder.py grid 4 3 path/to/inputfile.mp4 output_dirctory')
  23. print(' ... splits the video into 4x3 equally distributed tiles')
  24. print('')
  25. print('./video-shredder.py file layout.json path/to/inputfile.mp4 output_dirctory')
  26. print(' ... splits into tiles defined in the layout file')
  27. print('')
  28. exit()
  29. try:
  30. os.stat(outputdir)
  31. except:
  32. print('Creating new directory', outputdir)
  33. os.mkdir(outputdir)
  34. def generateGrid (source, h_tiles, v_tiles):
  35. probe = ffmpeg.probe(source)
  36. video = next((stream for stream in probe['streams'] if stream['codec_type'] == 'video'), None)
  37. width = int(video['width'])
  38. height = int(video['height'])
  39. layout = []
  40. tile_width = width/int(h_tiles)
  41. tile_height = height/int(v_tiles)
  42. for row in range(int(v_tiles)):
  43. for col in range(int(h_tiles)):
  44. print('row col', row, col)
  45. layout.append(
  46. {
  47. "name": str(row+1) + "-" + str(col+1),
  48. "geomentry": {
  49. "x": str(tile_width*col).split('.')[0],
  50. "y": str(tile_height*row).split('.')[0],
  51. "width": str(tile_width).split('.')[0],
  52. "height": str(tile_height).split('.')[0]
  53. }
  54. })
  55. return layout
  56. def processLayout (layout):
  57. print(layout)
  58. for item in layout:
  59. outputpath = os.path.join(outputdir, item["name"] + '.mp4')
  60. print('processing: ' +item["name"])
  61. print(' input path: ' + inputpath)
  62. print(' output path: ' + outputpath)
  63. stream = (
  64. ffmpeg
  65. .input(inputpath)
  66. .crop(**item['geomentry'])
  67. .output(outputpath, pix_fmt='yuv420p')
  68. .run()
  69. )
  70. print('Finished processing all tiles!')
  71. print('Output directory: ' + str(outputdir))
  72. if (mode == 'file'):
  73. with open(layoutpath, "r") as read_file:
  74. processLayout(json.load(read_file))
  75. if (mode == 'grid'):
  76. layout = generateGrid(inputpath, cols, rows)
  77. processLayout(layout)