pytubedown / app.py
portalniy-dev's picture
Update app.py
3560597 verified
import gradio as gr
from pytube import YouTube
from pytube.exceptions import RegexMatchError, VideoUnavailable
import os
import subprocess
def download_media(url, resolution, media_format):
try:
yt = YouTube(url)
output_path = "downloads"
os.makedirs(output_path, exist_ok=True)
# Очищаем название файла от недопустимых символов
title = "".join(c for c in yt.title if c.isalnum() or c in (' ', '_')).rstrip()
if media_format == "mp3":
audio_stream = yt.streams.get_audio_only()
out_file = audio_stream.download(output_path=output_path, filename=title)
base, _ = os.path.splitext(out_file)
new_file = f"{base}.mp3"
os.rename(out_file, new_file)
return new_file
else: # mp4
if resolution in ["1080p", "4k"]:
# Для высоких разрешений
video_stream = yt.streams.filter(res=resolution, file_extension="mp4", type="video").first()
audio_stream = yt.streams.get_audio_only()
if not video_stream or not audio_stream:
raise Exception("Required streams not found")
video_path = video_stream.download(output_path=output_path, filename_prefix="video_")
audio_path = audio_stream.download(output_path=output_path, filename_prefix="audio_")
output_file = os.path.join(output_path, f"{title}.mp4")
subprocess.run([
'ffmpeg', '-i', video_path, '-i', audio_path,
'-c:v', 'copy', '-c:a', 'aac', '-strict', 'experimental',
output_file
], check=True)
os.remove(video_path)
os.remove(audio_path)
return output_file
else:
stream = yt.streams.filter(res=resolution, file_extension="mp4", progressive=True).first()
if not stream:
raise Exception("Stream not found")
return stream.download(output_path=output_path, filename=title + ".mp4")
except Exception as e:
print(f"Error: {str(e)}")
return None # Возвращаем None вместо строки с ошибкой
# Создаем интерфейс с отдельным компонентом для ошибок
with gr.Blocks() as app:
gr.Markdown("## YouTube Video Downloader")
with gr.Row():
url = gr.Textbox(label="YouTube URL")
resolution = gr.Dropdown(["144p", "360p", "720p", "1080p", "4k"], label="Resolution")
media_format = gr.Dropdown(["mp4", "mp3"], label="Format")
download_button = gr.Button("Download")
output_file = gr.File(label="Downloaded File")
error_output = gr.Textbox(label="Error Message", visible=False)
def handle_download(url, resolution, media_format):
result = download_media(url, resolution, media_format)
if result and os.path.exists(result):
return [result, gr.Textbox(visible=False)]
return [None, gr.Textbox(value="Error: Failed to download. Possible reasons:\n- Invalid URL\n- Restricted content\n- Unavailable format", visible=True)]
download_button.click(
fn=handle_download,
inputs=[url, resolution, media_format],
outputs=[output_file, error_output]
)
if __name__ == "__main__":
app.launch(share=True) # Добавлен параметр share=True