File size: 6,985 Bytes
f3da3f2
9de7e25
 
fc7fdb7
9de7e25
d81f996
 
fc7fdb7
c08ff30
 
 
 
 
9de7e25
f3da3f2
 
9de7e25
9482f0d
 
6d31a4f
9482f0d
8be4c85
a47481d
fc7fdb7
 
c08ff30
6d31a4f
 
 
fc7fdb7
 
8be4c85
 
 
 
 
 
 
 
6d31a4f
 
8be4c85
 
d2cdcd3
8be4c85
2ceb823
8be4c85
 
 
 
 
 
 
 
 
 
9de7e25
 
8be4c85
 
 
6d31a4f
 
8be4c85
 
 
6d31a4f
 
8be4c85
 
 
6d31a4f
 
 
 
 
8be4c85
 
6d31a4f
8be4c85
 
 
 
 
6d31a4f
8be4c85
6d31a4f
8be4c85
6d31a4f
 
 
 
 
9de7e25
 
 
f3da3f2
 
 
 
8be4c85
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2ceb823
8be4c85
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9de7e25
 
6d31a4f
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
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
supported_formats = [data.upper() for data in (sorted(['3GP', 'ASF', 'AVI', 'DIVX', 'FLV', 'M2TS', 'M4V', 'MKV', 'MOV', 'MP4', 'MPEG', 'MPG', 'MTS', 'TS', 'VOB', 'WEBM', 'WMV', 'XVID'])) if data not in ['3GP', 'DIVX', 'XVID']]
audio_formats = [data.upper() for data in (sorted(['MP3', 'WAV', 'AAC', 'FLAC', 'OGG', 'M4A', 'ALAC', 'WMA', 'AIFF', 'OPUS', 'APE', 'CAF', 'PCM', 'DTS', 'TTA', 'AMR', 'MID', 'SPX', 'WV', 'RA', 'TAK'])) if data not in ['ALC', 'AMR', 'APE', 'DTS', 'MID', 'PCM', 'RA', 'TAK']]
gif_formats = ['GIF']
image_formats = [data.upper() for data in sorted(Image.SAVE.keys() or ['BLP', 'BMP', 'BUFR', 'DDS', 'DIB', 'EPS', 'GIF', 'GRIB', 'HDF5', 'ICNS', 'ICO', 'IM',
                                              'JPEG', 'JPEG2000', 'MPO', 'MSP', 'PALM', 'PCX', 'PDF', 'PNG', 'PPM', 'SGI', 'SPIDER', 
                                              'TGA', 'TIFF', 'WEBP', 'WMX', 'XBM'])]

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 clean_cache():
    """Remove files in the cache directory older than 15 minutes."""
    now = time.time()
    for file in os.listdir(CACHE_DIR):
        file_path = os.path.join(CACHE_DIR, file)
        if os.path.isfile(file_path) and now - os.path.getmtime(file_path) > 900:  # 15 minutes
            os.remove(file_path)

def get_video_duration(video_path):
    """Get video duration in seconds using ffmpeg."""
    probe = ffmpeg.probe(video_path, v='error', select_streams='v:0', show_entries='stream=duration')
    return float(probe['streams'][0]['duration'])

def convert_video(video, target_format, conversion_type, time_in_seconds=None):
    try:
        # Create a temporary directory for the uploaded file
        temp_dir = tempfile.mkdtemp()

        # Sanitize the filename and save the uploaded video to the temp directory
        base_name = os.path.splitext(os.path.basename(video.name))[0]
        sanitized_base_name = sanitize_filename(base_name)
        video_path = os.path.join(temp_dir, f"{sanitized_base_name}.mp4")  # Saving as mp4 by default for now

        with open(video_path, "wb") as f:
            f.write(video.getbuffer())  # Save the uploaded video to a local file

        if conversion_type == 'Video to Video':
            output_file = f"flowly_ai_video_converter_{sanitized_base_name}.{target_format.lower()}"
            ffmpeg.input(video_path).output(output_file).overwrite_output().run()  # Add .overwrite_output()
            return output_file

        elif conversion_type == 'Video to Audio':
            audio_output_file = f"flowly_ai_video_to_audio_{sanitized_base_name}.{target_format.lower()}"
            ffmpeg.input(video_path).output(audio_output_file).overwrite_output().run()  # Add .overwrite_output()
            return audio_output_file

        elif conversion_type == 'Video to GIF':
            gif_output_file = f"flowly_ai_video_to_gif_{sanitized_base_name}.gif"
            ffmpeg.input(video_path).output(gif_output_file, vf="fps=10,scale=320:-1:flags=lanczos").overwrite_output().run()  # Add .overwrite_output()
            return gif_output_file

        elif conversion_type == 'Video to Image':
            if time_in_seconds is None:
                return "Please specify a valid time in seconds for image extraction."

            image_output_file = f"flowly_ai_video_to_image_{sanitized_base_name}_{time_in_seconds}.png"
            ffmpeg.input(video_path, ss=time_in_seconds).output(image_output_file, vframes=1).overwrite_output().run()  # Add .overwrite_output()

            return image_output_file

    except Exception as e:
        return f"Error: {e}"
        
def update_format_choices(conversion_type):
    """Update available format choices based on the conversion type."""
    if conversion_type == 'Video to Video':
        return supported_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.")

    # Create two columns
    col1, col2 = st.columns([1, 1])

    with col1:
        # Upload video file
        video_file = st.file_uploader("Upload a Video", type=supported_formats)
        if video_file:
            st.video(video_file)

    with col2:
        if video_file:
            # Save uploaded video to cache
            temp_video_path = os.path.join(CACHE_DIR, video_file.name)
            with open(temp_video_path, "wb") as f:
                f.write(video_file.getbuffer())

            # Get video duration
            video_duration = get_video_duration(temp_video_path)

            # Select conversion type
            conversion_type = st.selectbox(
                "Select Conversion Type", 
                ['Video to Video', 'Video to Audio', 'Video to GIF', 'Video to Image']
            )

            # Update format choices based on conversion type
            target_format_choices = update_format_choices(conversion_type)
            target_format = st.selectbox("Select Target Format", target_format_choices)

            # If 'Video to Image' conversion, ask for time in seconds
            if conversion_type == 'Video to Image':
                time_in_seconds = st.slider(
                    label="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(video_file, target_format, conversion_type, time_in_seconds)

                    if "Error" in output_file:
                        st.error(output_file)
                    else:
                        st.success("Conversion Successful! Download the file:")
                        st.download_button(
                            label="Download Converted File", 
                            data=open(output_file, 'rb').read(), 
                            file_name=os.path.basename(output_file)
                        )

if __name__ == "__main__":
    main()