Yt2mp3 / app.py
13ze's picture
Create app.py
e04c725 verified
# app.py
import gradio as gr
from pytube import YouTube
import moviepy.editor as mp
import os
import re
import time # Para nomes de arquivos únicos
# Função para limpar o nome do arquivo
def sanitize_filename(filename):
# Remove caracteres inválidos para nomes de arquivo no Windows/Linux/Mac
sanitized = re.sub(r'[\\/*?:"<>|]', "", filename)
# Limita o comprimento para evitar problemas
return sanitized[:100]
# Função principal que baixa e converte
def baixar_audio_youtube(youtube_url):
try:
print(f"Processando URL: {youtube_url}")
yt = YouTube(youtube_url)
# 1. Filtrar e selecionar o melhor stream de áudio
# Prioriza streams 'mp4' ou 'webm' que moviepy geralmente lida bem
audio_stream = yt.streams.filter(only_audio=True).order_by('abr').desc().first()
if not audio_stream:
print("Erro: Nenhum stream de áudio encontrado.")
return "Erro: Nenhuma stream de áudio encontrada para este vídeo.", None
print(f"Título: {yt.title}")
print(f"Stream selecionado: {audio_stream}")
# 2. Baixar o áudio
print("Baixando áudio...")
# Cria um nome de arquivo temporário seguro e único
temp_filename_base = sanitize_filename(yt.title)
timestamp = int(time.time())
# Usa a extensão correta do stream baixado (geralmente mp4 ou webm para áudio)
ext = audio_stream.mime_type.split('/')[-1]
temp_download_path = f"{temp_filename_base}_{timestamp}.{ext}"
audio_stream.download(filename=temp_download_path)
print(f"Áudio baixado para: {temp_download_path}")
# 3. Converter para MP3 usando moviepy
print("Convertendo para MP3...")
mp3_filename = f"{temp_filename_base}_{timestamp}.mp3"
# Garante que o arquivo MP3 de destino não exista (embora improvável com timestamp)
if os.path.exists(mp3_filename):
os.remove(mp3_filename)
audio_clip = mp.AudioFileClip(temp_download_path)
# codec='libmp3lame' é geralmente o encoder padrão e de boa qualidade para MP3
audio_clip.write_audiofile(mp3_filename, codec='libmp3lame')
audio_clip.close() # Libera o arquivo
print(f"Convertido com sucesso para: {mp3_filename}")
# 4. Limpar o arquivo temporário baixado
try:
os.remove(temp_download_path)
print(f"Arquivo temporário removido: {temp_download_path}")
except OSError as e:
print(f"Aviso: Não foi possível remover o arquivo temporário {temp_download_path}. Erro: {e}")
# 5. Retornar o caminho para o arquivo MP3 para o Gradio
# Gradio serve o arquivo a partir do diretório onde o script roda
return f"Sucesso! Áudio '{yt.title}' pronto.", mp3_filename
except Exception as e:
print(f"Ocorreu um erro: {e}")
# Tenta limpar arquivos parciais se existirem
if 'temp_download_path' in locals() and os.path.exists(temp_download_path):
try:
os.remove(temp_download_path)
except OSError: pass # Ignora erro na limpeza
if 'mp3_filename' in locals() and os.path.exists(mp3_filename):
try:
os.remove(mp3_filename)
except OSError: pass # Ignora erro na limpeza
return f"Ocorreu um erro: {str(e)}. Verifique o link ou tente novamente.", None
# --- Interface Gradio ---
with gr.Blocks() as iface:
gr.Markdown(
"""
# Baixar Áudio do YouTube em MP3
Cole o link (URL) de um vídeo do YouTube abaixo para extrair e baixar o áudio em formato MP3.
"""
)
with gr.Row():
youtube_link_input = gr.Textbox(label="Link do Vídeo do YouTube", placeholder="Ex: https://www.youtube.com/watch?v=...")
with gr.Row():
submit_button = gr.Button("Baixar e Converter para MP3")
with gr.Row():
status_output = gr.Textbox(label="Status", interactive=False)
with gr.Row():
mp3_output_file = gr.File(label="Download do Arquivo MP3") # Use gr.File para permitir download
submit_button.click(
fn=baixar_audio_youtube,
inputs=youtube_link_input,
outputs=[status_output, mp3_output_file] # Mapeia os retornos para os componentes de saída
)
gr.Examples(
[["https://www.youtube.com/watch?v=dQw4w9WgXcQ"],
["https://www.youtube.com/watch?v=kJQP7kiw5Fk"]],
inputs=youtube_link_input
)
# Lançar a interface (necessário para rodar localmente ou no Hugging Face Spaces)
if __name__ == "__main__":
iface.launch()