Created
March 15, 2018 11:31
-
-
Save patmandenver/1eb1646e46256c0fba2b0a98175e7963 to your computer and use it in GitHub Desktop.
This file contains 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
#!/usr/bin/env python | |
# | |
# Script to help create time-lapse videos | |
# But done in nasty way so that it works on cygwin while | |
# Utilizing ffmpeg on windows | |
# Also will fill in gaps if sequential images are missing | |
# | |
################################################## | |
import argparse | |
import sys, os | |
import datetime | |
from shutil import copyfile | |
import time | |
image_types = ('.png', '.jpg', '.jpeg') | |
def parseArgs(): | |
parser = argparse.ArgumentParser() | |
parser.add_argument("-f", "--folder", action='store', dest='images_folder', help="Folder that contains all images and subfolders you want to create videos for", required=True, default=None) | |
parser.add_argument("-r", "--recreate-videos", action='store', dest='recreate_videos', help="Recreates videos otherwise if they exist they will be skipped", required=False, default=False) | |
parser.add_argument("-v", "--verbose", action='store', dest='verbose', help="Allows ffmpeg to be verbose", required=False, default=False) | |
return parser.parse_args() | |
def get_folders_with_images(img_folder, file_extension): | |
folders_with_images = [] | |
all_folders = [x[0] for x in os.walk(img_folder)] | |
for folder in all_folders: | |
for file_name in os.listdir(folder): | |
if file_name.lower().endswith(image_types): | |
folders_with_images.append(folder) | |
break | |
return folders_with_images | |
def get_start_number(folder): | |
start_num = -1 | |
for file_name in os.listdir(folder): | |
if file_name.lower().endswith(image_types): | |
number = file_name[1:file_name.rfind(".")] | |
if start_num == -1 or start_num > int(number): | |
start_num = int(number) | |
return start_num | |
def print_elapsed_time(start_time, end_time): | |
elapsed_time = end_time - start_time | |
days = int(elapsed_time.seconds / (3600*24)) | |
hours = int((elapsed_time.seconds - days*3600*24)/3600) | |
minutes = int((elapsed_time.seconds - days*3600*24 - hours*3600)/60) | |
seconds = int((elapsed_time.seconds - days*3600*24 - hours*3600 - minutes*60)) | |
print(elapsed_time.seconds) | |
print(str(days) + " days " + str(hours) + " hours " + str(minutes) + " min " + str(seconds) + " sec") | |
#This will fill in gaps it finds in file numbers | |
def fill_in_gaps(folder, start_num): | |
last_img_file = "G" + str(start_num).zfill(7) + ".JPG" | |
file_list = os.listdir(folder) | |
biggest_num = start_num | |
#Find biggest file Number | |
for file_name in file_list: | |
if file_name.lower().endswith(image_types): | |
temp_num = int(file_name[1:-4]) | |
if temp_num > biggest_num: | |
biggest_num = temp_num | |
#Check sequence | |
for x in range(start_num, biggest_num): | |
file_check_name = "G" + str(x).zfill(7) + ".JPG" | |
if not os.path.exists(folder + "/" + file_check_name): | |
prior_file = "G" + str(x-1).zfill(7) + ".JPG" | |
print("Missing sequential file !!!!\n copying prior file \n'" + folder + "/" + prior_file + "' to\n'" + folder + "/" + file_check_name + "'") | |
copyfile(folder + "/" + prior_file,folder + "/" + file_check_name) | |
time.sleep(1) | |
################################################################################ | |
# MAIN | |
################################################################################ | |
if __name__ == '__main__': | |
args = parseArgs() | |
img_folder = args.images_folder | |
recreate = args.recreate_videos | |
verbose = args.verbose | |
#Start timer | |
start_time = datetime.datetime.now() | |
#check if folder exists | |
if os.path.exists(img_folder): | |
folders_with_images = get_folders_with_images(img_folder, ".JPG") | |
print(" === Obtaining all folders with image data ===") | |
x = 0 | |
for folder in folders_with_images: | |
x += 1 | |
print(" === working on " + str(x) + "/" + str(len(folders_with_images)) + " === ") | |
video_name = img_folder[img_folder.rfind('/')+1:] + folder[len(img_folder):].replace("/", "_") + ".mp4" | |
#if exists and recreate: | |
if os.path.isfile(img_folder + "/" + video_name) and not recreate: | |
print("video file exists '" + str(video_name) + "' ... Skipping creation") | |
#Want to skip | |
continue | |
#Find start number of files! | |
start_number = get_start_number(folder) | |
#Use ffmpeg on the command line to create video | |
#Had to do some funky stuff since it is using the windows ffmpeg | |
individual_start_time = datetime.datetime.now() | |
#fill in missing gaps in images by copying the last image up | |
fill_in_gaps(folder, start_number) | |
not_verbose = "" | |
if not verbose: | |
not_verbose = "-nostats -loglevel 0" | |
linux_command = "cd " + folder + "; /cygdrive/c/ffmpeg/bin/ffmpeg -err_detect ignore_err -y " + not_verbose + " -start_number " + str(start_number) + " -i G%07d.JPG -vcodec libx264 -pix_fmt yuv420p " + img_folder.replace("/cygdrive/c","C:") + "/" + video_name | |
os.system(linux_command) | |
print_elapsed_time(individual_start_time, datetime.datetime.now()) | |
else: | |
print("Folder does not exist '" + str(img_folder) + "' ... exiting") | |
sys.exit(1) | |
print(" === Job Complete == ") | |
print_elapsed_time(start_time, datetime.datetime.now()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment