Ajout d'une barre de progréssion lors du chargement des méthadonnées
This commit is contained in:
parent
be93154128
commit
84bd38eb30
180
main.py
180
main.py
@ -4,69 +4,137 @@ import requests
|
|||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from tkinter import *
|
from tkinter import *
|
||||||
from PIL import Image, ImageTk
|
from PIL import Image, ImageTk
|
||||||
|
from tkinter.ttk import Progressbar
|
||||||
|
import threading
|
||||||
|
import queue
|
||||||
|
|
||||||
def add_url():
|
def add_url():
|
||||||
|
|
||||||
|
#Ajoute un classe pour intercepter les logs
|
||||||
|
class YTDLLogger:
|
||||||
|
"""
|
||||||
|
Logger personnalisé pour capturer et afficher les messages de yt-dlp.
|
||||||
|
"""
|
||||||
|
def debug(self, msg):
|
||||||
|
print(msg) # Affiche les messages de debug
|
||||||
|
ProgresseLabel.config(text=msg)
|
||||||
|
|
||||||
|
def warning(self, msg):
|
||||||
|
print(f"WARNING: {msg}") # Affiche les avertissements
|
||||||
|
|
||||||
|
def error(self, msg):
|
||||||
|
print(f"ERROR: {msg}") # Affiche les erreurs
|
||||||
|
|
||||||
|
#Récuperer l'url
|
||||||
url = EntryURL.get()
|
url = EntryURL.get()
|
||||||
|
|
||||||
ydl_opts = {}
|
|
||||||
|
|
||||||
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
|
|
||||||
info = ydl.extract_info(url, download=False)
|
|
||||||
|
|
||||||
title = info.get('title', 'Titre indisponible')
|
|
||||||
subtitlte = (
|
|
||||||
info.get('artist', info.get('uploader', 'Artiste indisponible'))
|
|
||||||
+ ' · '
|
|
||||||
+ '{:,}'.format(info.get('view_count', 'Nombre de vue indisponible')).replace(',', ' ')
|
|
||||||
+ ' vues'
|
|
||||||
)
|
|
||||||
thumbnail_url = info.get('thumbnail')
|
|
||||||
|
|
||||||
response = requests.get(thumbnail_url)
|
|
||||||
image = Image.open(BytesIO(response.content))
|
|
||||||
width, height = image.size
|
|
||||||
|
|
||||||
# Découper l'image en un carré centré
|
|
||||||
square_size = min(width, height)
|
|
||||||
left = (width - square_size) // 2
|
|
||||||
top = (height - square_size) // 2
|
|
||||||
|
|
||||||
# Calculer les coordonnées du coin inférieur droit du carré
|
|
||||||
right = left + square_size
|
|
||||||
bottom = top + square_size
|
|
||||||
|
|
||||||
# Découper l'image carrée
|
|
||||||
image = image.crop((left, top, right, bottom))
|
|
||||||
image.thumbnail((50, 50))
|
|
||||||
|
|
||||||
# Création d'un cadre pour chaque vidéo
|
|
||||||
cadre = Frame(scrollable_frame)
|
|
||||||
cadre.pack(fill=X, padx=10, pady=5)
|
|
||||||
|
|
||||||
# Charger l'image et l'afficher
|
|
||||||
image = ImageTk.PhotoImage(image)
|
|
||||||
image_label = Label(cadre, image=image)
|
|
||||||
image_label.image = image # Préserver la référence pour éviter le garbage collection
|
|
||||||
image_label.pack(side=LEFT, padx=5)
|
|
||||||
|
|
||||||
# Ajouter les titres
|
|
||||||
texte_frame = Frame(cadre)
|
|
||||||
texte_frame.pack(side=LEFT, padx=10, fill=BOTH, expand=True)
|
|
||||||
|
|
||||||
label_texte1 = Label(texte_frame, text=title, font=("Arial", 12, "bold"))
|
|
||||||
label_texte1.pack(anchor="w")
|
|
||||||
|
|
||||||
label_texte2 = Label(texte_frame, text=subtitlte, font=("Arial", 10))
|
|
||||||
label_texte2.pack(anchor="w")
|
|
||||||
|
|
||||||
# Ajouter un bouton "Supprimer"
|
|
||||||
menu_button = Button(cadre, text="Supprimer", relief=FLAT, command=cadre.destroy)
|
|
||||||
menu_button.pack(side=RIGHT)
|
|
||||||
|
|
||||||
# Effacer l'entrée URL
|
# Effacer l'entrée URL
|
||||||
EntryURL.delete(0, END)
|
EntryURL.delete(0, END)
|
||||||
|
|
||||||
|
ydl_opts = {
|
||||||
|
'quiet': True, # Supprime la sortie standard (redirigée vers le logger)
|
||||||
|
'logger': YTDLLogger(), # Utilise le logger personnalisé
|
||||||
|
}
|
||||||
|
|
||||||
|
# Queue pour recuperer les donnes
|
||||||
|
q = queue.Queue()
|
||||||
|
|
||||||
|
# Fonction qui exécute le téléchargement dans un thread séparé
|
||||||
|
def process_download():
|
||||||
|
try:
|
||||||
|
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
|
||||||
|
info = ydl.extract_info(url, download=False) # Extraire les métadonnées sans télécharger
|
||||||
|
q.put(info) # Mettre l'info dans la queue pour être récupérée par le thread principal
|
||||||
|
except Exception as e:
|
||||||
|
q.put(f"Erreur : {str(e)}") # Mettre l'erreur dans la queue
|
||||||
|
finally:
|
||||||
|
progress_windows.after(2000, progress_windows.destroy) # Fermer la fenêtre de progression après 2s
|
||||||
|
|
||||||
|
# Fonction pour vérifier la queue et mettre à jour l'interface
|
||||||
|
def check_queue():
|
||||||
|
try:
|
||||||
|
# Essayer de récupérer l'info sans bloquer
|
||||||
|
info = q.get_nowait()
|
||||||
|
|
||||||
|
if isinstance(info, dict): # Si l'info est un dictionnaire (métadonnées)
|
||||||
|
ProgresseLabel.config(text=f"Dowloading complet")
|
||||||
|
title = info.get('title', 'Titre indisponible')
|
||||||
|
subtitlte = (
|
||||||
|
info.get('artist', info.get('uploader', 'Artiste indisponible'))
|
||||||
|
+ ' · '
|
||||||
|
+ '{:,}'.format(info.get('view_count', 'Nombre de vue indisponible')).replace(',', ' ')
|
||||||
|
+ ' vues'
|
||||||
|
)
|
||||||
|
thumbnail_url = info.get('thumbnail')
|
||||||
|
|
||||||
|
response = requests.get(thumbnail_url)
|
||||||
|
image = Image.open(BytesIO(response.content))
|
||||||
|
width, height = image.size
|
||||||
|
|
||||||
|
# Découper l'image en un carré centré
|
||||||
|
square_size = min(width, height)
|
||||||
|
left = (width - square_size) // 2
|
||||||
|
top = (height - square_size) // 2
|
||||||
|
|
||||||
|
# Calculer les coordonnées du coin inférieur droit du carré
|
||||||
|
right = left + square_size
|
||||||
|
bottom = top + square_size
|
||||||
|
|
||||||
|
# Découper l'image carrée
|
||||||
|
image = image.crop((left, top, right, bottom))
|
||||||
|
image.thumbnail((50, 50))
|
||||||
|
|
||||||
|
# Création d'un cadre pour chaque vidéo
|
||||||
|
cadre = Frame(scrollable_frame)
|
||||||
|
cadre.pack(fill=X, padx=10, pady=5)
|
||||||
|
|
||||||
|
# Charger l'image et l'afficher
|
||||||
|
image = ImageTk.PhotoImage(image)
|
||||||
|
image_label = Label(cadre, image=image)
|
||||||
|
image_label.image = image # Préserver la référence pour éviter le garbage collection
|
||||||
|
image_label.pack(side=LEFT, padx=5)
|
||||||
|
|
||||||
|
# Ajouter les titres
|
||||||
|
texte_frame = Frame(cadre)
|
||||||
|
texte_frame.pack(side=LEFT, padx=10, fill=BOTH, expand=True)
|
||||||
|
|
||||||
|
label_texte1 = Label(texte_frame, text=title, font=("Arial", 12, "bold"))
|
||||||
|
label_texte1.pack(anchor="w")
|
||||||
|
|
||||||
|
label_texte2 = Label(texte_frame, text=subtitlte, font=("Arial", 10))
|
||||||
|
label_texte2.pack(anchor="w")
|
||||||
|
|
||||||
|
# Ajouter un bouton "Supprimer"
|
||||||
|
menu_button = Button(cadre, text="Supprimer", relief=FLAT, command=cadre.destroy)
|
||||||
|
menu_button.pack(side=RIGHT)
|
||||||
|
else: # Si c'est une erreur
|
||||||
|
ProgresseLabel.config(text=info)
|
||||||
|
|
||||||
|
progress_windows.after(2000, progress_windows.destroy) # Fermer après 2s
|
||||||
|
|
||||||
|
except queue.Empty: # Si la queue est vide, vérifier à nouveau
|
||||||
|
progress_windows.after(100, check_queue)
|
||||||
|
|
||||||
|
# Création de la fenêtre de progression
|
||||||
|
progress_windows = Toplevel(root)
|
||||||
|
|
||||||
|
# Barre de progression et label
|
||||||
|
progressBarMetahdonne = Progressbar(progress_windows, orient=HORIZONTAL, length=400, mode='indeterminate')
|
||||||
|
progressBarMetahdonne.pack(side=TOP)
|
||||||
|
progressBarMetahdonne.start()
|
||||||
|
|
||||||
|
ProgresseLabel = Label(progress_windows, text="Téléchargement")
|
||||||
|
ProgresseLabel.pack(side=BOTTOM)
|
||||||
|
|
||||||
|
# Démarrer le téléchargement dans un thread séparé
|
||||||
|
thread = threading.Thread(target=process_download, daemon=True)
|
||||||
|
thread.start()
|
||||||
|
|
||||||
|
# Lancer la vérification périodique de la queue
|
||||||
|
check_queue()
|
||||||
|
|
||||||
|
# Mainloop Tkinter
|
||||||
|
root.mainloop()
|
||||||
|
|
||||||
# Fenêtre principale
|
# Fenêtre principale
|
||||||
root = Tk()
|
root = Tk()
|
||||||
root.title("Téléchargeur YouTube")
|
root.title("Téléchargeur YouTube")
|
||||||
|
Loading…
Reference in New Issue
Block a user