From 13010a9812a3a419a36f6cda63ce3c9e323ae96d Mon Sep 17 00:00:00 2001 From: Yannik Enss Date: Sun, 10 May 2020 11:06:47 +0200 Subject: [PATCH] init --- jumpcutter.py | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100755 jumpcutter.py diff --git a/jumpcutter.py b/jumpcutter.py new file mode 100755 index 0000000..ab05f87 --- /dev/null +++ b/jumpcutter.py @@ -0,0 +1,64 @@ +#!/usr/bin/python3 +import subprocess as sp +from shlex import quote +import re +import argparse +import sys, os + +FFMPEG_SILENCEDETECT_COMMAND = "ffmpeg -y -hide_banner -nostats -i {filename} -af silencedetect=d=0.3 -map 0 -map -0:v -f wav /dev/null" + +SILENCE_START_RE = re.compile("^\[silencedetect @ 0x[0-9a-f]+\] silence_start: ([\d\.]+)$") +SILENCE_END_RE = re.compile("^\[silencedetect @ 0x[0-9a-f]+\] silence_end: ([\d\.]+) \| silence_duration: ([\d\.]+)$") + +def cut(in_file, out_file="out_file.mkv", silences=[]): + betweens = "" + for silence in silences: + betweens += f"between(t,{silence[0]},{silence[1]})+" + + betweens = betweens[:-1] if betweens else betweens + + video_filter = f"select='{betweens}',setpts=N/FRAME_RATE/TB" + audio_filter = f"aselect='{betweens}',asetpts=N/SR/TB" + + command = ["ffmpeg", "-i", in_file, "-vf", video_filter, "-af", audio_filter, out_file] + + sp.run(command) + +def detect_silence(filename): + output = sp.run(FFMPEG_SILENCEDETECT_COMMAND.format(filename=quote(filename)), shell=True, stderr=sp.PIPE).stderr + total_silence = 0 + talking = [] + current_silence = ["0", None] + for line in output.split(b"\n"): + line = line.strip() + line = line.decode("utf8") + if not "silencedetect" in line: + continue + if match := SILENCE_START_RE.match(line): + print("Silence start at", match[1]) + current_silence[1] = match[1] + talking.append(tuple(current_silence)) + elif match := SILENCE_END_RE.match(line): + print("Silence end at", match[1]) + current_silence[0] = match[1] + total_silence += float(match.group(2)) + + print("Total:", total_silence) + return talking + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("--output-format", "-f") + parser.add_argument("infiles", nargs="+") + args = parser.parse_args() + + for f in args.infiles: + if not os.path.isfile(f): + print(f"{f} not found, skipping...", file=sys.stderr) + continue + + new_filename = os.path.splitext(f)[0]+".mkv" + + talking = detect_silence(f) + cut(f, new_filename, talking)