import gradio as gr import os import uuid from pydub import AudioSegment from pydub.silence import split_on_silence import re import click # --- LOGIC SECTION (SAME) --- def clean_file_name(file_path): file_name = os.path.basename(file_path) file_name, file_extension = os.path.splitext(file_name) cleaned = re.sub(r'[^a-zA-Z\d]+', '_', file_name) clean_file_name = re.sub(r'_+', '_', cleaned).strip('_') random_uuid = uuid.uuid4().hex[:6] clean_file_path = os.path.join(os.path.dirname(file_path), clean_file_name + f"_{random_uuid}" + file_extension) return clean_file_path def remove_silence(file_path, minimum_silence=50): sound = AudioSegment.from_file(file_path) audio_chunks = split_on_silence(sound, min_silence_len=100, silence_thresh=-45, keep_silence=minimum_silence) combined = AudioSegment.empty() for chunk in audio_chunks: combined += chunk output_path = clean_file_name(file_path) combined.export(output_path) return output_path def calculate_duration(file_path): audio = AudioSegment.from_file(file_path) return len(audio) / 1000.0 def process_audio(audio_file, seconds=0.05): if not audio_file: return None, None, "⚠️ Please upload a file first." keep_silence = int(seconds * 1000) output_audio_file = remove_silence(audio_file, minimum_silence=keep_silence) before = calculate_duration(audio_file) after = calculate_duration(output_audio_file) text = f"⏱️ Old: {before:.2f}s | ✅ New: {after:.2f}s | 🚀 Saved: {before-after:.2f}s" return output_audio_file, output_audio_file, text def reset_interface(): return None, 0.05, None, None, "" # --- NEW MOBILE-OPTIMIZED UI --- def ui(): # Clean Modern Font Theme theme = gr.themes.Soft( primary_hue="cyan", secondary_hue="slate", font=[gr.themes.GoogleFont("Poppins"), "sans-serif"], # Changed to Poppins (Cleaner) ).set( body_background_fill="#050505", block_background_fill="#121212", block_border_width="0px", input_background_fill="#1a1a1a" ) css = """ /* MOBILE FIX: Container width 100% karega */ .gradio-container { width: 100% !important; max-width: 100% !important; padding: 10px !important; margin: 0 !important; overflow-x: hidden; } /* Font Change */ * { font-family: 'Poppins', sans-serif !important; } /* RGB Animation */ @keyframes rgb-flow { 0% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } 100% { background-position: 0% 50%; } } /* Title Styling - Mobile Friendly */ .rgb-text { background: linear-gradient(45deg, #ff0000, #00ffd5, #002bff, #ff00c8); background-size: 300%; -webkit-background-clip: text; -webkit-text-fill-color: transparent; font-weight: 800; font-size: 2rem; /* Thoda chota kiya mobile ke liye */ text-align: center; animation: rgb-flow 8s linear infinite; margin-bottom: 5px; line-height: 1.2; } .subtitle { text-align: center; color: #888; font-size: 0.9rem; margin-bottom: 15px; } /* Card Styling */ .rgb-card { background: #111; border-radius: 15px; padding: 2px; /* Border patla kiya */ margin-bottom: 10px; position: relative; } .rgb-card::before { content: ""; position: absolute; inset: 0; z-index: -1; background: linear-gradient(45deg, #ff0000, #00ffd5, #002bff, #ff00c8); background-size: 400%; border-radius: 15px; animation: rgb-flow 15s linear infinite; opacity: 0.6; } .inner-card { background: #0a0a0a; border-radius: 13px; padding: 15px; } /* Button Styling */ .process-btn { background: linear-gradient(90deg, #00c6ff 0%, #0072ff 100%) !important; color: white !important; font-weight: 600 !important; border: none !important; box-shadow: 0 4px 15px rgba(0, 114, 255, 0.3); } .reset-btn { background: #ff0055 !important; color: white !important; border: none !important; } /* Stats Box Text Fix */ .stat-box textarea { background-color: #000 !important; color: #00ff88 !important; font-family: monospace; font-size: 14px !important; } /* Mobile Specific Tweaks */ @media (max-width: 768px) { .rgb-text { font-size: 1.5rem !important; } /* Mobile pe title chota */ .inner-card { padding: 10px !important; } .process-btn, .reset-btn { width: 100%; margin-top: 5px; } /* Buttons full width */ } """ with gr.Blocks(theme=theme, css=css, title="Silence Remover Pro") as demo: gr.HTML("""