diff --git a/languages/ar.json b/languages/ar.json index 95cf234..e7253ea 100644 --- a/languages/ar.json +++ b/languages/ar.json @@ -39,16 +39,11 @@ "file_size": "حجم الملف", "codec": "الترميز", "audio": "الصوت", - "notes": "ملاحظات", + "fps": "إطار/ث", "will_merge_audio": "سيتم دمج الصوت", "has_audio": "✓ يحتوي على صوت", "audio_only": "صوت فقط", - "large_size": "حجم كبير", - "medium_size": "حجم متوسط", - "standard_size": "حجم قياسي", - "compatible": "متوافق", - "efficient": "فعال", - "high_quality": "جودة عالية", + "best_4k": "الأفضل (4K)", "best_2k": "الأفضل (2K)", "high_1080p": "عالية (1080p)", diff --git a/languages/de.json b/languages/de.json index e2afb9e..9f98326 100644 --- a/languages/de.json +++ b/languages/de.json @@ -39,16 +39,11 @@ "file_size": "Dateigröße", "codec": "Codec", "audio": "Audio", - "notes": "Notizen", + "fps": "FPS", "will_merge_audio": "Audio wird zusammengeführt", "has_audio": "✓ Hat Audio", "audio_only": "Nur Audio", - "large_size": "Große Größe", - "medium_size": "Mittlere Größe", - "standard_size": "Standardgröße", - "compatible": "Kompatibel", - "efficient": "Effizient", - "high_quality": "Hohe Qualität", + "best_4k": "Beste (4K)", "best_2k": "Beste (2K)", "high_1080p": "Hoch (1080p)", diff --git a/languages/en.json b/languages/en.json index f515192..bb5f6c6 100644 --- a/languages/en.json +++ b/languages/en.json @@ -39,16 +39,11 @@ "file_size": "File Size", "codec": "Codec", "audio": "Audio", - "notes": "Notes", + "fps": "FPS", "will_merge_audio": "Will merge audio", "has_audio": "✓ Has Audio", "audio_only": "Audio Only", - "large_size": "Large size", - "medium_size": "Medium size", - "standard_size": "Standard size", - "compatible": "Compatible", - "efficient": "Efficient", - "high_quality": "High quality", + "best_4k": "Best (4K)", "best_2k": "Best (2K)", "high_1080p": "High (1080p)", diff --git a/languages/es.json b/languages/es.json index 68ce558..05dbf62 100644 --- a/languages/es.json +++ b/languages/es.json @@ -132,16 +132,11 @@ "file_size": "Tamaño", "codec": "Códec", "audio": "Audio", - "notes": "Notas", + "fps": "FPS", "will_merge_audio": "Se combinará audio", "has_audio": "✓ Tiene Audio", "audio_only": "Solo Audio", - "large_size": "Tamaño grande", - "medium_size": "Tamaño mediano", - "standard_size": "Tamaño estándar", - "compatible": "Compatible", - "efficient": "Eficiente", - "high_quality": "Alta calidad", + "best_4k": "Óptima (4K)", "best_2k": "Óptima (2K)", "high_1080p": "Alta (1080p)", diff --git a/languages/fr.json b/languages/fr.json index be3cc05..365d266 100644 --- a/languages/fr.json +++ b/languages/fr.json @@ -39,16 +39,11 @@ "file_size": "Taille du fichier", "codec": "Codec", "audio": "Audio", - "notes": "Notes", + "fps": "IPS", "will_merge_audio": "L'audio sera fusionné", "has_audio": "✓ Contient de l'audio", "audio_only": "Audio uniquement", - "large_size": "Taille importante", - "medium_size": "Taille moyenne", - "standard_size": "Taille standard", - "compatible": "Compatible", - "efficient": "Efficace", - "high_quality": "Haute qualité", + "best_4k": "Meilleure (4K)", "best_2k": "Meilleure (2K)", "high_1080p": "Haute (1080p)", diff --git a/languages/hi.json b/languages/hi.json index 0daaa7a..253449e 100644 --- a/languages/hi.json +++ b/languages/hi.json @@ -39,16 +39,11 @@ "file_size": "फ़ाइल आकार", "codec": "कोडेक", "audio": "ऑडियो", - "notes": "नोट्स", + "fps": "फ्रेम दर", "will_merge_audio": "ऑडियो मर्ज किया जाएगा", "has_audio": "✓ ऑडियो है", "audio_only": "केवल ऑडियो", - "large_size": "बड़ा आकार", - "medium_size": "मध्यम आकार", - "standard_size": "मानक आकार", - "compatible": "संगत", - "efficient": "कुशल", - "high_quality": "उच्च गुणवत्ता", + "best_4k": "सर्वोत्तम (4K)", "best_2k": "सर्वोत्तम (2K)", "high_1080p": "उच्च (1080p)", diff --git a/languages/id.json b/languages/id.json index 1e0cebf..54375c6 100644 --- a/languages/id.json +++ b/languages/id.json @@ -39,16 +39,11 @@ "file_size": "Ukuran file", "codec": "Codec", "audio": "Audio", - "notes": "Catatan", + "fps": "FPS", "will_merge_audio": "Audio akan digabungkan", "has_audio": "✓ Memiliki audio", "audio_only": "Audio saja", - "large_size": "Ukuran besar", - "medium_size": "Ukuran sedang", - "standard_size": "Ukuran standar", - "compatible": "Kompatibel", - "efficient": "Efisien", - "high_quality": "Kualitas tinggi", + "best_4k": "Terbaik (4K)", "best_2k": "Terbaik (2K)", "high_1080p": "Tinggi (1080p)", diff --git a/languages/it.json b/languages/it.json index 379661b..501a5dc 100644 --- a/languages/it.json +++ b/languages/it.json @@ -39,16 +39,11 @@ "file_size": "Dimensione file", "codec": "Codec", "audio": "Audio", - "notes": "Note", + "fps": "FPS", "will_merge_audio": "L'audio verrà unito", "has_audio": "✓ Contiene audio", "audio_only": "Solo audio", - "large_size": "Dimensione grande", - "medium_size": "Dimensione media", - "standard_size": "Dimensione standard", - "compatible": "Compatibile", - "efficient": "Efficiente", - "high_quality": "Alta qualità", + "best_4k": "Migliore (4K)", "best_2k": "Migliore (2K)", "high_1080p": "Alta (1080p)", diff --git a/languages/ja.json b/languages/ja.json index 4736feb..d03c55f 100644 --- a/languages/ja.json +++ b/languages/ja.json @@ -39,16 +39,11 @@ "file_size": "ファイルサイズ", "codec": "コーデック", "audio": "音声", - "notes": "備考", + "fps": "FPS", "will_merge_audio": "音声が結合されます", "has_audio": "✓ 音声あり", "audio_only": "音声のみ", - "large_size": "大サイズ", - "medium_size": "中サイズ", - "standard_size": "標準サイズ", - "compatible": "互換性あり", - "efficient": "効率的", - "high_quality": "高品質", + "best_4k": "最高 (4K)", "best_2k": "最高 (2K)", "high_1080p": "高 (1080p)", diff --git a/languages/pl.json b/languages/pl.json index 9ac5bf3..f560a4d 100644 --- a/languages/pl.json +++ b/languages/pl.json @@ -39,16 +39,11 @@ "file_size": "Rozmiar pliku", "codec": "Kodek", "audio": "Dźwięk", - "notes": "Notatki", + "fps": "KL/S", "will_merge_audio": "Dźwięk zostanie połączony", "has_audio": "✓ Zawiera dźwięk", "audio_only": "Tylko dźwięk", - "large_size": "Duży rozmiar", - "medium_size": "Średni rozmiar", - "standard_size": "Standardowy rozmiar", - "compatible": "Zgodny", - "efficient": "Wydajny", - "high_quality": "Wysoka jakość", + "best_4k": "Najlepsza (4K)", "best_2k": "Najlepsza (2K)", "high_1080p": "Wysoka (1080p)", diff --git a/languages/pt.json b/languages/pt.json index 3e2bfd3..7f9cefe 100644 --- a/languages/pt.json +++ b/languages/pt.json @@ -39,16 +39,11 @@ "file_size": "Tamanho do Arquivo", "codec": "Codec", "audio": "Áudio", - "notes": "Notas", + "fps": "FPS", "will_merge_audio": "Irá mesclar áudio", "has_audio": "✓ Tem Áudio", "audio_only": "Apenas Áudio", - "large_size": "Tamanho grande", - "medium_size": "Tamanho médio", - "standard_size": "Tamanho padrão", - "compatible": "Compatível", - "efficient": "Eficiente", - "high_quality": "Alta qualidade", + "best_4k": "Melhor (4K)", "best_2k": "Melhor (2K)", "high_1080p": "Alta (1080p)", diff --git a/languages/ru.json b/languages/ru.json index 21bc797..9759dd2 100644 --- a/languages/ru.json +++ b/languages/ru.json @@ -39,16 +39,11 @@ "file_size": "Размер файла", "codec": "Кодек", "audio": "Аудио", - "notes": "Заметки", + "fps": "Кадр/с", "will_merge_audio": "Объединит аудио", "has_audio": "✓ Есть аудио", "audio_only": "Только аудио", - "large_size": "Большой размер", - "medium_size": "Средний размер", - "standard_size": "Стандартный размер", - "compatible": "Совместимый", - "efficient": "Эффективный", - "high_quality": "Высокое качество", + "best_4k": "Лучшее (4K)", "best_2k": "Лучшее (2K)", "high_1080p": "Высокое (1080p)", diff --git a/languages/tr.json b/languages/tr.json index 78a075e..105717a 100644 --- a/languages/tr.json +++ b/languages/tr.json @@ -39,16 +39,11 @@ "file_size": "Dosya boyutu", "codec": "Codec", "audio": "Ses", - "notes": "Notlar", + "fps": "FPS", "will_merge_audio": "Ses birleştirilecek", "has_audio": "✓ Ses var", "audio_only": "Sadece ses", - "large_size": "Büyük boyut", - "medium_size": "Orta boyut", - "standard_size": "Standart boyut", - "compatible": "Uyumlu", - "efficient": "Verimli", - "high_quality": "Yüksek kalite", + "best_4k": "En iyi (4K)", "best_2k": "En iyi (2K)", "high_1080p": "Yüksek (1080p)", diff --git a/languages/zh.json b/languages/zh.json index e49884f..3a34211 100644 --- a/languages/zh.json +++ b/languages/zh.json @@ -39,16 +39,11 @@ "file_size": "文件大小", "codec": "编解码器", "audio": "音频", - "notes": "备注", + "fps": "帧率", "will_merge_audio": "将合并音频", "has_audio": "✓ 有音频", "audio_only": "仅音频", - "large_size": "大尺寸", - "medium_size": "中等尺寸", - "standard_size": "标准尺寸", - "compatible": "兼容", - "efficient": "高效", - "high_quality": "高质量", + "best_4k": "最佳 (4K)", "best_2k": "最佳 (2K)", "high_1080p": "高清 (1080p)", diff --git a/src/gui/ytsage_gui_format_table.py b/src/gui/ytsage_gui_format_table.py index 9be5186..ecfc410 100644 --- a/src/gui/ytsage_gui_format_table.py +++ b/src/gui/ytsage_gui_format_table.py @@ -31,7 +31,7 @@ class FormatTableMixin: _("formats.file_size"), _("formats.codec"), _("formats.audio"), - _("formats.notes"), + _("formats.fps"), ] ) @@ -40,27 +40,28 @@ class FormatTableMixin: # Set specific column widths and resize modes self.format_table.horizontalHeader().setSectionResizeMode(0, QHeaderView.ResizeMode.Fixed) # Select - self.format_table.setColumnWidth(0, 80) # Select column width (increased for longer translations) + self.format_table.setColumnWidth(0, 70) # Select column width (slightly reduced) self.format_table.horizontalHeader().setSectionResizeMode(1, QHeaderView.ResizeMode.Fixed) # Quality - self.format_table.setColumnWidth(1, 100) # Quality width + self.format_table.setColumnWidth(1, 110) # Quality width (increased for better visibility) self.format_table.horizontalHeader().setSectionResizeMode(2, QHeaderView.ResizeMode.Fixed) # Extension - self.format_table.setColumnWidth(2, 80) # Extension width + self.format_table.setColumnWidth(2, 85) # Extension width (slightly increased) self.format_table.horizontalHeader().setSectionResizeMode(3, QHeaderView.ResizeMode.Fixed) # Resolution - self.format_table.setColumnWidth(3, 100) # Resolution width + self.format_table.setColumnWidth(3, 110) # Resolution width (increased for better visibility) self.format_table.horizontalHeader().setSectionResizeMode(4, QHeaderView.ResizeMode.Fixed) # File Size - self.format_table.setColumnWidth(4, 100) # File Size width + self.format_table.setColumnWidth(4, 110) # File Size width (increased for better readability) self.format_table.horizontalHeader().setSectionResizeMode(5, QHeaderView.ResizeMode.Fixed) # Codec - self.format_table.setColumnWidth(5, 150) # Codec width + self.format_table.setColumnWidth(5, 160) # Codec width (increased for codec names) self.format_table.horizontalHeader().setSectionResizeMode(6, QHeaderView.ResizeMode.Fixed) # Audio - self.format_table.setColumnWidth(6, 120) # Audio width + self.format_table.setColumnWidth(6, 140) # Audio width (increased for better text visibility) - self.format_table.horizontalHeader().setSectionResizeMode(7, QHeaderView.ResizeMode.Stretch) # Notes (will stretch) + self.format_table.horizontalHeader().setSectionResizeMode(7, QHeaderView.ResizeMode.Stretch) # FPS column stretches to fill + # FPS column will stretch to fill remaining space # Set vertical header (row numbers) visible to false self.format_table.verticalHeader().setVisible(False) @@ -185,7 +186,7 @@ class FormatTableMixin: # Configure columns based on mode if is_playlist_mode: self.format_table.setColumnCount(5) - self.format_table.setHorizontalHeaderLabels([_("formats.select"), _("formats.quality"), _("formats.resolution"), _("formats.notes"), _("formats.audio")]) + self.format_table.setHorizontalHeaderLabels([_("formats.select"), _("formats.quality"), _("formats.resolution"), _("formats.fps"), _("formats.audio")]) # Configure column visibility and resizing for playlist mode self.format_table.setColumnHidden(5, True) @@ -211,37 +212,32 @@ class FormatTableMixin: _("formats.file_size"), _("formats.codec"), _("formats.audio"), - _("formats.notes"), + _("formats.fps"), ] ) # Ensure all columns are visible for i in range(2, 8): self.format_table.setColumnHidden(i, False) - # Reapply resize modes for non-playlist mode if needed (optional, might be okay without) + # Reapply optimized resize modes for non-playlist mode self.format_table.horizontalHeader().setSectionResizeMode(0, QHeaderView.ResizeMode.Fixed) - self.format_table.setColumnWidth(0, 80) # Match the width set in setup_format_table + self.format_table.setColumnWidth(0, 70) # Match the optimized width self.format_table.horizontalHeader().setSectionResizeMode(1, QHeaderView.ResizeMode.Fixed) - self.format_table.setColumnWidth(1, 100) + self.format_table.setColumnWidth(1, 110) self.format_table.horizontalHeader().setSectionResizeMode(2, QHeaderView.ResizeMode.Fixed) - self.format_table.setColumnWidth(2, 80) + self.format_table.setColumnWidth(2, 85) self.format_table.horizontalHeader().setSectionResizeMode(3, QHeaderView.ResizeMode.Fixed) - self.format_table.setColumnWidth(3, 100) + self.format_table.setColumnWidth(3, 110) self.format_table.horizontalHeader().setSectionResizeMode(4, QHeaderView.ResizeMode.Fixed) - self.format_table.setColumnWidth(4, 100) + self.format_table.setColumnWidth(4, 110) self.format_table.horizontalHeader().setSectionResizeMode(5, QHeaderView.ResizeMode.Fixed) - self.format_table.setColumnWidth(5, 150) + self.format_table.setColumnWidth(5, 160) self.format_table.horizontalHeader().setSectionResizeMode(6, QHeaderView.ResizeMode.Fixed) - self.format_table.setColumnWidth(6, 120) + self.format_table.setColumnWidth(6, 140) self.format_table.horizontalHeader().setSectionResizeMode(7, QHeaderView.ResizeMode.Stretch) + # FPS column stretches to fill remaining space + - # Find best quality format for recommendations (only needed for non-playlist mode notes) - best_video_size = 0 - if not is_playlist_mode: - best_video_size = max( - (f.get("filesize", 0) for f in formats if f.get("vcodec") != "none"), - default=0, - ) for f in formats: row = self.format_table.rowCount() @@ -284,18 +280,30 @@ class FormatTableMixin: resolution = _("formats.audio_only_resolution") self.format_table.setItem(row, 2, QTableWidgetItem(resolution)) - # Column 3: Notes for playlist mode, Extension for normal mode + # Column 3: FPS for playlist mode, Extension for normal mode if is_playlist_mode: - # Get notes for playlist mode - notes = self._get_format_notes(f) - notes_item = QTableWidgetItem(notes) - if "✨ Recommended" in notes: - notes_item.setForeground(QColor("#00ff00")) # Green for recommended - elif "💾 Storage friendly" in notes: - notes_item.setForeground(QColor("#00ccff")) # Blue for storage friendly - elif "📱 Mobile friendly" in notes: - notes_item.setForeground(QColor("#ff9900")) # Orange for mobile - self.format_table.setItem(row, 3, notes_item) + # Get FPS for playlist mode + fps_value = f.get("fps") + if fps_value is not None: + # Format FPS value appropriately + if fps_value >= 1: + fps_text = f"{fps_value:.0f}fps" + else: + fps_text = "N/A" # Very low fps like storyboards + else: + fps_text = "N/A" + + fps_item = QTableWidgetItem(fps_text) + # Color code based on FPS value + if fps_value and fps_value >= 60: + fps_item.setForeground(QColor("#00ff00")) # Green for 60+ fps + elif fps_value and fps_value >= 30: + fps_item.setForeground(QColor("#ffaa00")) # Orange for 30+ fps + elif fps_value and fps_value >= 1: + fps_item.setForeground(QColor("#ff5555")) # Red for low fps + else: + fps_item.setForeground(QColor("#888888")) # Gray for N/A + self.format_table.setItem(row, 3, fps_item) else: # Extension for normal mode (column 2) self.format_table.setItem(row, 2, QTableWidgetItem(f.get("ext", "").upper())) @@ -332,16 +340,28 @@ class FormatTableMixin: codec += f" / {f.get('acodec', 'N/A')}" self.format_table.setItem(row, 5, QTableWidgetItem(codec)) - # Column 7: Notes - notes = self._get_format_notes(f) - notes_item = QTableWidgetItem(notes) - if "✨ Recommended" in notes: - notes_item.setForeground(QColor("#00ff00")) # Green for recommended - elif "💾 Storage friendly" in notes: - notes_item.setForeground(QColor("#00ccff")) # Blue for storage friendly - elif "📱 Mobile friendly" in notes: - notes_item.setForeground(QColor("#ff9900")) # Orange for mobile - self.format_table.setItem(row, 7, notes_item) + # Column 7: FPS (Frame Rate) + fps_value = f.get("fps") + if fps_value is not None: + # Format FPS value appropriately + if fps_value >= 1: + fps_text = f"{fps_value:.0f}fps" + else: + fps_text = "N/A" # Very low fps like storyboards + else: + fps_text = "N/A" + + fps_item = QTableWidgetItem(fps_text) + # Color code based on FPS value + if fps_value and fps_value >= 60: + fps_item.setForeground(QColor("#00ff00")) # Green for 60+ fps + elif fps_value and fps_value >= 30: + fps_item.setForeground(QColor("#ffaa00")) # Orange for 30+ fps + elif fps_value and fps_value >= 1: + fps_item.setForeground(QColor("#ff5555")) # Red for low fps + else: + fps_item.setForeground(QColor("#888888")) # Gray for N/A + self.format_table.setItem(row, 7, fps_item) def handle_checkbox_click(self, clicked_checkbox) -> None: self = cast("YTSageApp", self) # for autocompletion and type inference. @@ -402,38 +422,4 @@ class FormatTableMixin: else: return _("formats.low_quality") - def _get_format_notes(self, format_info) -> str: - """Generate helpful format notes based on format info.""" - self = cast("YTSageApp", self) # for autocompletion and type inference. - - notes = [] - # Add storage indicator with more granular categories - file_size = format_info.get("filesize") or format_info.get("filesize_approx", 0) - - # Better file size categories - if file_size > 50 * 1024 * 1024: # Over 50MB - notes.append(_("formats.large_size")) - elif file_size > 15 * 1024 * 1024: # 15-50MB - notes.append(_("formats.medium_size")) - elif file_size > 5 * 1024 * 1024: # 5-15MB - notes.append(_("formats.standard_size")) - else: # Under 5MB - notes.append("Small size") - - # Add codec quality indicator - vcodec = format_info.get("vcodec", "") - if vcodec != "none": - if "avc1" in vcodec: # H.264 - notes.append(_("formats.compatible")) - elif "av01" in vcodec: # AV1 - notes.append(_("formats.efficient")) - elif "vp9" in vcodec: # VP9 - notes.append(_("formats.high_quality")) - - # Add quick mobile compatibility check - if "avc1" in vcodec and file_size < 8 * 1024 * 1024: - notes.append("Mobile") - - # Return simple string - return " • ".join(notes)