import gradio as gr import os import uuid from pydub import ...
Prompt
import gradio as gr import os import uuid from pydub import AudioSegment from pydub.silence import split_on_silence import re import time import subprocess import threading # ZeroGPU Space 启动时要求检测到至少一个 @spaces.GPU 函数。 # 这里定义一个从不调用的占位函数满足检查,实际处理全部跑在 CPU 主容器。 # 本地运行没有 spaces 包,自动跳过。 try: import spaces @spaces.GPU(duration=10) def _gpu_placeholder(): return None except ImportError: pass # gr.close_all() 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('_') if clean_file_name.endswith('_tmp'): clean_file_name = clean_file_name[:-4] random_uuid = uuid.uuid4().hex[:6] clean_file_path = os.path.join( os.path.dirname(file_path), f"{clean_file_name}_{random_uuid}{file_extension}" ) return clean_file_path def remove_silence(file_path, minimum_silence=50): sound = AudioSegment.from_file(file_path) # Try splitting with default -45 dBFS audio_chunks = split_on_silence( sound, min_silence_len=100, silence_thresh=-45, keep_silence=minimum_silence ) # If no chunks were extracted (e.g. whole file is quieter than -45dBFS) # retry with a dynamic threshold relative to the audio's actual loudness if not audio_chunks: dynamic_thresh = sound.dBFS - 16 audio_chunks = split_on_silence( sound, min_silence_len=100, silence_thresh=dynamic_thresh, keep_silence=minimum_silence ) combined = AudioSegment.empty() for chunk in audio_chunks: combined += chunk if len(combined) == 0: combined = sound output_path = clean_file_name(file_path) ext = os.path.splitext(output_path)[1].lower().replace('.', '') if not ext: ext = "wav" output_path += ".wav" combined.export(output_path, format=ext) return output_path def calculate_duration(file_path): audio = AudioSegment.from_file(file_path) duration_seconds = len(audio) / 1000.0 return duration_seconds FILE_TIMESTAMPS = {} def track_file(file_path): FILE_TIMESTAMPS[file_path] = time.time() def cleanup_tracked_files(max_age_seconds=3600): now = time.time() to_delete = [] for file_path, created_time in list(FILE_TIMESTAMPS.items()): if now - created_time > max_age_seconds: if os.path.exists(file_path): try: os.remove(file_path) print(f"🗑️ Deleted: {file_path}") except Exception as e: print(f"⚠️ Error deleting {file_path}: {e}") to_delete.append(file_path) for f in to_delete: FILE_TIMESTAMPS.pop(f, None) _CLEANUP_STARTED = False def start_cleanup_worker(interval=3600): global _CLEANUP_STARTED if _CLEANUP_STARTED: return _CLEANUP_STARTED = True def worker(): while True: cleanup_tracked_files() time.sleep(interval) threading.Thread(target=worker, daemon=True).start() def convert_to_wav(audio_path): if not os.path.isfile(audio_path): return None file_name = os.path.splitext(os.path.basename(audio_path))[0] clean_name = re.sub(r'[^a-zA-Z0-9]+', '_', file_name) clean_name = re.sub(r'_+', '_', clean_name).strip('_') wav_path = os.path.join( os.path.dirname(audio_path), f"{clean_name}_tmp.wav" ) try: subprocess.run( [ "ffmpeg", "-y", "-i", audio_path, wav_path ], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=True ) if os.path.isfile(wav_path) and os.path.getsize(wav_path) > 0: return wav_path except Exception as e: print(f"⚠️ FFmpeg conversion error: {e}") pass return None def process_audio(audio_file, seconds=0.05): if audio_file is None: return None, None, "No file uploaded" if not os.path.exists(audio_file): return None, None, "File not found" track_file(audio_file) converted_audio = convert_to_wav(audio_file) if converted_audio: track_file(converted_audio) audio_file = converted_audio else: return None, None, "Invalid file format or conversion failed" keep_silence = int(seconds * 1000) try: before = calculate_duration(audio_file) output_audio_file = remove_silence( audio_file, minimum_silence=keep_silence ) track_file(output_audio_file) after = calculate_duration(output_audio_file) text = f"Old Duration: {before:.3f} Seconds \nNew Duration: {after:.3f} Seconds" return output_audio_file, output_audio_file, text except Exception as e: print(f"⚠️ Error processing audio: {e}") return None, None, f"An error occurred during processing: {str(e)}" def ui(): theme = gr.themes.Soft( font=[gr.themes.GoogleFont("Source Sans Pro"), "Arial", "sans-serif"] ) css = """ .gradio-container {max-width: none !important;} .tab-content {padding: 20px;} /* Primary button - BLUE by default */ button.primary { background-color: #2563eb !important; color: white !important; font-weight: 600; border: none !important; border-radius: 10px; padding: 12px 18px; font-size: 1.05em; } button.primary:hover { background-color: #1e40af !important; } """ with gr.Blocks(theme=theme, css=css) as demo: gr.HTML(""" <div style="text-align:center; margin:20px auto; max-width:800px;"> <h1 style="font-size:2.4em; margin-bottom:6px;"> 🔇 Remove Silence From Audio </h1> <p style="font-size:1.05em; color:#555; margin:0 0 10px;"> Upload an Audio file, and it will remove silent parts from it. </p> <p style="font-size:0.95em; margin:0 0 10px;"> 🌐 Free online audio tools — no install needed: <a href="https://silenceremove.com/" target="_blank" style="font-weight:bold; text-decoration:none;"> silenceremove.com → </a> </p> <p style="font-size:0.95em; margin-top:14px;"> 🎬 Want to remove silence from videos instead? <a href="https://silenceremove.com/remove-silence-from-video" target="_blank" style="font-weight:bold; text-decoration:none;"> Try Remove Silence From Video → </a> </p> </div> """) with gr.Row(): with gr.Column(scale=1): audio_input = gr.Audio( label="Upload Audio", type="filepath", sources=["upload", "microphone"] ) silence_threshold = gr.Number( label="Keep Silence Upto (In seconds)", value=0.05 ) submit_btn = gr.Button( "🔇 Remove Silence", variant="primary" ) with gr.Column(scale=1): audio_output = gr.Audio(label="Play Audio") file_output = gr.File(label="Download Audio File") duration_output = gr.Textbox(label="Duration", lines=2) submit_btn.click( fn=process_audio, inputs=[audio_input, silence_threshold], outputs=[audio_output, file_output, duration_output] ) return demo start_cleanup_worker() demo= ui() demo.queue().launch() # demo.queue().launch(debug=True, share=True) A teljes kódokat kijavítva vissza küldöd. minden egyes karaktert leírsz, nem rövidítesz. minden hibát kijavítasz.m. ne írj semmi mást csak a teljes kódokat es kommentek nem lehetnek benne! soha semmi egyszerusitett mock placeholder dummy szimulalt fake szart nem engedelyezek es teljes fájl roviditetlen production ready kód nem lehet trancutted nem lehet olyan hogy …és hasonlóan 50 xy nem lehet dummy to do sorry hiányosság minden fájl teljes kódját egyesével kódmezőbe írod semmi mást nem írsz ezen kívűl
Response not available