import streamlit as st import ffmpeg import os import time from PIL import Image import re import tempfile import shutil import threading def delete_temp_dir(directory, delay=900): # 15 minutes = 900 seconds timer = threading.Timer(delay, shutil.rmtree, [directory]) timer.start() st.set_page_config(layout="wide", page_title="Video Conversion Tool") # Supported formats video_formats = ['3GP', 'ASF', 'AVI', 'FLV', 'M4V', 'MKV', 'MOV', 'MP4', 'MPEG', 'MPG', 'TS', 'WEBM', 'WMV'] audio_formats = ['MP3', 'WAV', 'AAC', 'FLAC', 'OGG', 'M4A'] gif_formats = ['GIF'] image_formats = ['JPEG', 'PNG', 'BMP', 'TIFF'] CACHE_DIR = tempfile.mkdtemp() delete_temp_dir(CACHE_DIR, delay=900) # Clean up cache after 15 minutes def sanitize_filename(filename): """Sanitize filename by removing special characters and spaces.""" return re.sub(r'[^a-zA-Z0-9_.-]', '_', filename) def get_video_duration(video_path): """Get video duration in seconds using ffmpeg.""" try: probe = ffmpeg.probe(video_path) duration = float(probe['streams'][0]['duration']) return duration except Exception as e: st.error(f"Error getting video duration: {e}") return 0 def convert_video(video_path, target_format, conversion_type, time_in_seconds=None): try: # Sanitize the filename sanitized_base_name = sanitize_filename(os.path.splitext(os.path.basename(video_path))[0]) output_file = None if conversion_type == 'Video to Video': output_file = os.path.join(CACHE_DIR, f"{sanitized_base_name}.{target_format.lower()}") ffmpeg.input(video_path).output(output_file).overwrite_output().run() elif conversion_type == 'Video to Audio': output_file = os.path.join(CACHE_DIR, f"{sanitized_base_name}.{target_format.lower()}") ffmpeg.input(video_path).output(output_file, audio_bitrate='192k').overwrite_output().run() elif conversion_type == 'Video to GIF': output_file = os.path.join(CACHE_DIR, f"{sanitized_base_name}.gif") ffmpeg.input(video_path).output(output_file, vf="fps=10,scale=320:-1").overwrite_output().run() elif conversion_type == 'Video to Image': if time_in_seconds is None: return "Please specify a valid time in seconds for image extraction." output_file = os.path.join(CACHE_DIR, f"{sanitized_base_name}_{time_in_seconds}.png") ffmpeg.input(video_path, ss=time_in_seconds).output(output_file, vframes=1).overwrite_output().run() return output_file except Exception as e: return f"Error during conversion: {e}" def update_format_choices(conversion_type): if conversion_type == 'Video to Video': return video_formats elif conversion_type == 'Video to Audio': return audio_formats elif conversion_type == 'Video to GIF': return gif_formats elif conversion_type == 'Video to Image': return image_formats return [] def main(): st.title("Video Conversion Tool") st.write("Convert videos to audio, GIFs, images, or other formats easily with this powerful tool.") video_file = st.file_uploader("Upload a Video", type=video_formats) if video_file: temp_video_path = os.path.join(CACHE_DIR, sanitize_filename(video_file.name)) with open(temp_video_path, "wb") as f: f.write(video_file.getbuffer()) st.video(temp_video_path) video_duration = get_video_duration(temp_video_path) conversion_type = st.selectbox( "Select Conversion Type", ['Video to Video', 'Video to Audio', 'Video to GIF', 'Video to Image'] ) target_format_choices = update_format_choices(conversion_type) target_format = st.selectbox("Select Target Format", target_format_choices) if conversion_type == 'Video to Image': time_in_seconds = st.slider( "Time (in seconds) for image extraction", min_value=0, max_value=int(video_duration), value=0, step=1 ) else: time_in_seconds = None if st.button("Convert"): with st.spinner("Converting..."): output_file = convert_video(temp_video_path, target_format, conversion_type, time_in_seconds) if "Error" in output_file: st.error(output_file) else: st.success("Conversion Successful! Download the file:") with open(output_file, 'rb') as f: st.download_button("Download", f.read(), os.path.basename(output_file)) if __name__ == "__main__": main()