It now handles more YouTube layouts:
Classic videoRenderer, gridVideoRenderer, and compactVideoRenderer
Shorts-style reelItemRenderer
Newer lockupViewModel channel grid objects
Raw HTML fallback by extracting watch?v=, /shorts/, /embed/, and
"videoId" matches
A second scrape attempt using YouTube’s older grid query:
view=0&sort=dd&flow=grid
So instead of stopping at “no videos found” when YouTube changes the
JSON shape, it now tries multiple extraction strategies and can still
import proper YouTube embed URLs with fallback thumbnails.
Added [admin/youtube_import.php (line
1)](/Users/tyemeclifford/Documents/GH/mediaplayer/admin/youtube_import.php:1),
which:
Accepts a channel URL, @handle, or UC... channel ID.
Scrapes the channel /videos page.
Extracts videos from ytInitialData.
Shows a preview with checkboxes.
Imports selected videos into videos and video_sources.
Stores each video as a canonical YouTube watch URL with mime_type =
text/html, so the existing YouTube embed playback path handles it
correctly.
Downloads scraped thumbnails into media/thumbs/ when possible.
Skips duplicates by matching existing remote YouTube URLs.
Also wired it into the admin navigation in [admin/index.php (line
172)](/Users/tyemeclifford/Documents/GH/mediaplayer/admin/index.php:172),
[admin/add.php (line
199)](/Users/tyemeclifford/Documents/GH/mediaplayer/admin/add.php:199),
[admin/edit.php (line
267)](/Users/tyemeclifford/Documents/GH/mediaplayer/admin/edit.php:267),
and [admin/settings.php (line
109)](/Users/tyemeclifford/Documents/GH/mediaplayer/admin/settings.php:109).
Updated [README.md (line
81)](/Users/tyemeclifford/Documents/GH/mediaplayer/README.md:81) with
usage notes.