#!/bin/python """jsonclips.py - generate highlights based on JSON usage: jsonclips.py clips.json JSON file can specify: - output filename - source filepath - start time - duration - transition type [default: luma] - transition duration [default: 30] """ DEFAULT_TRANSITION_DURATION = 30 # 30 frames, ie 0.5s at 60FPS DEFAULT_TRANSITION_TYPE = "luma" def process_highlights(jsonfile): """Go through highlights, make clips, join to a video""" import tempfile def make_clips(sources=None, outputdir=None): """Use ffmpeg to create output from processed JSON""" import subprocess import os ffmpeg_common_args = ["ffmpeg", "-loglevel", "quiet", "-hide_banner"] clipnum = 0 for source in sources: print("Making {}s clip from {} at {}".format( source["duration"], source["filepath"], source["time"])) ffmpeg_file_args = ["-ss", str(source["time"]), "-i", source["filepath"], "-t", str(source["duration"]), "-c", "copy", os.path.join(outputdir, "clip{}.mkv".format(clipnum))] ffmpeg_args = ffmpeg_common_args + ffmpeg_file_args print("Running ffmpeg with args:\n\n{}". format(ffmpeg_args)) subprocess.run(ffmpeg_args) clipnum += 1 def make_output(workingdir=None, outputfile=None, numsources=None): """Use MLT (melt) to join clips""" import subprocess import os melt_args = ["melt"] for i in range(numsources): if i == 0: melt_args.extend([os.path.join(workingdir, "clip{}.mkv" .format(i))]) else: melt_args.extend([ os.path.join(workingdir, "clip{}.mkv".format(i)), "-mix", str(DEFAULT_TRANSITION_DURATION), "-mixer", str(DEFAULT_TRANSITION_TYPE)]) melt_args.extend(["-consumer", "avformat:{}".format(outputfile), "crf=20"]) print("Running melt with args:\n\n{}".format(melt_args)) subprocess.run(melt_args) def parse_json(jsonfile=None): """Parse global / per--clip options from jsonfile Requires: - outputfile - list of sources """ import json import sys if jsonfile: with open(jsonfile, "r") as fh: json_in = json.load(fh) if "outputfile" not in json_in: print("Please specify an outputfile to write to") sys.exit(1) if "sources" not in json_in: print("Please specify some sources to process") sys.exit(1) return json_in # Start if jsonfile: json_in = parse_json(jsonfile) # in temporary dir with tempfile.TemporaryDirectory() as tmpdir: # make clips make_clips(sources=json_in["sources"], outputdir=tmpdir) # join clips using melt make_output(workingdir=tmpdir, outputfile=json_in["outputfile"], numsources=len(json_in["sources"])) if __name__ == "__main__": import sys process_highlights(sys.argv[1])