diff --git a/make-video-thumbnails b/make-video-thumbnails new file mode 100755 index 0000000..bfb55a5 --- /dev/null +++ b/make-video-thumbnails @@ -0,0 +1,94 @@ +#!/usr/bin/env python3 +# call pyvideothumbnailer for every video file found +# +# calculates rows based on the duration of the video + +import math +import os +import subprocess + +from pymediainfo import MediaInfo + + +VERBOSE = False + +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): + # Recursively walk through directory + for dirpath, dirs, files in os.walk(directory): + for filename in files: + filename_path = os.path.join(dirpath, filename) + if is_video_file(filename_path, video_extensions): + yield os.path.abspath(filename_path) + + +def get_video_duration(video_file_path): + # Get media information + media_info = MediaInfo.parse(video_file_path) + + # Iterate through tracks in the media file + for track in media_info.tracks: + # If the track type is video + if track.track_type == "Video": + # Get duration and return it + duration_str = track.duration + duration_sec = float(duration_str) / 1000 # Convert to seconds + return duration_sec + + # Return None if no video track found + return None + + +def call_thumbnailer(video_file, width, rows, *, skip_seconds=10): + # Call external thumbnailer program + subprocess.run( + [ + "pyvideothumbnailer", + "--width", + str(width), + "--rows", + str(rows), + "--jpeg-quality", + str(90), + "--skip-seconds", + str(skip_seconds), + video_file, + ] + ) + + +def main(): + VIDEO_FILE_EXT = [".mp4", ".mkv", ".avi", ".mov", ".wmv"] + video_files = find_video_files(".", VIDEO_FILE_EXT) + + for video_file in video_files: + # Skip if .jpg file already exists + thumbnails_file = video_file + ".jpg" + if os.path.exists(thumbnails_file): + if VERBOSE: + print(f"Skipping: {video_file} (thumbnails already exist)") + continue + + try: + duration = get_video_duration(video_file) + if duration is not None: + # Calculate rows + COLS = 4 # pyvideothumbnailer default + EVERY = 5 * 60 # seconds + rows = math.ceil(duration / EVERY / COLS) + + skip_seconds = 10 + if duration < 60: + skip_seconds = 0 + + # Call the thumbnailer + WIDTH = 1600 + call_thumbnailer(video_file, WIDTH, rows, skip_seconds=skip_seconds) + except (TypeError, UnicodeEncodeError, FileNotFoundError) as e: + print(f"Error for {video_file}: {e}") + + +if __name__ == "__main__": + main()