Skip to content

Instantly share code, notes, and snippets.

@amolok
Created December 21, 2023 15:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save amolok/4913562c5b4c4213865800cbb7014d4f to your computer and use it in GitHub Desktop.
Save amolok/4913562c5b4c4213865800cbb7014d4f to your computer and use it in GitHub Desktop.
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from __future__ import print_function
import sys
import os
import re
from datetime import datetime
import time
import subprocess
DISK = "Y:"
FOLDER = "DCIM"
FILE = "files.txt"
OUT_PATH = os.path.join("M:","Projects","RIMANI","timelapse")
bin_path = "C:/Users/amrok/Dropbox/soft/ffmpeg-3.4-win64-static/bin/"
# bin_path = "./bin/"
# Print iterations progress
# ░▒▓█
def printProgressBar (iteration, total, prefix = '', suffix = '', decimals = 1, length = 100, fill = '▓', empty = '░', printEnd = "\r"):
"""
Call in a loop to create terminal progress bar
@params:
iteration - Required : current iteration (Int)
total - Required : total iterations (Int)
prefix - Optional : prefix string (Str)
suffix - Optional : suffix string (Str)
decimals - Optional : positive number of decimals in percent complete (Int)
length - Optional : character length of bar (Int)
fill - Optional : bar fill character (Str)
empty - Optional : bar empty character (Str)
printEnd - Optional : end character (e.g. "\r", "\r\n") (Str)
"""
percent = ("{0:." + str(decimals) + "f}").format(100 * (iteration / float(total)))
filledLength = int(length * iteration // total)
bar = fill * filledLength + empty * (length - filledLength)
print(f'\r{prefix} {bar} {percent}% {suffix}', end = printEnd)
# Print New Line on Complete
if iteration == total:
print()
def getTimeS(time):
h = int(time[0:2])
m = int(time[3:5])
s = int(time[6:8])
ms = int(time[9:11])
ts = (h * 60 * 60) + (m * 60) + s + (ms/60)
return int(ts)
def time_format(seconds):
if seconds < 90:
return f"{seconds:.0f}s"
elif seconds < 150:
return f"{seconds / 60:.1f}m"
elif seconds < 3600:
minutes = seconds // 60
seconds = seconds % 60
return f"{minutes:02.0f}:{seconds:02.0f}"
else:
hours = seconds // 3600
minutes = (seconds % 3600) // 60
seconds = seconds % 60
return f"{hours:02.0f}:{minutes:02.0f}:{seconds:02.0f}"
# -i g%04d.jpg -an -c:v libx264 -crf 30 -maxrate 1M -bufsize 1M -pix_fmt yuv420p -vf "eq=contrast=1.2:gamma=1.2:saturation=2,scale=800:-1" timelapse.mp4
def create_timelapse(input_file, output_file, total_frames):
bitrate = "1M"
cmd = subprocess.Popen([bin_path+"ffmpeg",
# "-minrate "+bitrate, "-maxrate "+bitrate, "-b:v "+bitrate,
"-f", "concat",
"-safe", "0",
"-i", os.path.join(input_file),
"-an",
"-c:v", "libx264",
"-crf", "30",
"-maxrate", "1M",
"-bufsize", "1M",
"-pix_fmt", "yuv420p",
"-vf", "eq=contrast=1.2:gamma=1.2:saturation=2,scale=800:-1",
"-y", output_file
],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
universal_newlines=True,
# shell=True
)
for line in cmd.stdout:
# print(line)
# print(str(line.rstrip()))
frame = re.search('frame= +([^ ]*)',line)
fps = re.search('fps= ?([^ ]*)',line)
size = re.search('size= +([^ ]*)',line)
# if frame:
# print(frame[1])
# if fps:
# print(fps[1])
# if size:
# print(size[1])
if frame and fps and size:
# print(line)
# print("f={}, {}fps, {}".format(frame[1], fps[1], size[1]))
printProgressBar(int(frame[1]), total_frames, length=60, prefix=" * Собираем кадр {:>7}".format(frame[1]) , suffix="({} fps) размер {}".format(fps[1], size[1]))
# cmd.stdout.flush()
# print("Записали файл "+filename.upper()+"."+ 60*" ")
return cmd.stdout
def get_file_list_and_time(directory):
file_list = []
earliest_time = None
latest_time = None
for root, dirs, files in os.walk(directory):
# print(" +- {} {} {}".format(root, len(dirs), len(files)))
if len(dirs)>0:
print(" +- {} папок".format(len(dirs)), end=" "*20+'\r')
else:
print(" +- {} файлов в папке {}".format(len(files), root), end=" "*20+'\r')
for file in files:
# print(" + - {} / {}".format(root, file))
if file.endswith(".JPG"):
file_path = os.path.join(root, file)
# print(" +-> "+file_path)
print(" +-> "+file_path, end=" "*20+'\r')
file_list.append(file_path)
# creation_time = os.path.getctime(file_path)
# if earliest_time is None or creation_time < earliest_time:
# earliest_time = creation_time
# if latest_time is None or creation_time > latest_time:
# latest_time = creation_time
# print(" += {} файлов нашлось".format(len(file_list)))
return [file_list, datetime.fromtimestamp(os.path.getctime(file_list[0])), datetime.fromtimestamp(os.path.getctime(file_list[-1]))]
# return [file_list, datetime.fromtimestamp(earliest_time), datetime.fromtimestamp(latest_time)]
def save_file_list(file_list, output_file):
with open(output_file, 'w') as f:
for file in file_list:
f.write(file + '\n')
def main():
if len(sys.argv)<2:
folder = DISK+'\\'+FOLDER
else:
folder = sys.argv[1]
if len(sys.argv)==3:
output_file = sys.argv[2]
else:
output_file = os.path.join(DISK, FILE)
start = time.time()
print("[ ] Собираем таймлапс из папки: {}".format(folder))
[files, earliest_time, latest_time] = get_file_list_and_time(folder)
# file_list = ["file '{}'".format(file) for file in files]
file_list = ["file 'file:{}'".format(file) for file in files]
# file_list = ["file 'file:{}'".format(file.replace('\\', '/')) for file in files]
# file_list = ["file '{}'".format(file.replace(DISK, "").replace("\\", "/")) for file in files]
save_file_list(file_list, output_file)
timelapse = "timelapse ({} - {}).mp4".format(earliest_time.strftime("%Y-%m-%d"), latest_time.strftime("%Y-%m-%d"))
print("[-] Сохраняем в файл {1} в папке {0}".format(OUT_PATH, timelapse))
print("[+] Всего кадров: {:>7}".format(len(files)))
create_timelapse(output_file, timelapse, len(file_list))
# create_timelapse(output_file, os.path.join(OUT_PATH, timelapse))
end = time.time()
print("[=] Закончили за {}".format(time_format(end - start)))
if __name__ == '__main__':
print ("Сборка таймлапса с гоупро.")
# print ("Первый параметр - откуда брать JPG, второй - название таймлапса. Где брать ffmpeg захардкожено. Работает и без параметров.")
print ("t.me/amrok")
main()
# print()
quit()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment