Spaces:
Sleeping
Sleeping
import gradio as gr | |
import subprocess | |
import os | |
import json | |
from typing import List, Optional | |
def run_ytdlp_command(command: List[str]) -> str: | |
"""Execute a yt-dlp command and return the output.""" | |
try: | |
result = subprocess.run(command, capture_output=True, text=True) | |
return result.stdout if result.stdout else result.stderr | |
except Exception as e: | |
return f"Error: {str(e)}" | |
def get_available_formats(url: str) -> str: | |
"""List available formats for a given URL.""" | |
command = ["yt-dlp", "-F", url] | |
return run_ytdlp_command(command) | |
def download_audio( | |
url: str, | |
output_dir: str, | |
audio_format: str = "mp3", | |
audio_quality: str = "320k", | |
extract_metadata: bool = True, | |
embed_thumbnail: bool = True, | |
playlist_items: Optional[str] = None, | |
split_chapters: bool = False, | |
time_range: Optional[str] = None, | |
download_archive: bool = False, | |
rate_limit: Optional[str] = None | |
) -> str: | |
"""Download audio with specified parameters.""" | |
command = ["yt-dlp", "-f", "bestaudio", "--extract-audio"] | |
# Basic audio settings | |
command.extend([ | |
"--audio-format", audio_format, | |
"--postprocessor-args", f"-b:a {audio_quality}", | |
"-o", os.path.join(output_dir, "%(title)s.%(ext)s") | |
]) | |
# Optional features | |
if extract_metadata: | |
command.extend(["--embed-metadata", "--add-metadata"]) | |
if embed_thumbnail: | |
command.append("--embed-thumbnail") | |
if playlist_items: | |
command.extend(["--playlist-items", playlist_items]) | |
if split_chapters: | |
command.append("--split-chapters") | |
if time_range: | |
start, end = time_range.split("-") | |
command.extend([ | |
"--external-downloader", "ffmpeg", | |
"--external-downloader-args", f"ffmpeg_i:-ss {start} -to {end}" | |
]) | |
if download_archive: | |
command.extend(["--download-archive", os.path.join(output_dir, "downloaded.txt")]) | |
if rate_limit: | |
command.extend(["--rate-limit", rate_limit]) | |
command.append(url) | |
return run_ytdlp_command(command) | |
def download_transcript(url: str, output_dir: str, format: str = "srt") -> str: | |
"""Download video transcript.""" | |
command = [ | |
"yt-dlp", | |
"--write-auto-subs", | |
"--sub-lang", "en", | |
"--skip-download", | |
"--convert-subs", format, | |
"-o", os.path.join(output_dir, "%(title)s.%(ext)s"), | |
url | |
] | |
return run_ytdlp_command(command) | |
def download_info_json(url: str, output_dir: str) -> str: | |
"""Download video information as JSON.""" | |
command = [ | |
"yt-dlp", | |
"--write-info-json", | |
"--skip-download", | |
"-o", os.path.join(output_dir, "%(title)s.json"), | |
url | |
] | |
return run_ytdlp_command(command) | |
def create_interface(): | |
with gr.Blocks(title="YT-DLP GUI") as app: | |
gr.Markdown("# YT-DLP Graphical Interface") | |
with gr.Tab("Basic Download"): | |
url_input = gr.Textbox(label="URL") | |
output_dir = gr.Textbox(label="Output Directory", value="downloads") | |
with gr.Row(): | |
audio_format = gr.Dropdown( | |
choices=["mp3", "opus", "m4a", "wav"], | |
value="mp3", | |
label="Audio Format" | |
) | |
audio_quality = gr.Dropdown( | |
choices=["320k", "256k", "192k", "128k"], | |
value="320k", | |
label="Audio Quality" | |
) | |
with gr.Row(): | |
extract_metadata = gr.Checkbox(label="Extract Metadata", value=True) | |
embed_thumbnail = gr.Checkbox(label="Embed Thumbnail", value=True) | |
download_btn = gr.Button("Download") | |
output = gr.Textbox(label="Output", lines=5) | |
download_btn.click( | |
download_audio, | |
inputs=[ | |
url_input, | |
output_dir, | |
audio_format, | |
audio_quality, | |
extract_metadata, | |
embed_thumbnail | |
], | |
outputs=output | |
) | |
with gr.Tab("Advanced Options"): | |
adv_url = gr.Textbox(label="URL") | |
adv_output_dir = gr.Textbox(label="Output Directory", value="downloads") | |
with gr.Row(): | |
playlist_items = gr.Textbox(label="Playlist Items (e.g., 1-5)") | |
rate_limit = gr.Textbox(label="Rate Limit (e.g., 1M)") | |
with gr.Row(): | |
split_chapters = gr.Checkbox(label="Split by Chapters") | |
use_archive = gr.Checkbox(label="Use Download Archive") | |
time_range = gr.Textbox(label="Time Range (e.g., 00:01:00-00:05:00)") | |
adv_download_btn = gr.Button("Download with Advanced Options") | |
adv_output = gr.Textbox(label="Output", lines=5) | |
adv_download_btn.click( | |
download_audio, | |
inputs=[ | |
adv_url, | |
adv_output_dir, | |
"mp3", # fixed format for simplicity | |
"320k", # fixed quality for simplicity | |
True, # always extract metadata | |
True, # always embed thumbnail | |
playlist_items, | |
split_chapters, | |
time_range, | |
use_archive, | |
rate_limit | |
], | |
outputs=adv_output | |
) | |
with gr.Tab("Format Info"): | |
format_url = gr.Textbox(label="URL") | |
format_btn = gr.Button("Get Available Formats") | |
format_output = gr.Textbox(label="Available Formats", lines=10) | |
format_btn.click( | |
get_available_formats, | |
inputs=format_url, | |
outputs=format_output | |
) | |
with gr.Tab("Extras"): | |
extra_url = gr.Textbox(label="URL") | |
extra_output_dir = gr.Textbox(label="Output Directory", value="downloads") | |
with gr.Row(): | |
transcript_btn = gr.Button("Download Transcript") | |
info_json_btn = gr.Button("Download Info JSON") | |
extra_output = gr.Textbox(label="Output", lines=5) | |
transcript_btn.click( | |
download_transcript, | |
inputs=[extra_url, extra_output_dir], | |
outputs=extra_output | |
) | |
info_json_btn.click( | |
download_info_json, | |
inputs=[extra_url, extra_output_dir], | |
outputs=extra_output | |
) | |
return app | |
if __name__ == "__main__": | |
app = create_interface() | |
app.launch() |