Created
October 1, 2023 16:31
-
-
Save JupyterJones/13ed280dafd5d8a4f31096d6ec8f9c4c to your computer and use it in GitHub Desktop.
Flask Zoom and Image to video
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
#!/home/jack/Desktop/FlaskAppArchitect_Flask_App_Creator/env/bin/python3 | |
from flask import Flask, request, render_template, redirect, url_for, flash, send_from_directory | |
import os | |
import subprocess | |
import random | |
import uuid | |
import shutil | |
from werkzeug.utils import secure_filename | |
import glob | |
import logging | |
from logging.handlers import RotatingFileHandler | |
from PIL import Image | |
app = Flask(__name__) | |
app.secret_key = os.urandom(24) | |
# Create a logger object | |
logger = logging.getLogger(__name__) | |
logger.setLevel(logging.DEBUG) | |
# Create a formatter for the log messages | |
formatter = logging.Formatter( | |
'%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d]') | |
# Create a file handler to write log messages to a file | |
file_handler = RotatingFileHandler( | |
'Logs/zoom.log', maxBytes=10000, backupCount=1) | |
file_handler.setLevel(logging.DEBUG) | |
file_handler.setFormatter(formatter) | |
# Add the file handler to the logger | |
logger.addHandler(file_handler) | |
# Define a directory to store uploaded images | |
UPLOAD_FOLDER = 'static/temp_uploads' | |
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER | |
# Allowed image extensions | |
ALLOWED_EXTENSIONS = {'jpg', 'jpeg', 'png', 'gif'} | |
# Function to check if a filename has an allowed extension | |
def allowed_file(filename): | |
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS | |
# Route to display the upload form and select an image directory | |
@app.route('/', methods=['GET',]) | |
def upload_form(): | |
# List available image directories | |
image_directories = get_image_directories() | |
image_directories = sorted(image_directories) | |
logger.debug('Image directories: %s', image_directories) | |
video2 = "static/output/generated_video.mp4" | |
return render_template('dir_tovideo.html', image_directories=image_directories, video2=video2) | |
# Route to display the upload form and select an image directory | |
@app.route('/upload_zoom', methods=['GET',]) | |
def upload_zoom(): | |
# List available image directories | |
image_directories = get_image_directories() | |
image_directories = sorted(image_directories) | |
logger.debug('Image directories: %s', image_directories) | |
video2 = "static/output/generated_video.mp4" | |
return render_template('dir_tozoom.html', image_directories=image_directories, video2=video2) | |
# @codeing4me1948 | |
# Route to handle image directory selection and video generation | |
# Function to get a list of image directories | |
def get_image_directories(): | |
image_dir = glob.glob("static/images/*") | |
image_dir = sorted(image_dir) | |
return image_dir | |
@app.route('/image_dir_to_zoom', methods=['POST','GET']) | |
def image_dir_to_zoom(): | |
image_directories = get_image_directories() | |
print("IMAGE_DIRECTORIES: %s",image_directories) | |
image_directories = sorted(image_directories) | |
#print(image_directories) | |
# Display the form again and show an error message | |
try: | |
selected_directory = request.form.get('selected_directory') | |
logger.debug('Selected image directory: %s', selected_directory) | |
# List image files in the selected directory | |
image_files = glob.glob(os.path.join(selected_directory, '*.jpg')) | |
SIZE =Image.open(image_files[0]).size | |
print(SIZE) | |
print("SIZE[0]:SIZE[1]",SIZE[0],SIZE[1]) | |
# Modify the extension as needed | |
random.shuffle(image_files) | |
logger.debug('Image files: %s', image_files) | |
if not image_files: | |
flash('No image files found in the selected directory.') | |
return redirect(request.url) | |
# Specify the output video file path | |
output_video = os.path.join('static', 'output', 'generated_video.mp4') | |
# Frame rate for the output video (adjust as needed) | |
frame_rate = 60 # Adjust the frame rate as needed | |
# Initialize the FFmpeg command | |
ffmpeg_cmd = [ | |
'ffmpeg', | |
'-framerate', str(frame_rate), | |
'-i', os.path.join(selected_directory, '%05d.jpg'), # Modify the format if necessary | |
] | |
width = SIZE[0] | |
height = SIZE[1] | |
# Adjust these parameters as needed | |
zoom_increment = 0.0005 | |
zoom_duration = 300 # Increase for a longer zoom duration | |
frame_rate = 60 # Increase the frame rate | |
ffmpeg_cmd += [ | |
'-vf', f"scale=8000:-1,zoompan=z='min(zoom+{zoom_increment},1.5)':x='iw/2':y='ih/2-4000':d={zoom_duration}:s={width}x{height},crop={width}:{height}:0:256", | |
'-c:v', 'libx264', | |
'-pix_fmt', 'yuv420p', | |
'-r', str(frame_rate), # Adjust the frame rate here | |
'-s', f'{width}x{height}', | |
'-y', # Overwrite output file if it exists | |
output_video, | |
] | |
logger.debug('FFmpeg command: %s', ffmpeg_cmd) | |
# Run the FFmpeg command to generate the video | |
subprocess.run(ffmpeg_cmd) | |
logger.debug('Video created: %s', output_video) | |
shutil.copy(output_video, 'static/assets') | |
# mp4 video name generated with uuid | |
video_name = str(uuid.uuid4()) + '_zoomed.mp4' | |
shutil.copy('static/assets/generated_video.mp4', os.path.join('static/assets', video_name)) | |
# Now, render the HTML template and pass the context variables | |
output_vid = os.path.join('assets', 'generated_video.mp4') | |
return render_template('dir_tozoom.html', image_directories=image_directories, video2=output_vid) | |
except Exception as e: | |
output_video = os.path.join('output', 'generated_video.mp4') | |
logger.exception('Error occurred during image directory to zoomed video conversion: %s', str(e)) | |
return render_template('dir_tozoom.html', image_directories=image_directories, video2=output_video) | |
# Route to handle image directory selection and video generation | |
@app.route('/image_dir_to_video', methods=['POST']) | |
def image_dir_to_video(): | |
try: | |
selected_directory = request.form.get('selected_directory') | |
logger.debug('Selected image directory: %s', selected_directory) | |
# List image files in the selected directory | |
image_files = glob.glob(os.path.join(selected_directory, '*.jpg')) # Modify the extension as needed | |
logger.debug('Image files: %s', image_files) | |
if not image_files: | |
flash('No image files found in the selected directory.') | |
return redirect(request.url) | |
# Specify the output video file path | |
output_video = os.path.join('static', 'output', 'generated_video.mp4') | |
# Frame rate for the output video (adjust as needed) | |
frame_rate = 1 | |
# Initialize the FFmpeg command | |
ffmpeg_cmd = [ | |
'ffmpeg', | |
'-pattern_type', 'glob', | |
'-framerate', str(frame_rate), | |
'-i', os.path.join(selected_directory, '*.jpg'), | |
] | |
# Output video settings | |
ffmpeg_cmd += [ | |
'-c:v', 'libx264', | |
'-pix_fmt', 'yuv420p', | |
'-r', '20', | |
'-y', # Overwrite output file if it exists | |
output_video, | |
] | |
# Run the FFmpeg command to generate the video | |
subprocess.run(ffmpeg_cmd) | |
logger.debug('Video created: %s', output_video) | |
shutil.copy(output_video, 'static/assets') | |
# mp4 video name generated with uuid | |
video_name = str(uuid.uuid4()) + 'framed.mp4' | |
shutil.move('static/assets/generated_video.mp4', 'static/assets/' + video_name) | |
return redirect(url_for('download_video', filename='generated_video.mp4')) | |
except Exception as e: | |
logger.exception('Error occurred during image directory to video conversion: %s', str(e)) | |
return "An error occurred during image directory to video conversion." | |
# Route to download the generated video | |
@app.route('/download_video/<filename>') | |
def download_video(filename): | |
return redirect(url_for('static', filename=f'output/{filename}')) | |
if __name__ == '__main__': | |
app.run(debug=True, port="5000") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment