Spaces:
Sleeping
Sleeping
Update app.py from anycoder
Browse files
app.py
CHANGED
|
@@ -3,7 +3,7 @@ import subprocess
|
|
| 3 |
import os
|
| 4 |
from pathlib import Path
|
| 5 |
import tempfile
|
| 6 |
-
import
|
| 7 |
|
| 8 |
# Comprehensive format support
|
| 9 |
VIDEO_FORMATS = [
|
|
@@ -30,48 +30,52 @@ ALL_FORMATS = sorted(set(VIDEO_FORMATS + AUDIO_FORMATS + IMAGE_FORMATS + DOCUMEN
|
|
| 30 |
def get_file_info(file_path):
|
| 31 |
"""Get detailed information about the uploaded file."""
|
| 32 |
if not file_path:
|
| 33 |
-
return "
|
| 34 |
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
|
|
|
| 41 |
π **File Information**
|
| 42 |
- **Name:** {Path(file_path).name}
|
| 43 |
- **Format:** {file_ext.upper()}
|
| 44 |
- **Size:** {size_mb:.2f} MB
|
| 45 |
-
- **Path:** {file_path}
|
| 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 |
def convert_media(input_file, output_format, quality="high", resolution=None):
|
| 77 |
"""
|
|
@@ -133,6 +137,11 @@ def convert_media(input_file, output_format, quality="high", resolution=None):
|
|
| 133 |
cmd.extend(["-codec:v", "libvpx-vp9", "-codec:a", "libopus"])
|
| 134 |
elif output_format == "mp4":
|
| 135 |
cmd.extend(["-codec:v", "libx264", "-codec:a", "aac"])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 136 |
|
| 137 |
cmd.append(output_file)
|
| 138 |
|
|
@@ -151,7 +160,8 @@ def convert_media(input_file, output_format, quality="high", resolution=None):
|
|
| 151 |
if not os.path.exists(output_file) or os.path.getsize(output_file) == 0:
|
| 152 |
raise Exception("Conversion produced empty file")
|
| 153 |
|
| 154 |
-
|
|
|
|
| 155 |
|
| 156 |
except subprocess.TimeoutExpired:
|
| 157 |
if os.path.exists(output_file):
|
|
@@ -171,11 +181,11 @@ def update_format_suggestions(input_file):
|
|
| 171 |
|
| 172 |
# Suggest related formats
|
| 173 |
if file_ext in VIDEO_FORMATS:
|
| 174 |
-
suggested = ["mp4", "webm", "avi", "mkv", "mov"]
|
| 175 |
elif file_ext in AUDIO_FORMATS:
|
| 176 |
-
suggested = ["mp3", "wav", "aac", "flac", "ogg"]
|
| 177 |
elif file_ext in IMAGE_FORMATS:
|
| 178 |
-
suggested = ["jpg", "png", "webp", "gif", "bmp"]
|
| 179 |
else:
|
| 180 |
suggested = ["mp4", "mp3", "jpg", "png"]
|
| 181 |
|
|
@@ -251,6 +261,20 @@ footer {
|
|
| 251 |
font-size: 0.875rem;
|
| 252 |
margin: 0.25rem;
|
| 253 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 254 |
"""
|
| 255 |
|
| 256 |
# Build the Gradio interface
|
|
@@ -276,7 +300,7 @@ with gr.Blocks(fill_height=True) as demo:
|
|
| 276 |
)
|
| 277 |
|
| 278 |
file_info = gr.Markdown(
|
| 279 |
-
value="*Upload a file to see details*",
|
| 280 |
elem_classes="info-box"
|
| 281 |
)
|
| 282 |
|
|
@@ -345,24 +369,22 @@ with gr.Blocks(fill_height=True) as demo:
|
|
| 345 |
### β¨ Features
|
| 346 |
|
| 347 |
- π― 60+ format support
|
| 348 |
-
- π¨ Quality control
|
| 349 |
-
- π Resolution options
|
| 350 |
-
- β‘ Fast conversion
|
| 351 |
-
- πΎ
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 352 |
""")
|
| 353 |
|
| 354 |
-
# Examples section
|
| 355 |
-
gr.Markdown("### π‘ Quick Examples")
|
| 356 |
-
gr.Examples(
|
| 357 |
-
examples=[
|
| 358 |
-
["example.mp4", "webm", "high"],
|
| 359 |
-
["example.mp3", "wav", "high"],
|
| 360 |
-
["example.jpg", "png", "high"],
|
| 361 |
-
],
|
| 362 |
-
inputs=[input_file, output_format, quality],
|
| 363 |
-
label="Try these examples (files will be created if needed)"
|
| 364 |
-
)
|
| 365 |
-
|
| 366 |
# Event handlers
|
| 367 |
input_file.change(
|
| 368 |
fn=get_file_info,
|
|
|
|
| 3 |
import os
|
| 4 |
from pathlib import Path
|
| 5 |
import tempfile
|
| 6 |
+
import json
|
| 7 |
|
| 8 |
# Comprehensive format support
|
| 9 |
VIDEO_FORMATS = [
|
|
|
|
| 30 |
def get_file_info(file_path):
|
| 31 |
"""Get detailed information about the uploaded file."""
|
| 32 |
if not file_path:
|
| 33 |
+
return "π *Upload a file to see details*"
|
| 34 |
|
| 35 |
+
try:
|
| 36 |
+
file_size = os.path.getsize(file_path)
|
| 37 |
+
file_ext = Path(file_path).suffix.lower().replace(".", "")
|
| 38 |
+
|
| 39 |
+
size_mb = file_size / (1024 * 1024)
|
| 40 |
+
|
| 41 |
+
info = f"""
|
| 42 |
π **File Information**
|
| 43 |
- **Name:** {Path(file_path).name}
|
| 44 |
- **Format:** {file_ext.upper()}
|
| 45 |
- **Size:** {size_mb:.2f} MB
|
|
|
|
| 46 |
"""
|
| 47 |
+
|
| 48 |
+
# Try to get media info using ffprobe
|
| 49 |
+
try:
|
| 50 |
+
result = subprocess.run(
|
| 51 |
+
["ffprobe", "-v", "quiet", "-print_format", "json", "-show_format", "-show_streams", file_path],
|
| 52 |
+
capture_output=True,
|
| 53 |
+
text=True,
|
| 54 |
+
timeout=10
|
| 55 |
+
)
|
| 56 |
+
if result.returncode == 0:
|
| 57 |
+
data = json.loads(result.stdout)
|
| 58 |
+
if "format" in data:
|
| 59 |
+
duration = data["format"].get("duration", "N/A")
|
| 60 |
+
if duration != "N/A":
|
| 61 |
+
info += f"\n- **Duration:** {float(duration):.2f} seconds"
|
| 62 |
+
if "streams" in data:
|
| 63 |
+
for stream in data["streams"]:
|
| 64 |
+
if stream["codec_type"] == "video":
|
| 65 |
+
info += f"\n- **Video Codec:** {stream.get('codec_name', 'N/A')}"
|
| 66 |
+
info += f"\n- **Resolution:** {stream.get('width', 'N/A')}x{stream.get('height', 'N/A')}"
|
| 67 |
+
break
|
| 68 |
+
for stream in data["streams"]:
|
| 69 |
+
if stream["codec_type"] == "audio":
|
| 70 |
+
info += f"\n- **Audio Codec:** {stream.get('codec_name', 'N/A')}"
|
| 71 |
+
info += f"\n- **Sample Rate:** {stream.get('sample_rate', 'N/A')} Hz"
|
| 72 |
+
break
|
| 73 |
+
except Exception as e:
|
| 74 |
+
info += f"\n\n*Could not retrieve detailed media info*"
|
| 75 |
+
|
| 76 |
+
return info
|
| 77 |
+
except Exception as e:
|
| 78 |
+
return f"β Error reading file: {str(e)}"
|
| 79 |
|
| 80 |
def convert_media(input_file, output_format, quality="high", resolution=None):
|
| 81 |
"""
|
|
|
|
| 137 |
cmd.extend(["-codec:v", "libvpx-vp9", "-codec:a", "libopus"])
|
| 138 |
elif output_format == "mp4":
|
| 139 |
cmd.extend(["-codec:v", "libx264", "-codec:a", "aac"])
|
| 140 |
+
elif output_format == "wav":
|
| 141 |
+
cmd.extend(["-codec:a", "pcm_s16le"])
|
| 142 |
+
elif output_format in IMAGE_FORMATS:
|
| 143 |
+
# For image conversion, just specify format
|
| 144 |
+
pass
|
| 145 |
|
| 146 |
cmd.append(output_file)
|
| 147 |
|
|
|
|
| 160 |
if not os.path.exists(output_file) or os.path.getsize(output_file) == 0:
|
| 161 |
raise Exception("Conversion produced empty file")
|
| 162 |
|
| 163 |
+
output_size = os.path.getsize(output_file) / (1024 * 1024)
|
| 164 |
+
return output_file, f"β
**Conversion Successful!**\n\nConverted to **{output_format.upper()}** format with **{quality}** quality.\n\nπ¦ Output size: **{output_size:.2f} MB**"
|
| 165 |
|
| 166 |
except subprocess.TimeoutExpired:
|
| 167 |
if os.path.exists(output_file):
|
|
|
|
| 181 |
|
| 182 |
# Suggest related formats
|
| 183 |
if file_ext in VIDEO_FORMATS:
|
| 184 |
+
suggested = ["mp4", "webm", "avi", "mkv", "mov", "gif"]
|
| 185 |
elif file_ext in AUDIO_FORMATS:
|
| 186 |
+
suggested = ["mp3", "wav", "aac", "flac", "ogg", "m4a"]
|
| 187 |
elif file_ext in IMAGE_FORMATS:
|
| 188 |
+
suggested = ["jpg", "png", "webp", "gif", "bmp", "tiff"]
|
| 189 |
else:
|
| 190 |
suggested = ["mp4", "mp3", "jpg", "png"]
|
| 191 |
|
|
|
|
| 261 |
font-size: 0.875rem;
|
| 262 |
margin: 0.25rem;
|
| 263 |
}
|
| 264 |
+
|
| 265 |
+
.feature-grid {
|
| 266 |
+
display: grid;
|
| 267 |
+
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
| 268 |
+
gap: 1rem;
|
| 269 |
+
margin: 1rem 0;
|
| 270 |
+
}
|
| 271 |
+
|
| 272 |
+
.feature-item {
|
| 273 |
+
background: rgba(102, 126, 234, 0.1);
|
| 274 |
+
padding: 1rem;
|
| 275 |
+
border-radius: 8px;
|
| 276 |
+
text-align: center;
|
| 277 |
+
}
|
| 278 |
"""
|
| 279 |
|
| 280 |
# Build the Gradio interface
|
|
|
|
| 300 |
)
|
| 301 |
|
| 302 |
file_info = gr.Markdown(
|
| 303 |
+
value="π *Upload a file to see details*",
|
| 304 |
elem_classes="info-box"
|
| 305 |
)
|
| 306 |
|
|
|
|
| 369 |
### β¨ Features
|
| 370 |
|
| 371 |
- π― 60+ format support
|
| 372 |
+
- π¨ Quality control (high/medium/low)
|
| 373 |
+
- π Resolution options for video
|
| 374 |
+
- β‘ Fast conversion with FFmpeg
|
| 375 |
+
- πΎ Detailed file info analysis
|
| 376 |
+
- π Smart format suggestions
|
| 377 |
+
- π Output size reporting
|
| 378 |
+
|
| 379 |
+
### π How to Use
|
| 380 |
+
|
| 381 |
+
1. **Upload** your media file
|
| 382 |
+
2. **Select** output format (auto-suggested)
|
| 383 |
+
3. **Choose** quality level
|
| 384 |
+
4. **Click** Convert Media button
|
| 385 |
+
5. **Download** your converted file
|
| 386 |
""")
|
| 387 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 388 |
# Event handlers
|
| 389 |
input_file.change(
|
| 390 |
fn=get_file_info,
|