feat: add Spanish README and improve channel/playlist handling
All checks were successful
CI / test (push) Successful in 52s

* Add complete Spanish translation (README.es.md)
* Restructure English README for clarity and conciseness
* Filter out YouTube Shorts from channel video listings (sort=4)
* Add fallback for video count using playlist metadata when API returns zero
* Add get_playlist_metadata() to fetch metadata without full video list
* Add is_short() utility to detect YouTube Shorts by duration, badges, and type
* Export is_short from yt_data_extract for use across modules
This commit is contained in:
Jesus
2026-04-12 20:20:32 -05:00
parent 550457936a
commit c6c8030907
6 changed files with 378 additions and 130 deletions

View File

@@ -1,7 +1,7 @@
from .common import (get, multi_get, deep_get, multi_deep_get,
liberal_update, conservative_update, remove_redirect, normalize_url,
extract_str, extract_formatted_text, extract_int, extract_approx_int,
extract_date, extract_item_info, extract_items, extract_response)
extract_date, extract_item_info, extract_items, extract_response, is_short)
from .everything_else import (extract_channel_info, extract_search_info,
extract_playlist_metadata, extract_playlist_info, extract_comments_info)

View File

@@ -410,6 +410,51 @@ def extract_shorts_lockup_view_model_info(item, additional_info={}):
return info
def is_short(item_info):
"""Check if a video item is a YouTube Short.
Shorts are identified by:
1. Duration < 60 seconds (typical Shorts length)
2. Having "Shorts" badge or type
3. Being extracted from shortsLockupViewModel or reelItemRenderer
"""
if not item_info or item_info.get('error'):
return False
# Check renderer type
item_type = item_info.get('type', '')
if item_type == 'unsupported':
return False
# Check for "Shorts" badge
badges = item_info.get('badges', [])
if any('short' in str(badge).lower() for badge in badges):
return True
# Check duration (Shorts are typically < 60 seconds)
duration = item_info.get('duration')
if duration is not None:
# Duration can be string like "0:58" or "1:23:45" or int
if isinstance(duration, str):
# Parse duration string to seconds
parts = duration.split(':')
try:
if len(parts) == 2: # MM:SS
duration_seconds = int(parts[0]) * 60 + int(parts[1])
elif len(parts) == 3: # HH:MM:SS
duration_seconds = int(parts[0]) * 3600 + int(parts[1]) * 60 + int(parts[2])
else:
duration_seconds = int(duration)
if duration_seconds < 60:
return True
except (ValueError, IndexError):
pass
elif isinstance(duration, (int, float)) and duration < 60:
return True
return False
def extract_item_info(item, additional_info={}):
if not item:
return {'error': 'No item given'}