File size: 4,157 Bytes
a804d89
 
 
 
1903c80
a804d89
0f146e7
329ed22
 
0f146e7
329ed22
 
0f146e7
329ed22
 
 
 
0f146e7
329ed22
0f146e7
329ed22
 
0f146e7
329ed22
 
 
0f146e7
 
329ed22
0f146e7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
329ed22
 
 
 
0f146e7
329ed22
 
0f146e7
329ed22
 
 
1903c80
329ed22
1903c80
 
 
 
a804d89
 
 
 
 
329ed22
a804d89
 
 
 
 
 
 
b466991
 
a804d89
1903c80
 
 
 
 
 
 
 
 
 
329ed22
1903c80
 
 
329ed22
1903c80
 
 
 
 
 
 
 
 
 
329ed22
1903c80
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a804d89
392f7dd
a804d89
 
0f146e7
a804d89
 
329ed22
a804d89
 
 
 
 
 
 
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
import streamlit as st
import tempfile
import subprocess
import os
import re

# Page settings
st.set_page_config(page_title="Video Speed Tool", layout="centered")

# CSS styling for mobile
st.markdown("""
    <style>
    /* Center title */
    .title-center {
        text-align: center;
        font-size: 1.8em;
        font-weight: bold;
        margin-bottom: 20px;
    }
    /* Center all buttons */
    div.stButton > button {
        font-weight: bold;
        width: 80%;
        border-radius: 8px;
        padding: 10px 0;
        font-size: 1.1em;
        display: block;
        margin: 0 auto;
    }
    /* Center download button */
    div.stDownloadButton > button {
        font-weight: bold;
        width: 80%;
        border-radius: 8px;
        padding: 10px 0;
        font-size: 1.1em;
        display: block;
        margin: 0 auto;
    }
    /* Bigger + and - buttons in number input */
    div[data-baseweb="input"] button {
        width: 40px !important;
        height: 40px !important;
        font-size: 1.2em !important;
    }
    </style>
""", unsafe_allow_html=True)

# Title
st.markdown('<p class="title-center">🎬 Video Speed Tool</p>', unsafe_allow_html=True)

# Upload file
uploaded_file = st.file_uploader("Upload video", type=["mp4", "mov", "avi", "mkv"])

# Speed input
speed = st.number_input(
    "Speed (0.25x - 4x)",
    min_value=0.25,
    max_value=4.0,
    value=1.5,
    step=0.05
)

if uploaded_file is not None:
    st.video(uploaded_file)

    if st.button("PROCESS VIDEO"):
        with st.spinner("Processing... Please wait"):
            with tempfile.NamedTemporaryFile(delete=False, suffix=".mp4") as tmp_input:
                tmp_input.write(uploaded_file.read())
                input_path = tmp_input.name

            output_path = tempfile.NamedTemporaryFile(delete=False, suffix=".mp4").name

            video_speed = 1 / speed
            audio_speed = speed

            # Always compress
            cmd = [
                "ffmpeg", "-i", input_path,
                "-filter_complex", f"[0:v]setpts={video_speed}*PTS[v];[0:a]atempo={audio_speed}[a]",
                "-map", "[v]", "-map", "[a]",
                "-vcodec", "libx264", "-crf", "28", "-preset", "fast",
                "-movflags", "+faststart",
                "-y", output_path
            ]

            # Progress bar
            progress_text = st.empty()
            progress_bar = st.progress(0)

            # Get video duration
            probe = subprocess.run(
                ["ffprobe", "-v", "error", "-show_entries", "format=duration",
                 "-of", "default=noprint_wrappers=1:nokey=1", input_path],
                stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True
            )
            try:
                total_duration = float(probe.stdout.strip())
            except:
                total_duration = None

            # Run ffmpeg with live progress
            process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, bufsize=1)

            for line in process.stdout:
                if "time=" in line and total_duration:
                    match = re.search(r"time=(\d+:\d+:\d+\.\d+)", line)
                    if match:
                        h, m, s = match.group(1).split(":")
                        elapsed = int(h) * 3600 + int(m) * 60 + float(s)
                        percent = min(int((elapsed / total_duration) * 100), 100)
                        progress_bar.progress(percent)
                        progress_text.text(f"Processing... {percent}%")

            process.wait()
            progress_bar.progress(100)
            progress_text.text("βœ… Processing complete!")

            # Show processed video
            st.video(output_path)

            # Download button centered
            with open(output_path, "rb") as f:
                st.download_button(
                    label="DOWNLOAD VIDEO",
                    data=f,
                    file_name="processed_video.mp4",
                    mime="video/mp4"
                )

            os.remove(input_path)
            os.remove(output_path)