Nymbo commited on
Commit
fadefaf
·
verified ·
1 Parent(s): 2d7a52d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +174 -108
app.py CHANGED
@@ -1,115 +1,181 @@
1
  import gradio as gr
2
- import subprocess
3
  import os
4
 
5
- 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):
6
- """Runs the yt-dlp command based on the selected command type and parameters."""
7
-
8
- # sanitize output_dir to prevent arbitrary code execution
9
- output_dir = os.path.abspath(output_dir)
10
-
11
- # Create output directory if it doesn't exist
12
- os.makedirs(output_dir, exist_ok=True)
13
-
14
- # Basic command structure
15
- base_command = ["yt-dlp", "-o", f"{output_dir}/%(title)s.%(ext)s"]
16
-
17
- # Add archive file if provided
18
- if archive_file:
19
- base_command.extend(["--download-archive", archive_file])
20
-
21
- # Add cookies from browser if selected
22
- if cookies_browser and cookies_browser != "None":
23
- base_command.extend(["--cookies-from-browser", cookies_browser])
24
-
25
- # Construct command based on type
26
- if command_type == "List Formats":
27
- command = ["yt-dlp", "-F", url_or_id]
28
- elif command_type == "Download MP3 (Max Quality)":
29
- 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
30
- elif command_type == "Basic MP3 Download":
31
- command = base_command + ["-f", "bestaudio", "--extract-audio", "--audio-format", "mp3", "--audio-quality", quality, url_or_id]
32
- elif command_type == "Download with Custom Bitrate":
33
- 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
34
- elif command_type == "Download with Metadata":
35
- command = base_command + ["-f", "bestaudio", "--extract-audio", "--audio-format", "mp3", "--audio-quality", "0", "--embed-metadata", url_or_id]
36
- elif command_type == "Download Playlist":
37
- 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]
38
- elif command_type == "Download Playlist (Range)":
39
- 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]
40
- elif command_type == "Download with Album Art":
41
- command = base_command + ["-f", "bestaudio", "--extract-audio", "--audio-format", "mp3", "--embed-thumbnail", "--audio-quality", "0", url_or_id]
42
- elif command_type == "Download Opus":
43
- command = base_command + ["-f", "bestaudio", "--extract-audio", "--audio-format", "opus", url_or_id]
44
- elif command_type == "Skip Downloaded":
45
- command = base_command + ["--download-archive", archive_file, "-f", "bestaudio", "--extract-audio", "--audio-format", "mp3", "--audio-quality", "0", url_or_id]
46
- elif command_type == "Download Multiple URLs":
47
- if additional_urls:
48
- urls = [url_or_id] + additional_urls.split(",")
49
- 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
50
- else:
51
- return "Please provide additional URLs separated by commas."
52
- elif command_type == "Download with Chapters":
53
- command = base_command + ["-f", "bestaudio", "--extract-audio", "--audio-format", "mp3", "--audio-quality", "0", "--split-chapters", url_or_id]
54
- elif command_type == "Extract Portion":
55
- command = base_command + ["-f", "bestvideo+bestaudio", "--external-downloader", "ffmpeg", "--external-downloader-args", f"ffmpeg_i:-ss {start_time} -to {end_time}", url_or_id]
56
- elif command_type == "Update Metadata":
57
- command = ["yt-dlp", "--download-archive", archive_file, "--skip-download", "--embed-metadata", "--embed-thumbnail", "--write-description", url_or_id]
58
- elif command_type == "Rename Duplicate":
59
- command = base_command + ["-f", "bestaudio", "--extract-audio", "--audio-format", "mp3", "--audio-quality", "0", "--force-overwrites", url_or_id]
60
- elif command_type == "Download from URL List":
61
- 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"]
62
- elif command_type == "Limit Download Speed":
63
- command = base_command + ["-f", "bestaudio", "--extract-audio", "--audio-format", "mp3", "--audio-quality", "0", "--rate-limit", speed_limit, url_or_id]
64
- elif command_type == "Download Transcript (Text)":
65
- command = ["yt-dlp", "--write-auto-subs", "--sub-lang", sub_lang, "--skip-download", "-o", f"{output_dir}/%(title)s.%(ext)s", url_or_id]
66
- elif command_type == "Download Transcript (Markdown)":
67
- 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]
68
- elif command_type == "Download Video Info (JSON)":
69
- command = ["yt-dlp", "--write-info-json", "--skip-download", "-o", f"{output_dir}/%(title)s.json", url_or_id]
70
- # SoundCloud Commands
71
- elif command_type == "SoundCloud - Download MP3 (HQ)":
72
- 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]
73
- # ... (rest of the SoundCloud commands - apply the same fixes as above if they use postprocessor-args)
74
- else:
75
- return "Invalid command type selected."
76
-
77
  try:
78
- # Execute command and capture output
79
- process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
80
- stdout, stderr = process.communicate()
81
-
82
- # Decode output to string
83
- stdout = stdout.decode("utf-8")
84
- stderr = stderr.decode("utf-8")
85
-
86
- if process.returncode != 0:
87
- return f"Error executing command:\n{stderr}"
88
- else:
89
- return f"Command executed successfully:\n{stdout}"
90
  except Exception as e:
91
- return f"An error occurred: {e}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
 
93
- # Define Gradio interface
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  with gr.Blocks() as demo:
95
- gr.Markdown("# YT-DLP Gradio Interface")
96
- with gr.Row():
97
- with gr.Column():
98
- # ... (other input elements)
99
- cookies_browser = gr.Dropdown(
100
- choices=["None", "chrome", "firefox", "edge", "opera", "chromium"], # Add more if needed
101
- value="None",
102
- label="Cookies from Browser"
103
- )
104
- submit_btn = gr.Button("Run Command")
105
- with gr.Column():
106
- output_text = gr.Textbox(label="Output", lines=10)
107
-
108
- submit_btn.click(
109
- run_ytdlp_command,
110
- 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
111
- outputs=output_text
112
- )
113
-
114
- if __name__ == "__main__":
115
- demo.launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import gradio as gr
2
+ import yt_dlp
3
  import os
4
 
5
+ def run_yt_dlp_command(command):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
  try:
7
+ yt_dlp.main(command.split())
8
+ return "Download completed successfully!"
 
 
 
 
 
 
 
 
 
 
9
  except Exception as e:
10
+ return f"An error occurred: {str(e)}"
11
+
12
+ def list_formats(url):
13
+ return run_yt_dlp_command(f"yt-dlp -F {url}")
14
+
15
+ def download_mp3_max_quality(url):
16
+ return run_yt_dlp_command(f"yt-dlp -f bestaudio --extract-audio --audio-format mp3 --audio-quality 0 --postprocessor-args \"-b:a 320k\" -o \"P:/Local Music/%(title)s.%(ext)s\" {url}")
17
+
18
+ def basic_high_quality_mp3(url):
19
+ return run_yt_dlp_command(f"yt-dlp -f bestaudio --extract-audio --audio-format mp3 --audio-quality 0 -o \"P:/Local Music/%(title)s.%(ext)s\" {url}")
20
+
21
+ def download_custom_bitrate(url, bitrate):
22
+ return run_yt_dlp_command(f"yt-dlp -f bestaudio --extract-audio --audio-format mp3 --postprocessor-args \"-b:a {bitrate}k\" -o \"P:/Local Music/%(title)s.%(ext)s\" {url}")
23
+
24
+ def download_with_metadata(url):
25
+ return run_yt_dlp_command(f"yt-dlp -f bestaudio --extract-audio --audio-format mp3 --audio-quality 0 --embed-metadata -o \"P:/Local Music/%(title)s.%(ext)s\" {url}")
26
+
27
+ def download_playlist(url):
28
+ return run_yt_dlp_command(f"yt-dlp -f bestaudio --extract-audio --audio-format mp3 --audio-quality 0 -o \"P:/Local Music/%(playlist_title)s/%(title)s.%(ext)s\" {url}")
29
+
30
+ def download_playlist_range(url, range):
31
+ return run_yt_dlp_command(f"yt-dlp --playlist-items {range} -f bestaudio --extract-audio --audio-format mp3 --audio-quality 0 -o \"P:/Local Music/%(playlist_title)s/%(title)s.%(ext)s\" {url}")
32
+
33
+ def download_hq_soundcloud(url):
34
+ return run_yt_dlp_command(f"yt-dlp -f bestaudio --extract-audio --audio-format mp3 --audio-quality 0 -o \"P:/Local Music/SoundCloud/%(uploader)s - %(title)s.%(ext)s\" {url}")
35
+
36
+ def embed_album_art(url):
37
+ return run_yt_dlp_command(f"yt-dlp -f bestaudio --extract-audio --audio-format mp3 --embed-thumbnail --audio-quality 0 -o \"P:/Local Music/%(title)s.%(ext)s\" {url}")
38
+
39
+ def download_opus(url):
40
+ return run_yt_dlp_command(f"yt-dlp -f bestaudio --extract-audio --audio-format opus -o \"P:/Local Music/%(title)s.%(ext)s\" {url}")
41
+
42
+ def skip_downloaded_files(url):
43
+ return run_yt_dlp_command(f"yt-dlp --download-archive \"P:/Local Music/downloaded.txt\" -f bestaudio --extract-audio --audio-format mp3 --audio-quality 0 -o \"P:/Local Music/%(title)s.%(ext)s\" {url}")
44
 
45
+ def download_multiple_files(urls):
46
+ return run_yt_dlp_command(f"yt-dlp -f bestaudio --extract-audio --audio-format mp3 --audio-quality 0 --add-metadata --embed-thumbnail --write-description --postprocessor-args \"-b:a 320k\" -o \"P:/Local Music/%(title)s.%(ext)s\" {' '.join(urls.split(','))}")
47
+
48
+ def download_with_chapters(url):
49
+ return run_yt_dlp_command(f"yt-dlp -f bestaudio --extract-audio --audio-format mp3 --audio-quality 0 --split-chapters -o \"P:/Local Music/%(title)s.%(ext)s\" {url}")
50
+
51
+ def extract_portion(url, start, end):
52
+ return run_yt_dlp_command(f"yt-dlp -f bestvideo+bestaudio --external-downloader ffmpeg --external-downloader-args \"ffmpeg_i:-ss {start} -to {end}\" -o \"P:/Local Music/%(title)s.%(ext)s\" {url}")
53
+
54
+ def update_metadata(url):
55
+ return run_yt_dlp_command(f"yt-dlp --download-archive \"P:/Local Music/downloaded.txt\" --skip-download --embed-metadata --embed-thumbnail --write-description {url}")
56
+
57
+ def auto_rename_duplicates(url):
58
+ return run_yt_dlp_command(f"yt-dlp -f bestaudio --extract-audio --audio-format mp3 --audio-quality 0 --force-overwrites -o \"P:/Local Music/%(title)s.%(ext)s\" {url}")
59
+
60
+ def download_from_url_list(file_path):
61
+ return run_yt_dlp_command(f"yt-dlp -a \"{file_path}\" -f bestaudio --extract-audio --audio-format mp3 --audio-quality 0 -o \"P:/Local Music/%(title)s.%(ext)s\"")
62
+
63
+ def limit_download_speed(url, speed):
64
+ return run_yt_dlp_command(f"yt-dlp -f bestaudio --extract-audio --audio-format mp3 --audio-quality 0 --rate-limit {speed} -o \"P:/Local Music/%(title)s.%(ext)s\" {url}")
65
+
66
+ def download_youtube_transcript(url, format):
67
+ if format == "text":
68
+ return run_yt_dlp_command(f"yt-dlp --write-auto-subs --sub-lang en --skip-download -o \"P:/Local Music/%(title)s.%(ext)s\" {url}")
69
+ elif format == "markdown":
70
+ return run_yt_dlp_command(f"yt-dlp --write-auto-subs --sub-lang en --skip-download --convert-subs srt -o \"P:/Local Music/%(title)s.md\" {url}")
71
+
72
+ def download_video_info(url):
73
+ return run_yt_dlp_command(f"yt-dlp --write-info-json --skip-download -o \"P:/Local Music/%(title)s.json\" {url}")
74
+
75
+ def download_age_restricted_content(url, username, password):
76
+ return run_yt_dlp_command(f"yt-dlp --username \"{username}\" --password \"{password}\" -f bestvideo+bestaudio -o \"P:/Local Music/%(title)s.%(ext)s\" {url}")
77
+
78
+ # Define the Gradio interface
79
  with gr.Blocks() as demo:
80
+ gr.Markdown("# YT-DLP Download Interface")
81
+
82
+ with gr.Tab("General Commands"):
83
+ with gr.Row():
84
+ url_general = gr.Textbox(label="Video URL")
85
+ btn_list_formats = gr.Button("List Formats")
86
+ btn_list_formats.click(list_formats, inputs=url_general, outputs="text_box_output")
87
+
88
+ with gr.Row():
89
+ btn_mp3_max_quality = gr.Button("Download MP3 Max Quality")
90
+ btn_mp3_max_quality.click(download_mp3_max_quality, inputs=url_general, outputs="text_box_output")
91
+
92
+ with gr.Row():
93
+ btn_basic_mp3 = gr.Button("Basic High-Quality MP3")
94
+ btn_basic_mp3.click(basic_high_quality_mp3, inputs=url_general, outputs="text_box_output")
95
+
96
+ with gr.Row():
97
+ bitrate = gr.Textbox(label="Custom Bitrate (e.g., 192)")
98
+ btn_custom_bitrate = gr.Button("Download Custom Bitrate")
99
+ btn_custom_bitrate.click(download_custom_bitrate, inputs=[url_general, bitrate], outputs="text_box_output")
100
+
101
+ with gr.Row():
102
+ btn_metadata = gr.Button("Download with Metadata")
103
+ btn_metadata.click(download_with_metadata, inputs=url_general, outputs="text_box_output")
104
+
105
+ with gr.Row():
106
+ btn_playlist = gr.Button("Download Playlist")
107
+ btn_playlist.click(download_playlist, inputs=url_general, outputs="text_box_output")
108
+
109
+ with gr.Row():
110
+ playlist_range = gr.Textbox(label="Playlist Range (e.g., 1-5)")
111
+ btn_playlist_range = gr.Button("Download Playlist Range")
112
+ btn_playlist_range.click(download_playlist_range, inputs=[url_general, playlist_range], outputs="text_box_output")
113
+
114
+ with gr.Row():
115
+ btn_hq_soundcloud = gr.Button("Download HQ from SoundCloud")
116
+ btn_hq_soundcloud.click(download_hq_soundcloud, inputs=url_general, outputs="text_box_output")
117
+
118
+ with gr.Row():
119
+ btn_album_art = gr.Button("Embed Album Art")
120
+ btn_album_art.click(embed_album_art, inputs=url_general, outputs="text_box_output")
121
+
122
+ with gr.Row():
123
+ btn_opus = gr.Button("Download Opus")
124
+ btn_opus.click(download_opus, inputs=url_general, outputs="text_box_output")
125
+
126
+ with gr.Row():
127
+ btn_skip_downloaded = gr.Button("Skip Downloaded Files")
128
+ btn_skip_downloaded.click(skip_downloaded_files, inputs=url_general, outputs="text_box_output")
129
+
130
+ with gr.Row():
131
+ urls = gr.Textbox(label="Multiple URLs (comma-separated)")
132
+ btn_multiple_files = gr.Button("Download Multiple Files")
133
+ btn_multiple_files.click(download_multiple_files, inputs=urls, outputs="text_box_output")
134
+
135
+ with gr.Row():
136
+ btn_chapters = gr.Button("Download with Chapters")
137
+ btn_chapters.click(download_with_chapters, inputs=url_general, outputs="text_box_output")
138
+
139
+ with gr.Row():
140
+ start_time = gr.Textbox(label="Start Time (e.g., 00:01:00)")
141
+ end_time = gr.Textbox(label="End Time (e.g., 00:05:00)")
142
+ btn_extract_portion = gr.Button("Extract Portion")
143
+ btn_extract_portion.click(extract_portion, inputs=[url_general, start_time, end_time], outputs="text_box_output")
144
+
145
+ with gr.Row():
146
+ btn_update_metadata = gr.Button("Update Metadata")
147
+ btn_update_metadata.click(update_metadata, inputs=url_general, outputs="text_box_output")
148
+
149
+ with gr.Row():
150
+ btn_auto_rename = gr.Button("Auto-Rename Duplicates")
151
+ btn_auto_rename.click(auto_rename_duplicates, inputs=url_general, outputs="text_box_output")
152
+
153
+ with gr.Row():
154
+ url_list = gr.Textbox(label="URL List File Path")
155
+ btn_url_list = gr.Button("Download from URL List")
156
+ btn_url_list.click(download_from_url_list, inputs=url_list, outputs="text_box_output")
157
+
158
+ with gr.Row():
159
+ speed_limit = gr.Textbox(label="Download Speed (e.g., 1M)")
160
+ btn_limit_speed = gr.Button("Limit Download Speed")
161
+ btn_limit_speed.click(limit_download_speed, inputs=[url_general, speed_limit], outputs="text_box_output")
162
+
163
+ with gr.Row():
164
+ transcript_format = gr.Dropdown(["text", "markdown"], label="Transcript Format")
165
+ btn_transcript = gr.Button("Download Transcript")
166
+ btn_transcript.click(download_youtube_transcript, inputs=[url_general, transcript_format], outputs="text_box_output")
167
+
168
+ with gr.Row():
169
+ btn_video_info = gr.Button("Download Video Info")
170
+ btn_video_info.click(download_video_info, inputs=url_general, outputs="text_box_output")
171
+
172
+ with gr.Row():
173
+ youtube_username = gr.Textbox(label="YouTube Username")
174
+ youtube_password = gr.Textbox(label="YouTube Password", type="password")
175
+ btn_age_restricted = gr.Button("Download Age-Restricted Content")
176
+ btn_age_restricted.click(download_age_restricted_content, inputs=[url_general, youtube_username, youtube_password], outputs="text_box_output")
177
+
178
+ text_box_output = gr.Textbox(label="Output")
179
+
180
+ # Launch the Gradio app
181
+ demo.launch()