From 467f414ace2b06b7ca01bfec640eb7e24ac6168b Mon Sep 17 00:00:00 2001 From: Andreas Demmelbauer Date: Sun, 7 Feb 2021 19:54:51 +0100 Subject: [PATCH] shredder it --- README.md | 32 ++++++++++++++++++ layout.json | 56 ++++++++++++++++++++++++++++++ requirements.txt | 1 + video-shredder.py | 86 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 175 insertions(+) create mode 100644 README.md create mode 100644 layout.json create mode 100644 requirements.txt create mode 100644 video-shredder.py diff --git a/README.md b/README.md new file mode 100644 index 0000000..3a0785c --- /dev/null +++ b/README.md @@ -0,0 +1,32 @@ +# Python script for splitting videos into tiles with ffmpeg + +It supports simple grid definitions and advanced layout definitions from a json layout definition file. + +## Installation + +### Install git, ffmpeg and python3 with pip on your system +For Debian: +``` +sudo apt install git ffmpeg python3 python3-pip +``` + +### Clone this git repository +``` +git clone https://git.notice.at/redplanet/video-shredder.git +``` + +### Enter directory and install python requirements +``` +pip3 install -r requirements.txt +``` + +## Usage +grid mode: +``` +python3 videoshredder.py grid +``` + +file mode: +``` +python3 videoshredder.py file +``` \ No newline at end of file diff --git a/layout.json b/layout.json new file mode 100644 index 0000000..a6607d7 --- /dev/null +++ b/layout.json @@ -0,0 +1,56 @@ +[ + { + "name": "1-1", + "geomentry": { + "x": "0", + "y": "0", + "width": "1280/3", + "height": "720/2" + } + }, + { + "name": "1-2", + "geomentry": { + "x": "1280/3", + "y": "0", + "width": "1280/3", + "height": "720/2" + } + }, + { + "name": "1-3", + "geomentry": { + "x": "1280/3*2", + "y": "0", + "width": "1280/3", + "height": "720/2" + } + }, + { + "name": "2-1", + "geomentry": { + "x": "0", + "y": "720/2", + "width": "1280/3", + "height": "720/2" + } + }, + { + "name": "2-2", + "geomentry": { + "x": "1280/3", + "y": "720/2", + "width": "1280/3", + "height": "720/2" + } + }, + { + "name": "2-3", + "geomentry": { + "x": "1280/3*2", + "y": "720/2", + "width": "1280/3", + "height": "720/2" + } + } +] diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..9abb303 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +ffmpeg-python \ No newline at end of file diff --git a/video-shredder.py b/video-shredder.py new file mode 100644 index 0000000..1d1bc26 --- /dev/null +++ b/video-shredder.py @@ -0,0 +1,86 @@ +import os +import sys +import json +import ffmpeg + +if sys.argv[1] == 'grid' or sys.argv[1] == 'file': + mode = sys.argv[1] + + if (mode == 'grid'): + cols = sys.argv[2] + rows = sys.argv[3] + inputpath = os.path.abspath(sys.argv[4]) + outputdir = os.path.abspath(sys.argv[5]) + if (mode == 'file'): + layoutpath = os.path.abspath(sys.argv[2]) + inputpath = os.path.abspath(sys.argv[3]) + outputdir = os.path.abspath(sys.argv[4]) +else: + print('Videoshredder splits a video into multiple tiles') + print('There are two layout input modes available: grid and file') + print('') + print('Examples:') + print('') + print('./video-shredder.py grid 4 3 path/to/inputfile.mp4 output_dirctory') + print(' ... splits the video into 4x3 equally distributed tiles') + print('') + print('./video-shredder.py file layout.json path/to/inputfile.mp4 output_dirctory') + print(' ... splits into tiles defined in the layout file') + print('') + exit() + +try: + os.stat(outputdir) +except: + print('Creating new directory', outputdir) + os.mkdir(outputdir) + +def generateGrid (source, h_tiles, v_tiles): + probe = ffmpeg.probe(source) + video = next((stream for stream in probe['streams'] if stream['codec_type'] == 'video'), None) + width = int(video['width']) + height = int(video['height']) + + layout = [] + + tile_width = width/int(h_tiles) + tile_height = height/int(v_tiles) + + for row in range(int(v_tiles)): + for col in range(int(h_tiles)): + print('row col', row, col) + layout.append( + { + "name": str(row+1) + "-" + str(col+1), + "geomentry": { + "x": str(tile_width*col).split('.')[0], + "y": str(tile_height*row).split('.')[0], + "width": str(tile_width).split('.')[0], + "height": str(tile_height).split('.')[0] + } + }) + return layout + +def processLayout (layout): + print(layout) + for item in layout: + outputpath = os.path.join(outputdir, item["name"] + '.mp4') + print('processing: ' +item["name"]) + print(' input path: ' + inputpath) + print(' output path: ' + outputpath) + stream = ( + ffmpeg + .input(inputpath) + .crop(**item['geomentry']) + .output(outputpath) + .run() + ) + print('Finished processing all tiles!') + print('Output directory: ' + str(outputdir)) + +if (mode == 'file'): + with open(layoutpath, "r") as read_file: + processLayout(json.load(read_file)) +if (mode == 'grid'): + layout = generateGrid(inputpath, cols, rows) + processLayout(layout)