Skip to content

Fix media resolution and interactive login on the Chrome/CDP path - #1

Open
yingzhouquan3-art wants to merge 6 commits into
cimu233:mainfrom
yingzhouquan3-art:fix/windows-headless-media
Open

Fix media resolution and interactive login on the Chrome/CDP path#1
yingzhouquan3-art wants to merge 6 commits into
cimu233:mainfrom
yingzhouquan3-art:fix/windows-headless-media

Conversation

@yingzhouquan3-art

Copy link
Copy Markdown

Four fixes found while archiving a purchased course on Windows 11, where
there is no Ego browser to fall back on. Each commit stands alone.

1. httpproxy missing from the HLS protocol whitelist

With http_proxy/https_proxy set, every HLS download failed:

Protocol 'httpproxy' not on whitelist 'file,http,https,tcp,tls,crypto'

2. Unexpected download failures lost their cause

The catch-all recorded only the exception class, so a real failure read
Unexpected download failure: FileNotFoundError with no indication of
which path was missing. Now the message and failing frame are kept.

3. Media sources were never resolved in the CDP path

A headless player issues no media request without a user gesture, so
_media_urls observed nothing and lessons failed with "No playable
audio or HLS request was observed."
The Ego path already reads
getPlayUrl; the Chrome/CDP path did not.

This records getPlayUrl and get_lookback_list via an XHR/fetch hook
installed before navigation, then feeds the signed URLs through the
existing _synthetic_media_events path. Audio-only mp3 is preferred
where offered, since it needs no HLS assembly.

It also skips liveplay.* hosts while sniffing: a finished live lesson
still advertises its push-stream URL, which 404s, and it would otherwise
win over the replay playlist behind get_lookback_list.

Verified on a 50-lesson course: video lessons resolve to mp3 direct
links, live replays to their playlist_eof.m3u8.

4. auth start --visible

ensure_running() overwrote its own visible argument, so the managed
browser was always headless. Without a window there is no way to finish
a QR-code or SMS login on a platform with no Ego session to inherit.

The default is unchanged — automation still never steals the foreground
application. Only the explicit auth start --visible opens a window.

Testing

pytest tests gives 63 failed / 102 passed / 5 errors both before and
after these commits, i.e. no new failures. The pre-existing failures look
environment-related (the suite assumes macOS paths); happy to look into
them separately if useful.

yingzhouquan3-art and others added 6 commits August 28, 2026 20:16
ffmpeg opens HLS through a proxy when http_proxy/https_proxy are set in
the environment, but the protocol whitelist did not list httpproxy, so it
refused every playlist with:

    Protocol 'httpproxy' not on whitelist 'file,http,https,tcp,tls,crypto'

Downloading behind a corporate or local proxy therefore always failed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The catch-all handler recorded only the exception class name, so a
lesson that failed with FileNotFoundError gave no hint about which path
was missing. Record the exception message and the failing frame as well,
capped so the column stays readable.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A headless player never issues a real media request without a user
gesture, so _media_urls observed no .m3u8/.mp3 traffic and every lesson
failed with "No playable audio or HLS request was observed." The Ego
browser path already reads getPlayUrl, but the Chrome/CDP path did not.

Record the getPlayUrl and get_lookback_list responses through an
XHR/fetch hook installed before navigation, and feed the signed URLs
they carry through the existing _synthetic_media_events path. Audio-only
mp3 is preferred where offered: it needs no HLS assembly.

Also skip liveplay.* hosts when sniffing responses. A finished live
lesson still advertises its push-stream URL, which 404s, and it would
otherwise win over the replay playlist behind get_lookback_list.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
ensure_running() overwrote its own visible argument, so the managed
browser was always headless. On platforms with no Ego browser to inherit
a session from, that leaves no way to complete a QR-code or SMS login:
the window needed to scan the code never appears.

Honour the argument instead, and let requested_mode report it so an
existing session of the wrong mode is restarted. The default is
unchanged - only "auth start --visible" asks for a window, so automation
still never steals the user's foreground application.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Audio lessons (/p/course/audio/a_...) never expose a media request the
sniffer can see, so they failed with "No playable audio or HLS request
was observed." Their source sits in the audio.info.get response, whose
data.audio_info.audio_url is already a direct mp3.

Record that endpoint alongside getPlayUrl and get_lookback_list — the Ego
path's own capture pattern lists it too, so the CDP path was the only one
missing it.

Also mark PLAY_URL_RECORDER as a raw string: the JS regex it now carries
contains \. escapes, which Python flags as invalid escape sequences.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The assertion pinned requested_mode to "headless" for both inputs, which
encoded the old always-headless behaviour. With visible honoured as an
opt-in, the contract is that it reports what was requested.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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