innoai commited on
Commit
61be4cc
·
verified ·
1 Parent(s): df77dea

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +162 -0
app.py ADDED
@@ -0,0 +1,162 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import subprocess
3
+ import os
4
+ import re
5
+
6
+ def compress_video(input_video, resolution, progress=gr.Progress()):
7
+ if not input_video:
8
+ raise gr.Error("Please upload a video file!")
9
+
10
+ output_filename = "compressed_" + os.path.basename(input_video)
11
+ output_path = os.path.join(os.path.dirname(input_video), output_filename)
12
+
13
+ try:
14
+ # Get video duration (for progress calculation)
15
+ duration_cmd = [
16
+ "ffprobe",
17
+ "-v", "error",
18
+ "-show_entries", "format=duration",
19
+ "-of", "default=noprint_wrappers=1:nokey=1",
20
+ input_video
21
+ ]
22
+ duration_output = subprocess.check_output(duration_cmd, text=True, stderr=subprocess.STDOUT)
23
+ total_duration = float(duration_output.strip())
24
+
25
+ command = [
26
+ "ffmpeg",
27
+ "-y", # Overwrite output file (if exists)
28
+ "-i", input_video,
29
+ "-vf", f"scale=-2:{resolution}",
30
+ "-c:v", "libx264",
31
+ "-crf", "28",
32
+ "-preset", "veryslow",
33
+ "-c:a", "aac",
34
+ "-b:a", "64k",
35
+ "-movflags", "+faststart",
36
+ output_path,
37
+ ]
38
+
39
+ # Use Popen to read output in real-time
40
+ process = subprocess.Popen(command, stderr=subprocess.PIPE, text=True, encoding='utf-8')
41
+ progress(0, desc="Starting compression...")
42
+
43
+ for line in process.stderr:
44
+ # Use regex to match time progress (hh:mm:ss.ss)
45
+ match = re.search(r"time=(\d+:\d+:\d+\.\d+)", line)
46
+ if match:
47
+ current_time_str = match.group(1)
48
+ # Convert time string to seconds
49
+ h, m, s = map(float, current_time_str.split(':'))
50
+ current_time = h * 3600 + m * 60 + s
51
+ # Calculate progress percentage
52
+ percentage = min(current_time / total_duration, 1.0) # Prevent exceeding 100%
53
+ progress(percentage, desc=f"Compressing: {int(percentage * 100)}%")
54
+
55
+ process.stderr.close()
56
+ return_code = process.wait()
57
+ if return_code != 0:
58
+ raise subprocess.CalledProcessError(return_code,command, process.stderr)
59
+
60
+
61
+ except subprocess.CalledProcessError as e:
62
+ error_message = e.stderr.decode('utf-8', 'ignore') # Decode and ignore errors
63
+ if "width not divisible by 2" in error_message:
64
+ error_message += "\n\nError: Video width is not divisible by 2. FFmpeg requires both width and height to be even numbers. Please try a different video or pre-process it with a video editing software."
65
+ elif "No such file or directory" in error_message:
66
+ error_message += "\n\nError: Input file or FFmpeg not found. Please check if the file path is correct and FFmpeg is installed."
67
+ elif "Permission denied" in error_message:
68
+ error_message +="\n\nError: Permission denied to access the file. Please check the file permissions."
69
+ elif "Invalid data found when processing input" in error_message:
70
+ error_message += "\n\nError: Input file is invalid or corrupted. Please check if the video file can be played correctly."
71
+ else:
72
+ error_message += "\n\nFFmpeg error output:\n" + error_message
73
+ raise gr.Error(f"Video compression failed: {error_message}")
74
+
75
+ except FileNotFoundError:
76
+ raise gr.Error("FFmpeg or ffprobe not found. Please ensure FFmpeg is installed and added to your system's PATH environment variable.")
77
+ except ValueError:
78
+ raise gr.Error("Could not retrieve video duration. Please check if the video file is valid.")
79
+ except Exception as e:
80
+ raise gr.Error("An unknown error occurred: " + str(e))
81
+
82
+ return output_path
83
+
84
+
85
+ # Gradio Interface
86
+ css = """
87
+ .container {
88
+ max-width: 800px;
89
+ margin: auto;
90
+ padding: 20px;
91
+ border: 1px solid #ddd;
92
+ border-radius: 5px;
93
+ }
94
+ h1 {
95
+ text-align: center;
96
+ color: #333;
97
+ }
98
+ .description {
99
+ text-align: center;
100
+ margin-bottom: 20px;
101
+ color: #555;
102
+ }
103
+ .instructions {
104
+ margin-top: 20px;
105
+ padding: 10px;
106
+ border: 1px dashed #aaa;
107
+ border-radius: 5px;
108
+ color: #444;
109
+ }
110
+ """
111
+
112
+ with gr.Blocks(css=css, title="Video Compressor") as demo: # English title
113
+ gr.HTML("<div class='container'>")
114
+ gr.Markdown("# Video Compressor") # English title
115
+ gr.Markdown("## Easily compress videos and save storage space!", elem_classes="description") # English description
116
+ gr.Markdown(
117
+ """
118
+ This tool uses FFmpeg to compress videos, supporting multiple resolution options. It significantly reduces video file size while maintaining clarity as much as possible.
119
+ Ideal for:
120
+ * **Saving storage space:** Reduce the disk space occupied by videos.
121
+ * **Faster upload speeds:** Compressed videos are easier to upload to the internet.
122
+ * **Optimizing web page loading:** Use smaller videos on web pages to improve page load speed.
123
+ """,
124
+ elem_classes="description"
125
+ )
126
+
127
+ with gr.Row():
128
+ with gr.Column():
129
+ input_video = gr.Video(label="Upload Video", interactive=True) # English label
130
+ resolution = gr.Dropdown(
131
+ label="Select Resolution", # English label
132
+ choices=["240", "360", "480", "720"],
133
+ value="360",
134
+ interactive=True
135
+ )
136
+ compress_button = gr.Button("Compress Video") # English label
137
+
138
+ with gr.Column():
139
+ output_video = gr.Video(label="Compressed Video", interactive=False) # English label
140
+
141
+ gr.Markdown(
142
+ """
143
+ ## Instructions
144
+ 1. **Upload Video:** Click the "Upload Video" button and select the video file you want to compress.
145
+ 2. **Select Resolution:** Choose the target resolution from the dropdown list (e.g., 360p). Smaller numbers mean smaller files and lower quality.
146
+ 3. **Compress Video:** Click the "Compress Video" button. The compression process may take some time, depending on the video size and your computer's performance.
147
+ 4. **Download Video:** Once the compression is complete, you can preview and download the compressed video below.
148
+ """,
149
+ elem_classes="instructions"
150
+ )
151
+ gr.HTML("</div>")
152
+
153
+ compress_button.click(
154
+ compress_video,
155
+ inputs=[input_video, resolution],
156
+ outputs=[output_video]
157
+ )
158
+
159
+ demo.queue(default_concurrency_limit=3)
160
+
161
+ if __name__ == "__main__":
162
+ demo.launch(show_api=False,show_error=True)