Skip to content

feat(config): resolve media URLs + URL timestamps in config-driven video (parity with quick playback)#38

Merged
kfox merged 1 commit into
mainfrom
feat/config-url-resolution-parity
Jun 24, 2026
Merged

feat(config): resolve media URLs + URL timestamps in config-driven video (parity with quick playback)#38
kfox merged 1 commit into
mainfrom
feat/config-url-resolution-parity

Conversation

@kfox

@kfox kfox commented Jun 24, 2026

Copy link
Copy Markdown
Owner

Why

A video scene's file only accepted local paths or direct media URLs in config mode. A YouTube (or any yt-dlp) page URL was passed straight to PyAV, which failed at playback with ffmpeg's cryptic Invalid data found when processing input. yt-dlp resolution (and the ?t= start-offset parsing) only happened in the positional c64cast MEDIA… quick-playback path. This brings the two interfaces to parity.

What

[[scenes]]
type = "video"
file = "https://youtu.be/<id>?t=18m18s"   # resolved at load; starts at 18:18
  • One shared resolverquickcast.resolve_video_url (yt-dlp resolution +
    audio-only rejection + t=/start=/#t= timestamp). config.build_scene
    calls it for a single-URL video file, folding the URL timestamp into
    start_s (an explicit start_s still wins) and using the resolved title as
    the scene name. Local file / dir / glob / multi specs are untouched.
  • Single resolution sitequickcast.classify_url no longer pre-resolves;
    it stores the URL verbatim and parses the timestamp offline, so resolution
    happens once, in build_scene, for both the positional path and configs.
  • Better diagnostics--doctor and config load now flag (offline) a
    single URL that needs yt-dlp when the yt extra is missing, with an install
    hint, instead of the runtime ffmpeg failure. Direct media URLs need no extra.

Docs

CLAUDE.md (quickcast + config sections), docs/usage.md (type = "video"), and
the example TOML document URL file specs + the timestamp behavior.

Tests

  • resolve_video_url (video tuple / audio rejection), url_needs_ytdlp.
  • build_scene URL resolution: stream URL + timestamp→start_s + title→name;
    explicit start_s wins; audio-only rejected. (yt-dlp + network faked.)
  • Offline yt-extra doctor check: rejected without the extra, passes with it,
    direct URLs exempt.

Full suite green; schema unchanged (no new field).

…deo (parity with quick playback)

A video scene's `file` could only be a local path or a direct media URL in
config mode — a YouTube/etc. page was handed straight to PyAV and failed with
ffmpeg's "Invalid data found". Now config-driven video resolves URLs the same
way quick playback does, so both interfaces behave identically.

- quickcast.resolve_video_url is the single, shared resolver (yt-dlp resolution
  + audio-only rejection + t=/start=/#t= timestamp). build_scene calls it for a
  single-URL video `file`, folding the URL timestamp into start_s (an explicit
  start_s wins) and using the resolved title as the scene name.
- quickcast.classify_url no longer pre-resolves: it stores the URL verbatim and
  parses the timestamp offline, so resolution happens once, in build_scene, for
  both the positional MEDIA path and configs.
- --doctor / config load now flag (offline) a single URL that needs yt-dlp when
  the `yt` extra is missing, with an install hint — instead of the cryptic
  runtime ffmpeg failure. Direct media URLs need no extra.

Docs (CLAUDE.md, usage.md, example TOML) updated. Tests: shared resolver,
url_needs_ytdlp, build_scene URL resolution + timestamp/title wiring, and the
offline yt-extra doctor check.
@kfox kfox merged commit 77067af into main Jun 24, 2026
5 checks passed
@kfox kfox deleted the feat/config-url-resolution-parity branch June 24, 2026 01:33
@codecov

codecov Bot commented Jun 24, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 84.84848% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 79.55%. Comparing base (e37cbee) to head (f79233b).
⚠️ Report is 2 commits behind head on main.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
c64cast/config.py 86.36% 1 Missing and 2 partials ⚠️
c64cast/quickcast.py 81.81% 2 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main      #38   +/-   ##
=======================================
  Coverage   79.54%   79.55%           
=======================================
  Files          68       68           
  Lines       12817    12847   +30     
  Branches     1889     1896    +7     
=======================================
+ Hits        10195    10220   +25     
- Misses       2185     2188    +3     
- Partials      437      439    +2     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant