init
This commit is contained in:
64
jumpcutter.py
Executable file
64
jumpcutter.py
Executable file
@@ -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)
|
||||||
Reference in New Issue
Block a user