Created
October 5, 2020 19:07
-
-
Save antiboredom/8808d04c86ee13e5cf55b1347e043e20 to your computer and use it in GitHub Desktop.
Create a supercut of a video using only the quiet bits
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import argparse | |
import re | |
import os | |
import subprocess | |
from moviepy.editor import VideoFileClip, concatenate_videoclips | |
def get_silences(filename, db, duration): | |
args = "ffmpeg -nostats -i {} -af silencedetect=noise={}dB:d={} -f null -".format( | |
filename, db, duration | |
) | |
# > output.txt 2>&1 | |
results = subprocess.getoutput(args) | |
outname = filename + ".silences.txt" | |
with open(outname, "w") as outfile: | |
outfile.write(results) | |
return outname | |
def parse_silences(filename): | |
with open(filename, "r") as infile: | |
lines = infile.readlines() | |
out = [] | |
start = None | |
end = None | |
for l in lines: | |
if "silencedetect" not in l: | |
continue | |
if start is None: | |
results = re.search(r"silence_start: ([0-9.]+)", l) | |
if results: | |
start = float(results.group(1)) | |
else: | |
results = re.search(r"silence_end: ([0-9.]+)", l) | |
if results: | |
end = float(results.group(1)) | |
out.append((start, end)) | |
start = None | |
end = None | |
return out | |
def compose(videofile, silences): | |
filename, file_extension = os.path.splitext(videofile) | |
movie = VideoFileClip(videofile) | |
clips = [] | |
for start, end in silences: | |
duration = end - start | |
clip = movie.subclip(start, end) | |
clips.append(clip) | |
outname = filename + "_silences" + file_extension | |
final_clip = concatenate_videoclips(clips) | |
final_clip.write_videofile( | |
outname, | |
codec="libx264", | |
temp_audiofile="temp-audio.m4a", | |
remove_temp=True, | |
audio_codec="aac", | |
) | |
return outname | |
if __name__ == "__main__": | |
parser = argparse.ArgumentParser( | |
description="Create a supercut of silences in a video" | |
) | |
parser.add_argument("path", nargs="+", help="Path of a file or a folder of files.") | |
parser.add_argument("--db", dest="db", default="-30", help="Decibal level") | |
parser.add_argument( | |
"--duration", dest="duration", default="1", help="Silence duration" | |
) | |
args = parser.parse_args() | |
videofile = args.path[0] | |
silence_file = get_silences(videofile, args.db, args.duration) | |
silences = parse_silences(silence_file) | |
compose(videofile, silences) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This script create a supercut of the quiet bits of a video file, using ffmpeg to find silences and moviepy to stitch things together. To run, first install moviepy:
Also make sure that you have ffmpeg installed. On a mac:
Then call the script like so:
This will extract all the silences quieter than -30dB and longer than 1 second. You may need to play around with the db and duration parameters to get desirable results.