from flask import Flask, render_template, request, send_file import os import tempfile import subprocess import zipfile from waitress import serve # Initialize the Flask app, tell it to look in the current directory for templates app = Flask(__name__, template_folder='.') @app.route('/') def home(): return render_template('html.html') # Flask will look in the current directory @app.route('/process', methods=['POST']) def process_video(): video_file = request.files['video'] action = request.form['action'] copy_streams = 'copy_streams' in request.form # Check if the user selected "copy streams" # Save the uploaded video to a temporary file temp_file = tempfile.NamedTemporaryFile(delete=False) video_file.save(temp_file.name) output_path = tempfile.NamedTemporaryFile(delete=False, suffix='.mp4').name # Default output format # Process video based on action if action == 'Convert Format': selected_format = request.form['format'] output_path = tempfile.NamedTemporaryFile(delete=False, suffix=f'.{selected_format}').name # Adjust output format based on user selection if copy_streams: # If "copy streams" is selected, try to copy streams without re-encoding result = subprocess.run(['ffmpeg', '-i', temp_file.name, '-c:v', 'copy', '-c:a', 'copy', '-y', output_path], capture_output=True) if result.returncode != 0: # If copying the streams failed, re-encode the video subprocess.run(['ffmpeg', '-i', temp_file.name, '-y', output_path]) else: subprocess.run(['ffmpeg', '-i', temp_file.name, '-y', output_path]) elif action == 'Trim Video': start_time = request.form['start_time'] duration = request.form['duration'] output_path = tempfile.NamedTemporaryFile(delete=False, suffix='.mp4').name # Example output format if copy_streams: # Try to copy streams during trim operation (if selected) result = subprocess.run(['ffmpeg', '-i', temp_file.name, '-ss', start_time, '-t', duration, '-c:v', 'copy', '-c:a', 'copy', '-y', output_path], capture_output=True) if result.returncode != 0: # If copying the streams failed, re-encode the video subprocess.run(['ffmpeg', '-i', temp_file.name, '-ss', start_time, '-t', duration, '-y', output_path]) else: subprocess.run(['ffmpeg', '-i', temp_file.name, '-ss', start_time, '-t', duration, '-y', output_path]) elif action == 'Resize Video': width = request.form['width'] height = request.form['height'] output_path = tempfile.NamedTemporaryFile(delete=False, suffix='.mp4').name # Example output format subprocess.run(['ffmpeg', '-i', temp_file.name, '-vf', f'scale={width}:{height}', '-y', output_path]) elif action == 'Extract Audio': output_path = tempfile.NamedTemporaryFile(delete=False, suffix='.mp3').name # Output audio in MP3 format subprocess.run(['ffmpeg', '-i', temp_file.name, '-vn', '-acodec', 'mp3', '-y', output_path]) elif action == 'Extract Frames': # Extract frames and save as .jpg files frame_dir = tempfile.mkdtemp() # Create a temporary directory to store frames output_zip = tempfile.NamedTemporaryFile(delete=False, suffix='.zip').name # Output ZIP file # Extract frames from the video (saving as JPG files) subprocess.run(['ffmpeg', '-i', temp_file.name, '-an', f'{frame_dir}/frame_%04d.jpg', '-y']) # Create a ZIP file containing the frames with zipfile.ZipFile(output_zip, 'w', zipfile.ZIP_DEFLATED) as zipf: for frame in os.listdir(frame_dir): if frame.endswith('.jpg'): zipf.write(os.path.join(frame_dir, frame), frame) # Write each frame into the ZIP # Clean up the extracted frames directory for frame in os.listdir(frame_dir): os.remove(os.path.join(frame_dir, frame)) os.rmdir(frame_dir) # Send the ZIP file containing the frames return send_file(output_zip, as_attachment=True, mimetype='application/zip') elif action == 'Change Video Speed': speed_factor = request.form['speed_factor'] output_path = tempfile.NamedTemporaryFile(delete=False, suffix='.mp4').name # Example output format subprocess.run(['ffmpeg', '-i', temp_file.name, '-filter:v', f'setpts={1/speed_factor}*PTS', '-y', output_path]) # Send the processed file back as a download (if applicable) if os.path.exists(output_path): return send_file(output_path, as_attachment=True) return 'Error processing video', 500 if __name__ == '__main__': # Run the app using waitress to serve the HTML and video processing functionality serve(app, host='0.0.0.0', port=8080)