add format, title
This commit is contained in:
parent
e3fbb24ef4
commit
6f0ca29327
@ -1,4 +1,3 @@
|
||||
|
||||
import logging
|
||||
import traceback
|
||||
from threading import Thread
|
||||
@ -36,7 +35,7 @@ class Downloader:
|
||||
def __init__(self):
|
||||
self.progress_callback: Optional[Callable[[int], None]] = None
|
||||
self.completion_callback: Optional[Callable[[Optional[str]], None]] = None
|
||||
self.formats_callback: Optional[Callable[[Optional[List[VideoFormat]]], None]] = None
|
||||
self.formats_callback: Optional[Callable[[Optional[Dict[str, Any]], Optional[List[VideoFormat]]], None]] = None
|
||||
|
||||
def _progress_hook(self, d: Dict[str, Any]):
|
||||
if d["status"] == "downloading":
|
||||
@ -48,16 +47,21 @@ class Downloader:
|
||||
logger.info("yt-dlp finished downloading.")
|
||||
|
||||
def _get_formats_task(self, url: str):
|
||||
"""Task to fetch video formats in a thread."""
|
||||
"""Task to fetch video formats and info in a thread."""
|
||||
try:
|
||||
logger.info(f"Fetching formats for URL: {url}")
|
||||
ydl_opts = {"noplaylist": True}
|
||||
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
|
||||
info = ydl.extract_info(url, download=False)
|
||||
|
||||
video_info = {
|
||||
"title": info.get("title", "N/A"),
|
||||
"uploader": info.get("uploader", "N/A"),
|
||||
"duration_string": info.get("duration_string", "N/A"),
|
||||
}
|
||||
|
||||
formats = []
|
||||
for f in info.get("formats", []):
|
||||
# We are interested in mp4 files that have video
|
||||
if f.get("vcodec", "none") != "none" and f.get("ext") == "mp4":
|
||||
note = "Progressive" if f.get("acodec", "none") != "none" else "Video Only"
|
||||
formats.append(VideoFormat(
|
||||
@ -68,21 +72,20 @@ class Downloader:
|
||||
note=note
|
||||
))
|
||||
|
||||
# Sort formats: progressive first, then by resolution
|
||||
formats.sort(key=lambda x: (x.note != "Progressive", -int(x.resolution.replace("p", "")) if x.resolution.replace("p", "").isdigit() else 0))
|
||||
|
||||
logger.info(f"Found {len(formats)} suitable formats.")
|
||||
if self.formats_callback:
|
||||
self.formats_callback(formats)
|
||||
self.formats_callback(video_info, formats)
|
||||
|
||||
except Exception as e:
|
||||
error_message = f"Failed to fetch formats: {e}"
|
||||
logger.error(error_message)
|
||||
logger.debug(traceback.format_exc())
|
||||
if self.formats_callback:
|
||||
self.formats_callback(None) # Indicate failure
|
||||
self.formats_callback(None, None) # Indicate failure
|
||||
|
||||
def get_video_formats(self, url: str, formats_callback: Callable[[Optional[List[VideoFormat]]], None]):
|
||||
def get_video_formats(self, url: str, formats_callback: Callable[[Optional[Dict[str, Any]], Optional[List[VideoFormat]]], None]):
|
||||
"""Starts the format fetching process in a new thread."""
|
||||
self.formats_callback = formats_callback
|
||||
thread = Thread(target=self._get_formats_task, args=(url,), daemon=True)
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
|
||||
import logging
|
||||
import tkinter as tk
|
||||
from tkinter import ttk, filedialog, messagebox
|
||||
from tkinter.scrolledtext import ScrolledText
|
||||
from typing import Optional, List
|
||||
from typing import Optional, List, Dict, Any
|
||||
|
||||
from downloaderyoutube.core.core import Downloader, VideoFormat
|
||||
from downloaderyoutube.utils.logger import add_tkinter_handler, get_logger
|
||||
@ -35,8 +36,13 @@ class App(tk.Frame):
|
||||
self.download_path: Optional[str] = None
|
||||
self.available_formats: List[VideoFormat] = []
|
||||
|
||||
# StringVars for video info labels
|
||||
self.title_var = tk.StringVar(value="Titolo: N/A")
|
||||
self.uploader_var = tk.StringVar(value="Autore: N/A")
|
||||
self.duration_var = tk.StringVar(value="Durata: N/A")
|
||||
|
||||
self.master.title("YouTube Downloader")
|
||||
self.master.geometry("800x600")
|
||||
self.master.geometry("800x650") # Increased height for new info panel
|
||||
|
||||
self.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
|
||||
|
||||
@ -57,6 +63,14 @@ class App(tk.Frame):
|
||||
)
|
||||
self.analyze_button.pack(side=tk.LEFT, padx=(5, 0))
|
||||
|
||||
# --- Video Info Panel ---
|
||||
info_frame = ttk.LabelFrame(self, text="Informazioni Video")
|
||||
info_frame.pack(fill=tk.X, pady=5, padx=2)
|
||||
|
||||
ttk.Label(info_frame, textvariable=self.title_var).pack(anchor="w", padx=5)
|
||||
ttk.Label(info_frame, textvariable=self.uploader_var).pack(anchor="w", padx=5)
|
||||
ttk.Label(info_frame, textvariable=self.duration_var).pack(anchor="w", padx=5)
|
||||
|
||||
# --- Path Frame ---
|
||||
path_frame = ttk.Frame(self)
|
||||
path_frame.pack(fill=tk.X, pady=5)
|
||||
@ -120,25 +134,35 @@ class App(tk.Frame):
|
||||
self.analyze_button.config(state="disabled")
|
||||
self.download_button.config(state="disabled")
|
||||
self.format_combobox.set("Analisi in corso...")
|
||||
self.title_var.set("Titolo: Analisi in corso...")
|
||||
self.uploader_var.set("Autore: Analisi in corso...")
|
||||
self.duration_var.set("Durata: Analisi in corso...")
|
||||
self.downloader.get_video_formats(url, self._on_formats_received)
|
||||
|
||||
def _on_formats_received(self, formats: Optional[List[VideoFormat]]):
|
||||
# This is called from a different thread, so we schedule GUI updates
|
||||
self.master.after(0, self._update_formats_combobox, formats)
|
||||
def _on_formats_received(self, video_info: Optional[Dict[str, Any]], formats: Optional[List[VideoFormat]]):
|
||||
self.master.after(0, self._update_ui_after_analysis, video_info, formats)
|
||||
|
||||
def _update_formats_combobox(self, formats: Optional[List[VideoFormat]]):
|
||||
def _update_ui_after_analysis(self, video_info: Optional[Dict[str, Any]], formats: Optional[List[VideoFormat]]):
|
||||
self.analyze_button.config(state="normal")
|
||||
if formats:
|
||||
logger.info("Successfully fetched formats. Populating combobox.")
|
||||
if video_info and formats:
|
||||
logger.info("Successfully fetched video info and formats.")
|
||||
self.title_var.set(f"Titolo: {video_info['title']}")
|
||||
self.uploader_var.set(f"Autore: {video_info['uploader']}")
|
||||
self.duration_var.set(f"Durata: {video_info['duration_string']}")
|
||||
|
||||
self.available_formats = formats
|
||||
self.format_combobox["values"] = [str(f) for f in formats]
|
||||
self.format_combobox.current(0)
|
||||
self.format_combobox.config(state="readonly")
|
||||
self.download_button.config(state="normal")
|
||||
else:
|
||||
logger.error("Failed to fetch video formats.")
|
||||
messagebox.showerror("Error", "Could not retrieve video formats. Check the URL and logs.")
|
||||
logger.error("Failed to fetch video info or formats.")
|
||||
messagebox.showerror("Error", "Could not retrieve video information. Check the URL and logs.")
|
||||
self.format_combobox.set("Analisi fallita.")
|
||||
self.format_combobox["values"] = []
|
||||
self.title_var.set("Titolo: N/A")
|
||||
self.uploader_var.set("Autore: N/A")
|
||||
self.duration_var.set("Durata: N/A")
|
||||
|
||||
def start_download(self):
|
||||
url = self.url_entry.get()
|
||||
|
||||
Loading…
Reference in New Issue
Block a user