🚧 autopyvideothumbnailer

master
neingeist 9 months ago
parent 3872b5ed0d
commit 144e755e41

@ -7,21 +7,24 @@ import math
import os import os
import subprocess import subprocess
import click import click
import mimetypes
from addict import Dict
from pymediainfo import MediaInfo from pymediainfo import MediaInfo
VERBOSE = False def is_video_file(video_file_path):
type_ = mimetypes.guess_type(video_file_path)[0]
return type_ is not None and type_.startswith("video/")
def is_video_file(video_file_path, video_extensions):
return video_file_path.lower().endswith(tuple(video_extensions))
def find_video_files(directory, video_extensions): def find_video_files(directory):
# Recursively walk through directory # Recursively walk through directory
for dirpath, dirs, files in os.walk(directory): for dirpath, dirs, files in os.walk(directory):
for filename in files: for filename in files:
filename_path = os.path.join(dirpath, filename) filename_path = os.path.join(dirpath, filename)
if is_video_file(filename_path, video_extensions): if is_video_file(filename_path):
yield os.path.abspath(filename_path) yield os.path.abspath(filename_path)
@ -42,60 +45,77 @@ def get_video_duration(video_file_path):
return None return None
def call_thumbnailer(video_file, width, rows, *, skip_seconds=10): def call_thumbnailer(video_file, width, columns, rows, *, skip_seconds=10):
# Call external thumbnailer program # Call external thumbnailer program
subprocess.run( subprocess.run(
[ [
"pyvideothumbnailer", "pyvideothumbnailer",
"--width", "--width",
str(width), str(width),
"--columns",
str(columns),
"--rows", "--rows",
str(rows), str(rows),
"--jpeg-quality", "--jpeg-quality",
str(90), str(90),
"--header-font",
config.font,
"--skip-seconds", "--skip-seconds",
str(skip_seconds), str(skip_seconds),
video_file, video_file,
] ]
) )
def process(searchdir): def process(searchdir):
VIDEO_FILE_EXT = [".mp4", ".mkv", ".avi", ".mov", ".wmv"] video_files = find_video_files(searchdir)
video_files = find_video_files(searchdir, VIDEO_FILE_EXT)
for video_file in video_files: for video_file in video_files:
# Skip if .jpg file already exists # Skip if .jpg file already exists
thumbnails_file = video_file + ".jpg" thumbnails_file = video_file + ".jpg"
if os.path.exists(thumbnails_file): if os.path.exists(thumbnails_file):
if VERBOSE: if config.verbose:
print(f"Skipping: {video_file} (thumbnails already exist)") print(f"Skipping: {video_file} (thumbnails already exist)")
continue continue
try: try:
duration = get_video_duration(video_file) duration = get_video_duration(video_file)
if duration is not None: if duration is not None:
# Calculate rows rows = math.ceil(duration / config.every / config.columns)
COLS = 4 # pyvideothumbnailer default
EVERY = 5 * 60 # seconds
rows = math.ceil(duration / EVERY / COLS)
skip_seconds = 10 skip_seconds = 10
if duration < 60: if duration < 60:
skip_seconds = 0 skip_seconds = 0
# Call the thumbnailer # Call the thumbnailer
WIDTH = 1600 call_thumbnailer(
call_thumbnailer(video_file, WIDTH, rows, skip_seconds=skip_seconds) video_file,
config.width,
config.columns,
rows,
skip_seconds=skip_seconds,
)
except (TypeError, UnicodeEncodeError, FileNotFoundError) as e: except (TypeError, UnicodeEncodeError, FileNotFoundError) as e:
print(f"Error for {video_file}: {e}") print(f"Error for {video_file}: {e}")
config = Dict()
@click.command() @click.command()
@click.argument('searchdirs', nargs=-1) @click.argument("searchdirs", nargs=-1)
def main(searchdirs): @click.option("-v", "--verbose", is_flag=True, default=False)
def main(searchdirs, verbose):
"""Run pyvideothumbnailer for every video file found""" """Run pyvideothumbnailer for every video file found"""
config.verbose = verbose
config.width = 1600
config.columns = 4 # pyvideothumbnailer default
config.every = 5 * 60 # seconds
config.font = "DejaVuSansMono.ttf"
if not searchdirs: if not searchdirs:
searchdirs=["."] searchdirs = ["."]
for searchdir in searchdirs: for searchdir in searchdirs:
process(searchdir) process(searchdir)

Loading…
Cancel
Save