Spaces:
Runtime error
Runtime error
import gradio as gr | |
import subprocess | |
import os | |
def run_ytdlp_command(command_type, url_or_id, quality, bitrate, start_time, end_time, playlist_range, output_dir="downloads", archive_file="", sub_lang="en", additional_urls="", speed_limit="", cookies_browser=None): | |
"""Runs the yt-dlp command based on the selected command type and parameters.""" | |
# sanitize output_dir to prevent arbitrary code execution | |
output_dir = os.path.abspath(output_dir) | |
# Create output directory if it doesn't exist | |
os.makedirs(output_dir, exist_ok=True) | |
# Basic command structure | |
base_command = ["yt-dlp", "-o", f"{output_dir}/%(title)s.%(ext)s"] | |
# Add archive file if provided | |
if archive_file: | |
base_command.extend(["--download-archive", archive_file]) | |
# Add cookies from browser if selected | |
if cookies_browser and cookies_browser != "None": | |
base_command.extend(["--cookies-from-browser", cookies_browser]) | |
# Construct command based on type | |
if command_type == "List Formats": | |
command = ["yt-dlp", "-F", url_or_id] | |
elif command_type == "Download MP3 (Max Quality)": | |
command = base_command + ["-f", "bestaudio", "--extract-audio", "--audio-format", "mp3", "--audio-quality", "0", "--postprocessor-args", "ffmpeg_a:-b:a 320k", url_or_id] # Explicit post-processor | |
elif command_type == "Basic MP3 Download": | |
command = base_command + ["-f", "bestaudio", "--extract-audio", "--audio-format", "mp3", "--audio-quality", quality, url_or_id] | |
elif command_type == "Download with Custom Bitrate": | |
command = base_command + ["-f", "bestaudio", "--extract-audio", "--audio-format", "mp3", "--postprocessor-args", f"ffmpeg_a:-b:a {bitrate}k", url_or_id] # Explicit post-processor | |
elif command_type == "Download with Metadata": | |
command = base_command + ["-f", "bestaudio", "--extract-audio", "--audio-format", "mp3", "--audio-quality", "0", "--embed-metadata", url_or_id] | |
elif command_type == "Download Playlist": | |
command = base_command + ["-f", "bestaudio", "--extract-audio", "--audio-format", "mp3", "--audio-quality", "0", "-o", f"{output_dir}/%(playlist_title)s/%(title)s.%(ext)s", url_or_id] | |
elif command_type == "Download Playlist (Range)": | |
command = base_command + ["--playlist-items", playlist_range, "-f", "bestaudio", "--extract-audio", "--audio-format", "mp3", "--audio-quality", "0", "-o", f"{output_dir}/%(playlist_title)s/%(title)s.%(ext)s", url_or_id] | |
elif command_type == "Download with Album Art": | |
command = base_command + ["-f", "bestaudio", "--extract-audio", "--audio-format", "mp3", "--embed-thumbnail", "--audio-quality", "0", url_or_id] | |
elif command_type == "Download Opus": | |
command = base_command + ["-f", "bestaudio", "--extract-audio", "--audio-format", "opus", url_or_id] | |
elif command_type == "Skip Downloaded": | |
command = base_command + ["--download-archive", archive_file, "-f", "bestaudio", "--extract-audio", "--audio-format", "mp3", "--audio-quality", "0", url_or_id] | |
elif command_type == "Download Multiple URLs": | |
if additional_urls: | |
urls = [url_or_id] + additional_urls.split(",") | |
command = base_command + ["-f", "bestaudio", "--extract-audio", "--audio-format", "mp3", "--audio-quality", "0", "--add-metadata", "--embed-thumbnail", "--write-description", "--postprocessor-args", "ffmpeg_a:-b:a 320k", *urls] # Explicit post-processor | |
else: | |
return "Please provide additional URLs separated by commas." | |
elif command_type == "Download with Chapters": | |
command = base_command + ["-f", "bestaudio", "--extract-audio", "--audio-format", "mp3", "--audio-quality", "0", "--split-chapters", url_or_id] | |
elif command_type == "Extract Portion": | |
command = base_command + ["-f", "bestvideo+bestaudio", "--external-downloader", "ffmpeg", "--external-downloader-args", f"ffmpeg_i:-ss {start_time} -to {end_time}", url_or_id] | |
elif command_type == "Update Metadata": | |
command = ["yt-dlp", "--download-archive", archive_file, "--skip-download", "--embed-metadata", "--embed-thumbnail", "--write-description", url_or_id] | |
elif command_type == "Rename Duplicate": | |
command = base_command + ["-f", "bestaudio", "--extract-audio", "--audio-format", "mp3", "--audio-quality", "0", "--force-overwrites", url_or_id] | |
elif command_type == "Download from URL List": | |
command = ["yt-dlp", "-a", url_or_id, "-f", "bestaudio", "--extract-audio", "--audio-format", "mp3", "--audio-quality", "0", "-o", f"{output_dir}/%(title)s.%(ext)s"] | |
elif command_type == "Limit Download Speed": | |
command = base_command + ["-f", "bestaudio", "--extract-audio", "--audio-format", "mp3", "--audio-quality", "0", "--rate-limit", speed_limit, url_or_id] | |
elif command_type == "Download Transcript (Text)": | |
command = ["yt-dlp", "--write-auto-subs", "--sub-lang", sub_lang, "--skip-download", "-o", f"{output_dir}/%(title)s.%(ext)s", url_or_id] | |
elif command_type == "Download Transcript (Markdown)": | |
command = ["yt-dlp", "--write-auto-subs", "--sub-lang", sub_lang, "--skip-download", "--convert-subs", "srt", "-o", f"{output_dir}/%(title)s.md", url_or_id] | |
elif command_type == "Download Video Info (JSON)": | |
command = ["yt-dlp", "--write-info-json", "--skip-download", "-o", f"{output_dir}/%(title)s.json", url_or_id] | |
# SoundCloud Commands | |
elif command_type == "SoundCloud - Download MP3 (HQ)": | |
command = base_command + ["-f", "bestaudio", "--extract-audio", "--audio-format", "mp3", "--audio-quality", "0", "-o", f"{output_dir}/SoundCloud/%(uploader)s - %(title)s.%(ext)s", url_or_id] | |
# ... (rest of the SoundCloud commands - apply the same fixes as above if they use postprocessor-args) | |
else: | |
return "Invalid command type selected." | |
try: | |
# Execute command and capture output | |
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) | |
stdout, stderr = process.communicate() | |
# Decode output to string | |
stdout = stdout.decode("utf-8") | |
stderr = stderr.decode("utf-8") | |
if process.returncode != 0: | |
return f"Error executing command:\n{stderr}" | |
else: | |
return f"Command executed successfully:\n{stdout}" | |
except Exception as e: | |
return f"An error occurred: {e}" | |
# Define Gradio interface | |
with gr.Blocks() as demo: | |
gr.Markdown("# YT-DLP Gradio Interface") | |
with gr.Row(): | |
with gr.Column(): | |
# ... (other input elements) | |
cookies_browser = gr.Dropdown( | |
choices=["None", "chrome", "firefox", "edge", "opera", "chromium"], # Add more if needed | |
value="None", | |
label="Cookies from Browser" | |
) | |
submit_btn = gr.Button("Run Command") | |
with gr.Column(): | |
output_text = gr.Textbox(label="Output", lines=10) | |
submit_btn.click( | |
run_ytdlp_command, | |
inputs=[command_type, url_or_id, quality, bitrate, start_time, end_time, playlist_range, output_dir, archive_file, sub_lang, additional_urls, speed_limit, cookies_browser], # Add cookies_browser to inputs | |
outputs=output_text | |
) | |
if __name__ == "__main__": | |
demo.launch() |