import gradio as gr import os from utils import download_media_from_url, convert_media def handle_url_input(url): """Downloads media from a URL and returns the path.""" if not url: raise gr.Error("Please enter a valid URL") try: gr.Info("Attempting download... This may take a few seconds.") file_path = download_media_from_url(url) return file_path, file_path # Return to state and video preview except Exception as e: # Friendly error message for common issues error_msg = str(e) if "403" in error_msg or "Forbidden" in error_msg: raise gr.Error("Access denied (403). The site might be blocking automated downloads from this server IP.") elif "Video unavailable" in error_msg: raise gr.Error("Video not found. It might be private or deleted.") else: raise gr.Error(f"Download failed: {error_msg}") def handle_file_upload(file): """Handles direct file upload.""" if not file: return None, None return file, file def process_conversion(input_path, target_format): """Orchestrates the conversion process.""" if not input_path: raise gr.Error("No media file selected. Please upload a file or enter a URL.") gr.Info(f"Converting to {target_format}...") try: output_path, is_audio = convert_media(input_path, target_format) # Return logic: (Video_Component, Audio_Component, File_Download_Component) if is_audio: return { video_output: gr.Video(visible=False), audio_output: gr.Audio(value=output_path, visible=True), file_output: gr.File(value=output_path, visible=True) } else: return { video_output: gr.Video(value=output_path, visible=True), audio_output: gr.Audio(visible=False), file_output: gr.File(value=output_path, visible=True) } except Exception as e: raise gr.Error(f"Conversion failed: {str(e)}") # --- Gradio 6 Application Definition --- with gr.Blocks( title="Universal Media Converter", theme=gr.themes.Soft(), footer_links=[ {"label": "Built with anycoder", "url": "https://huggingface.co/spaces/akhaliq/anycoder"}, {"label": "yt-dlp Documentation", "url": "https://github.com/yt-dlp/yt-dlp"} ] ) as demo: # State to hold the path of the currently loaded file current_file_state = gr.State() with gr.Row(): gr.Markdown( """ # 🔄 Universal Media Converter [Built with anycoder](https://huggingface.co/spaces/akhaliq/anycoder) Robust downloader and converter for Twitter/X, YouTube, TikTok, and more. """ ) with gr.Row(): with gr.Column(scale=1): with gr.Tabs(): with gr.Tab("🔗 From URL"): gr.Markdown("Paste a link from X (Twitter), YouTube, or TikTok.") url_input = gr.Textbox( label="Paste URL", placeholder="https://x.com/user/status/...", show_label=False ) url_btn = gr.Button("Fetch Media", variant="primary") with gr.Tab("📁 Upload File"): upload_input = gr.File( label="Drop Video File", file_types=["video", "audio"], type="filepath" ) # Preview of the input input_preview = gr.Video(label="Input Preview", interactive=False) with gr.Column(scale=1): gr.Markdown("### Conversion Settings") target_format = gr.Dropdown( choices=[ "MP4", "WEBM", "GIF", "AVI", "MOV", "MKV", # Video "MP3", "WAV", "FLAC", "AAC", "OGG" # Audio ], value="MP4", label="Target Format", info="Select output format" ) convert_btn = gr.Button("🚀 Convert Now", variant="secondary", size="lg") # Output Area gr.Markdown("### Result") video_output = gr.Video(label="Video Output", visible=False) audio_output = gr.Audio(label="Audio Output", visible=False) file_output = gr.File(label="Download Converted File") # --- Event Listeners --- url_btn.click( fn=handle_url_input, inputs=[url_input], outputs=[current_file_state, input_preview], api_visibility="public" ) upload_input.upload( fn=handle_file_upload, inputs=[upload_input], outputs=[current_file_state, input_preview], api_visibility="public" ) convert_btn.click( fn=process_conversion, inputs=[current_file_state, target_format], outputs=[video_output, audio_output, file_output], api_visibility="public" ) if __name__ == "__main__": demo.launch()