Skip to content

Instantly share code, notes, and snippets.

@JupyterJones
Created October 1, 2023 16:31
Show Gist options
  • Save JupyterJones/13ed280dafd5d8a4f31096d6ec8f9c4c to your computer and use it in GitHub Desktop.
Save JupyterJones/13ed280dafd5d8a4f31096d6ec8f9c4c to your computer and use it in GitHub Desktop.
Flask Zoom and Image to video
#!/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