Parcourir la source

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]
master
bertieb il y a 4 ans
Parent
révision
e5bcb8d9ef
1 fichiers modifiés avec 113 ajouts et 0 suppressions
  1. +113
    -0
      jsonclips.py

+ 113
- 0
jsonclips.py Voir le fichier

@@ -0,0 +1,113 @@
#!/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])

Chargement…
Annuler
Enregistrer