Widen thumbnail sampling window past platform bumpers
Many course platforms (Pluralsight, Packt, ...) open with a generic branded bumper animation running 10-20s before the actual course title card. The 8s candidate window landed squarely inside that bumper and grabbed the platform logo instead of anything course-specific. Candidates now spread across the first ~25s. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
2026-08-25 00:33 UTC — Widen thumbnail sampling window past platform bumpers
|
||||
2026-08-25 00:26 UTC — Fix race condition in thumbnail candidate generation
|
||||
2026-08-25 00:20 UTC — Add autoplay, progress rings, duplicate-lesson detection, title-card thumbnails
|
||||
2026-08-24 23:22 UTC — Add Favorites, storage drill-down, shortcuts, and What's New
|
||||
|
||||
@@ -1 +1 @@
|
||||
2026-08-25 00:26 UTC — fix race condition in thumbnail candidate generation
|
||||
2026-08-25 00:33 UTC — widen thumbnail sampling window past platform bumpers
|
||||
|
||||
+17
-11
@@ -926,15 +926,16 @@ def _generate_course_thumbnail(course_dir: Path) -> Optional[str]:
|
||||
added later is still picked up on the next request past the short
|
||||
in-memory cache above.
|
||||
|
||||
Course intros typically show a title card (course/lesson name, maybe
|
||||
a logo) for the first several seconds before cutting to the
|
||||
presenter - a single frame at a fixed offset can easily land past
|
||||
that cut and grab someone mid-sentence instead. Rather than guess one
|
||||
offset, this samples a handful of candidates in the first ~8 seconds
|
||||
and keeps the one with the largest resulting JPEG: a title card (text,
|
||||
graphics, a logo) compresses to a noticeably bigger file than a blank
|
||||
fade-in or a plain talking-head frame, which is a cheap enough proxy
|
||||
for "has more going on" without any real image analysis.
|
||||
Course intros typically run a branded bumper animation (10-20s on
|
||||
some platforms) followed by a title card before cutting to the
|
||||
presenter - a single frame at a fixed offset can easily land inside
|
||||
the bumper or past the cut into someone mid-sentence instead. Rather
|
||||
than guess one offset, this samples candidates spread across the
|
||||
first ~25 seconds and keeps the one with the largest resulting JPEG:
|
||||
a title card or logo (text, graphics) compresses to a noticeably
|
||||
bigger file than a blank fade-in or a plain talking-head frame, which
|
||||
is a cheap enough proxy for "has more going on" without any real
|
||||
image analysis.
|
||||
"""
|
||||
video_files = sorted(
|
||||
f for f in course_dir.rglob('*')
|
||||
@@ -945,8 +946,13 @@ def _generate_course_thumbnail(course_dir: Path) -> Optional[str]:
|
||||
source = video_files[0]
|
||||
|
||||
duration = _probe_media_duration_seconds(source) or 0
|
||||
max_offset = min(8.0, duration * 0.5) if duration else 6.0
|
||||
candidate_offsets = sorted({o for o in (1.0, 2.5, 4.0, 6.0) if o <= max_offset}) or [1.0]
|
||||
# Many course platforms (Pluralsight, Packt, ...) open with a
|
||||
# generic branded bumper animation running 10-20s before the actual
|
||||
# course title card - an 8s window landed squarely inside that
|
||||
# bumper and grabbed the platform logo instead. Spread candidates
|
||||
# further in to reach past it.
|
||||
max_offset = min(25.0, duration * 0.5) if duration else 15.0
|
||||
candidate_offsets = sorted({o for o in (2.0, 5.0, 8.0, 12.0, 16.0, 20.0, 25.0) if o <= max_offset}) or [2.0]
|
||||
|
||||
output_path = course_dir / AUTO_THUMBNAIL_FILENAME
|
||||
best_candidate = None
|
||||
|
||||
Reference in New Issue
Block a user