Spaces:
Paused
Paused
Commit ·
289d0de
1
Parent(s): 3a9b42e
Gradio Update
Browse files
app.py
CHANGED
|
@@ -1,18 +1,10 @@
|
|
| 1 |
import os
|
| 2 |
import re
|
| 3 |
import yt_dlp
|
|
|
|
| 4 |
import subprocess
|
| 5 |
import gradio as gr
|
| 6 |
-
|
| 7 |
-
# Install yt-dlp
|
| 8 |
-
try:
|
| 9 |
-
|
| 10 |
-
print("yt-dlp sudah terinstal.")
|
| 11 |
-
except ImportError:
|
| 12 |
-
print("yt-dlp belum terinstal, menginstal sekarang...")
|
| 13 |
-
subprocess.run(['pip', 'install', 'yt-dlp', 'mutagen'])
|
| 14 |
-
import yt_dlp
|
| 15 |
-
print("yt-dlp berhasil diinstal.")
|
| 16 |
|
| 17 |
# Deteksi orientasi video berdasarkan URL atau metadata
|
| 18 |
def get_orientation(url):
|
|
@@ -26,13 +18,16 @@ def get_orientation(url):
|
|
| 26 |
return None
|
| 27 |
|
| 28 |
# Fungsi download video
|
| 29 |
-
def video_download(url
|
| 30 |
-
|
| 31 |
-
os.makedirs(video_folder)
|
| 32 |
try:
|
| 33 |
-
result = subprocess.run(['yt-dlp', '--
|
| 34 |
-
title = result.stdout.strip()
|
|
|
|
| 35 |
title = re.sub(r'[\\/:*?"<>|]', ' ', title)
|
|
|
|
|
|
|
|
|
|
| 36 |
|
| 37 |
if not title:
|
| 38 |
raise ValueError("Tidak dapat mendapatkan judul video.")
|
|
@@ -46,61 +41,100 @@ def video_download(url, video_folder = "/home/user/app/Video"):
|
|
| 46 |
print("Gagal mendeteksi orientasi video.")
|
| 47 |
return None
|
| 48 |
|
| 49 |
-
|
| 50 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 51 |
|
| 52 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 53 |
|
| 54 |
except subprocess.CalledProcessError as e:
|
| 55 |
-
|
| 56 |
-
return None
|
| 57 |
except Exception as e:
|
| 58 |
-
|
| 59 |
-
return None
|
| 60 |
|
| 61 |
# Fungsi download MP3
|
| 62 |
-
def audio_download(url
|
| 63 |
-
|
| 64 |
-
os.makedirs(audio_folder)
|
| 65 |
try:
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
result = subprocess.run(['yt-dlp', '--get-title', url], capture_output=True, text=True, check=True)
|
| 71 |
-
title = result.stdout.strip()
|
| 72 |
title = re.sub(r'[\\/:*?"<>|]', ' ', title)
|
|
|
|
|
|
|
|
|
|
| 73 |
|
| 74 |
if not title:
|
| 75 |
raise ValueError("Tidak dapat mendapatkan judul audio.")
|
| 76 |
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 81 |
|
| 82 |
except subprocess.CalledProcessError as e:
|
| 83 |
-
|
| 84 |
-
return None
|
| 85 |
except Exception as e:
|
| 86 |
-
|
| 87 |
-
return None
|
| 88 |
|
| 89 |
# Fungsi proses input untuk Gradio
|
| 90 |
def process_input(url, download_type):
|
| 91 |
if download_type == "Video":
|
| 92 |
-
|
| 93 |
else:
|
| 94 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 95 |
|
| 96 |
# Gradio interface
|
| 97 |
-
|
|
|
|
|
|
|
| 98 |
gr.Markdown("# YouTube Downloader - Video dan Audio")
|
| 99 |
-
|
| 100 |
-
|
|
|
|
| 101 |
download_button = gr.Button("Download")
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 105 |
|
| 106 |
youtube.launch(share=True)
|
|
|
|
| 1 |
import os
|
| 2 |
import re
|
| 3 |
import yt_dlp
|
| 4 |
+
import requests
|
| 5 |
import subprocess
|
| 6 |
import gradio as gr
|
| 7 |
+
from urllib.parse import urlparse
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8 |
|
| 9 |
# Deteksi orientasi video berdasarkan URL atau metadata
|
| 10 |
def get_orientation(url):
|
|
|
|
| 18 |
return None
|
| 19 |
|
| 20 |
# Fungsi download video
|
| 21 |
+
def video_download(url):
|
| 22 |
+
domain = urlparse(url).hostname.split('.')[-2].title()
|
|
|
|
| 23 |
try:
|
| 24 |
+
result = subprocess.run(['yt-dlp', '--print', '%(title)s\n%(uploader)s\n%(thumbnail)s', '--skip-download', url], capture_output=True, text=True, check=True)
|
| 25 |
+
title, uploader, thumbnail_url = result.stdout.strip().split('\n')
|
| 26 |
+
uploader = re.sub(r'[\\/:*?"<>|]', ' ', uploader)
|
| 27 |
title = re.sub(r'[\\/:*?"<>|]', ' ', title)
|
| 28 |
+
if "ytimg" in thumbnail_url and thumbnail_url.endswith(".webp"):
|
| 29 |
+
thumbnail_url = thumbnail_url.replace("_webp", "").replace(".webp", ".jpg")
|
| 30 |
+
# print(f'Channel: {uploader}\nTitle: {title}\nThumbnail: {thumbnail_url}')
|
| 31 |
|
| 32 |
if not title:
|
| 33 |
raise ValueError("Tidak dapat mendapatkan judul video.")
|
|
|
|
| 41 |
print("Gagal mendeteksi orientasi video.")
|
| 42 |
return None
|
| 43 |
|
| 44 |
+
video_folder = os.path.join("Gradio", domain, uploader, "Video")
|
| 45 |
+
if not os.path.exists(video_folder):
|
| 46 |
+
os.makedirs(video_folder)
|
| 47 |
+
video_file = os.path.join(video_folder, f"{uploader} - {title}.mp4")
|
| 48 |
+
|
| 49 |
+
thumbnail_folder = os.path.join("Gradio", domain, uploader, "Thumbnail")
|
| 50 |
+
if not os.path.exists(thumbnail_folder):
|
| 51 |
+
os.makedirs(thumbnail_folder)
|
| 52 |
+
thumbnail_file = os.path.join(thumbnail_folder, f"{uploader} - {title}.jpg")
|
| 53 |
|
| 54 |
+
if not os.path.exists(thumbnail_file):
|
| 55 |
+
subprocess.run(['wget', '-O', thumbnail_file, thumbnail_url])
|
| 56 |
+
if not os.path.exists(video_file):
|
| 57 |
+
subprocess.run(['yt-dlp', '-f', format_filter, '-o', video_file, url], check=True)
|
| 58 |
+
|
| 59 |
+
return video_file, thumbnail_file
|
| 60 |
|
| 61 |
except subprocess.CalledProcessError as e:
|
| 62 |
+
return "", ""
|
|
|
|
| 63 |
except Exception as e:
|
| 64 |
+
return "", ""
|
|
|
|
| 65 |
|
| 66 |
# Fungsi download MP3
|
| 67 |
+
def audio_download(url):
|
| 68 |
+
domain = urlparse(url).hostname.split('.')[-2].title()
|
|
|
|
| 69 |
try:
|
| 70 |
+
result = subprocess.run(['yt-dlp', '--print', '%(title)s\n%(uploader)s\n%(thumbnail)s', '--skip-download', url], capture_output=True, text=True, check=True)
|
| 71 |
+
title, uploader, thumbnail_url = result.stdout.strip().split('\n')
|
| 72 |
+
uploader = re.sub(r'[\\/:*?"<>|]', ' ', uploader)
|
|
|
|
|
|
|
|
|
|
| 73 |
title = re.sub(r'[\\/:*?"<>|]', ' ', title)
|
| 74 |
+
if "ytimg" in thumbnail_url and thumbnail_url.endswith(".webp"):
|
| 75 |
+
thumbnail_url = thumbnail_url.replace("_webp", "").replace(".webp", ".jpg")
|
| 76 |
+
# print(f'Channel: {uploader}\nTitle: {title}\nThumbnail: {thumbnail_url}')
|
| 77 |
|
| 78 |
if not title:
|
| 79 |
raise ValueError("Tidak dapat mendapatkan judul audio.")
|
| 80 |
|
| 81 |
+
audio_folder = os.path.join("Gradio", domain, uploader, "Audio")
|
| 82 |
+
if not os.path.exists(audio_folder):
|
| 83 |
+
os.makedirs(audio_folder)
|
| 84 |
+
audio_file = os.path.join(audio_folder, f"{uploader} - {title}.mp3")
|
| 85 |
+
|
| 86 |
+
thumbnail_folder = os.path.join("Gradio", domain, uploader, "Thumbnail")
|
| 87 |
+
if not os.path.exists(thumbnail_folder):
|
| 88 |
+
os.makedirs(thumbnail_folder)
|
| 89 |
+
thumbnail_file = os.path.join(thumbnail_folder, f"{uploader} - {title}.jpg")
|
| 90 |
+
|
| 91 |
+
if not os.path.exists(thumbnail_file):
|
| 92 |
+
subprocess.run(['wget', '-O', thumbnail_file, thumbnail_url])
|
| 93 |
+
if not os.path.exists(audio_file):
|
| 94 |
+
subprocess.run(['yt-dlp', '-x', '--audio-format', 'mp3', '--embed-thumbnail', '-o', audio_file, url], check=True)
|
| 95 |
+
|
| 96 |
+
return audio_file, thumbnail_file
|
| 97 |
|
| 98 |
except subprocess.CalledProcessError as e:
|
| 99 |
+
return "", ""
|
|
|
|
| 100 |
except Exception as e:
|
| 101 |
+
return "", ""
|
|
|
|
| 102 |
|
| 103 |
# Fungsi proses input untuk Gradio
|
| 104 |
def process_input(url, download_type):
|
| 105 |
if download_type == "Video":
|
| 106 |
+
file, thumbnail = video_download(url.split("&")[0])
|
| 107 |
else:
|
| 108 |
+
file, thumbnail = audio_download(url.split("&")[0])
|
| 109 |
+
|
| 110 |
+
return (
|
| 111 |
+
gr.update(label=download_type, value=file, visible=True),
|
| 112 |
+
thumbnail,
|
| 113 |
+
gr.update(label=f"Download {download_type}", value=file, visible=True),
|
| 114 |
+
gr.update(label="Download Thumbnail", value=thumbnail, visible=True)
|
| 115 |
+
)
|
| 116 |
|
| 117 |
# Gradio interface
|
| 118 |
+
css_url = "https://gilbertclaus.pythonanywhere.com/templates/gradio.css"
|
| 119 |
+
|
| 120 |
+
with gr.Blocks(title="Video/Audio Downloader", css=requests.get(css_url).text) as youtube:
|
| 121 |
gr.Markdown("# YouTube Downloader - Video dan Audio")
|
| 122 |
+
with gr.Row():
|
| 123 |
+
input_text = gr.Textbox(label="Masukkan URL YouTube")
|
| 124 |
+
download_type = gr.Radio(["Video", "Audio"], label="Pilih Format Download", value="Video")
|
| 125 |
download_button = gr.Button("Download")
|
| 126 |
+
with gr.Row():
|
| 127 |
+
thumbnail_file = gr.Image(label="Thumbnail")
|
| 128 |
+
with gr.Column():
|
| 129 |
+
output_file = gr.File(visible=False)
|
| 130 |
+
with gr.Row():
|
| 131 |
+
download_thumbnail = gr.DownloadButton(visible=False)
|
| 132 |
+
download_file = gr.DownloadButton(visible=False)
|
| 133 |
+
|
| 134 |
+
download_button.click(
|
| 135 |
+
process_input,
|
| 136 |
+
inputs=[input_text, download_type],
|
| 137 |
+
outputs=[output_file, thumbnail_file, download_file, download_thumbnail]
|
| 138 |
+
)
|
| 139 |
|
| 140 |
youtube.launch(share=True)
|