Adityadn's picture
Update app.py
f2e306e verified
raw
history blame
4.85 kB
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 = (data for data in ['3GP', 'ASF', 'AVI', 'FLV', 'M4V', 'MKV', 'MOV', 'MP4', 'MPEG', 'MPG', 'TS', 'WEBM', 'WMV'] if data not in ['3GP', 'DIVX', 'XVID'])
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()