Spaces:
Paused
Paused
| import gradio as gr | |
| from pytubefix import YouTube | |
| import os | |
| # --- SILENT TECH THEME --- | |
| # A minimalist, dark, high-contrast monochrome theme. | |
| silent_theme = gr.themes.Monochrome( | |
| primary_hue="slate", | |
| secondary_hue="gray", | |
| neutral_hue="zinc", | |
| font=[gr.themes.GoogleFont("Inter"), "ui-sans-serif", "system-ui", "sans-serif"], | |
| ).set( | |
| body_background_fill="#0a0a0a", | |
| body_background_fill_dark="#0a0a0a", | |
| body_text_color="#e5e5e5", | |
| body_text_color_dark="#e5e5e5", | |
| button_primary_background_fill="#ffffff", | |
| button_primary_background_fill_hover="#cccccc", | |
| button_primary_text_color="#000000", | |
| border_color_primary="#262626", | |
| block_background_fill="#171717", | |
| block_background_fill_dark="#171717", | |
| input_background_fill="#0a0a0a", | |
| input_background_fill_dark="#0a0a0a", | |
| ) | |
| # Custom CSS for sharper edges and minimal styling | |
| custom_css = """ | |
| .container { max-width: 700px; margin: 40px auto; font-family: 'Inter', sans-serif; } | |
| h1 { text-align: center; letter-spacing: 0.2em; font-weight: 300; } | |
| .subtext { text-align: center; color: #737373; font-size: 0.9em; letter-spacing: 0.05em; margin-bottom: 30px; } | |
| """ | |
| def get_video_info(url): | |
| try: | |
| if not url: | |
| return "Awaiting input...", gr.update(choices=[], value=None) | |
| yt = YouTube(url) | |
| info = f""" | |
| ### {yt.title} | |
| * **AUTHOR:** {yt.author} | |
| * **DURATION:** {yt.length}s | |
| * **VIEWS:** {yt.views:,} | |
| """ | |
| # Extract available progressive resolutions (mp4 with audio/video combined) | |
| resolutions = list(set([ | |
| stream.resolution | |
| for stream in yt.streams.filter(progressive=True, file_extension='mp4') | |
| if stream.resolution | |
| ])) | |
| sorted_res = sorted(resolutions, key=lambda x: int(x.replace('p', '')) if x else 0, reverse=True) | |
| default_res = sorted_res[0] if sorted_res else None | |
| return info, gr.update(choices=sorted_res, value=default_res, interactive=True) | |
| except Exception as e: | |
| return f"ERROR: {str(e)}", gr.update(choices=[], value=None) | |
| def download_video(url, resolution): | |
| try: | |
| if not url or not resolution: | |
| return None, "ERROR: Target URL or Resolution missing." | |
| yt = YouTube(url) | |
| stream = yt.streams.filter(progressive=True, file_extension='mp4', resolution=resolution).first() | |
| if not stream: | |
| # Fallback if specific resolution drops | |
| stream = yt.streams.filter(progressive=True, file_extension='mp4').first() | |
| out_dir = "./downloads" | |
| os.makedirs(out_dir, exist_ok=True) | |
| # Download the file | |
| file_path = stream.download(output_path=out_dir) | |
| return file_path, "STATUS: ACQUISITION COMPLETE." | |
| except Exception as e: | |
| return None, f"ERROR: {str(e)}" | |
| # --- BUILD THE UI --- | |
| with gr.Blocks(theme=silent_theme, css=custom_css) as demo: | |
| with gr.Column(elem_classes="container"): | |
| gr.Markdown("# SILENT // TECH") | |
| gr.Markdown("<div class='subtext'>VIDEO EXTRACTION PROTOCOL</div>") | |
| with gr.Group(): | |
| url_input = gr.Textbox(label="TARGET URL", placeholder="Insert YouTube link here...", lines=1, show_label=True) | |
| analyze_btn = gr.Button("ANALYZE STREAM", variant="primary") | |
| info_output = gr.Markdown("Awaiting input...") | |
| with gr.Group(): | |
| res_dropdown = gr.Dropdown(label="SELECT RESOLUTION", choices=[], interactive=False) | |
| dl_btn = gr.Button("INITIALIZE DOWNLOAD") | |
| status_output = gr.Textbox(label="SYSTEM STATUS", interactive=False) | |
| file_output = gr.File(label="OUTPUT ARTIFACT") | |
| # Wire up the buttons | |
| analyze_btn.click( | |
| fn=get_video_info, | |
| inputs=[url_input], | |
| outputs=[info_output, res_dropdown] | |
| ) | |
| dl_btn.click( | |
| fn=download_video, | |
| inputs=[url_input, res_dropdown], | |
| outputs=[file_output, status_output] | |
| ) | |
| if __name__ == "__main__": | |
| # Run the server on 0.0.0.0 to work properly inside HF Docker Spaces | |
| demo.launch(server_name="0.0.0.0", server_port=7860) |