Spaces:
Runtime error
Runtime error
File size: 5,228 Bytes
a17739e |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 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 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
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() |