| name | icourse-live-localhost |
| description | Diagnose Fudan iCourse live-room access failures, verify whether a lecture is truly live, extract the active stream endpoints, and expose the stream on localhost for playback. Use when a user provides an `icourse.fudan.edu.cn/livingroom` or `livingpage` link, reports that a live room cannot be entered, sees replay-related or playback-timing errors during a live class, or wants the current iCourse stream proxied to localhost. |
iCourse Live Localhost
Use this skill for the full path from an iCourse live-room URL to local playback:
- Parse the live-room URL.
- Login to WebVPN + iCourse CAS.
- Verify permission vs real stream availability.
- Identify the correct active
sub_id when the provided link is stale.
- Proxy the live HLS stream to
127.0.0.1.
Preconditions
- Credentials are available in env:
- A local checkout of a compatible iCourse client repo is available. It must provide:
main.login_with_retry()
src.icourse.ICourseClient
- If the user has the Fudan iCourse Subscriber repo, pass its path through
--subscriber-repo or set ICOURSE_SUBSCRIBER_REPO.
If the user also needs the login workflow extracted into its own repo, cite the elearning-login skill or publish it separately after sanitizing credentials and local paths.
Quick Start
Parse the incoming URL:
python scripts\parse_icourse_live_url.py "https://icourse.fudan.edu.cn/livingroom?course_id=<course_id>&sub_id=<sub_id>&tenant_code=<tenant_code>"
Launch the localhost proxy:
$env:StuId=$env:uis
$env:UISPsw=$env:uis_psw
python scripts\local_icourse_live_proxy.py --subscriber-repo <path-to-icourse-subscriber-repo> --course-id <course_id> --sub-id <sub_id> --host 127.0.0.1 --port 8765
Open:
http://127.0.0.1:8765/
http://127.0.0.1:8765/stream.m3u8
Workflow
1. Parse the incoming URL
Extract:
course_id
sub_id
tenant_code
Do not trust a pasted sub_id blindly. iCourse live lectures often rotate to a new sub_id for each teaching week.
2. Login with the existing iCourse client
Prefer the existing repo implementation instead of reimplementing CAS/WebVPN:
from main import login_with_retry
from src.icourse import ICourseClient
vpn = login_with_retry(max_attempts=5)
client = ICourseClient(vpn)
This establishes:
- WebVPN session
- iCourse CAS session
- authenticated API access for course detail, live status, and stream discovery
3. Separate permission from playability
Check both:
- Permission endpoint:
/coursesourceapi/course/study-auth/{course_id}/{sub_id}
- Lecture live info endpoint:
/courseapi/v3/portal-home-setting/get-sub-info?course_id=...&sub_id=...
If permission returns hasPermission=true, userPermission=true, and videoPermission=true, that only means the account is allowed to view the lecture. It does not prove that a live stream URL exists.
The real source of truth for local playback is get-sub-info.
4. Interpret get-sub-info
Inspect:
sub_status
sub_review_type
start_at
end_at
now
live_url
playurl
Status interpretation:
sub_status = 1: live in progress
sub_status = 2: live starting or transitional
sub_status = 3: replay generating
sub_status = 5: no replay
sub_status = 6: replay available
Decision rules:
- If
sub_status in {1,2} and live_url.output.m3u8 or live_url.output.flv exists, the class is truly live.
- If permission is true but
live_url is absent and playurl is empty, report a server/resource issue rather than an auth issue.
- If the provided
sub_id is stale, query course detail and find the active lecture by date/title/status instead of retrying the stale link.
5. Handle iCourse frontend false negatives
Old /livingroom frontend logic can show replay-timing errors and redirect back to the course list even while the lecture is actually live.
When API data shows:
sub_status = 1
live_url.output.m3u8 exists
then treat website playback failure as a frontend routing/player issue and continue with localhost proxying.
6. Proxy to localhost
Use the bundled script:
python scripts\local_icourse_live_proxy.py --subscriber-repo <path-to-icourse-subscriber-repo> --course-id <course_id> --sub-id <sub_id>
The proxy:
- logs into iCourse through the subscriber repo
- fetches current
live_url.output
- serves a local HTML player on
/
- serves a rewritten HLS manifest on
/stream.m3u8
- rewrites segment URLs through
/hls?...
- binds to
127.0.0.1 by default
Validation checks:
http://127.0.0.1:8765/status
http://127.0.0.1:8765/stream.m3u8
If /stream.m3u8 returns a playlist whose media lines are rewritten to /hls?url=..., the proxy is functioning.
7. Confirm segment fetches
Also fetch one rewritten media segment and verify:
- HTTP
200
- reasonable
Content-Type, usually video/mp2t
- non-trivial body size
If a segment fetch works, localhost playback should work in browser or VLC.
Recovery Rules
- If login fails, stop and report the exact failed login stage.
- If
study-auth says true but get-sub-info has no live URL, report a stream/resource issue.
- If the URL points to an old lecture, search the course detail for the current active lecture.
- If browser playback fails but localhost HLS works, prefer localhost playback and note the iCourse frontend issue.