Skip to content

feat(web-player): copy media links with middle-click - #737

Merged
stackia merged 8 commits into
mainfrom
cursor/copy-media-direct-link-77d2
Sep 2, 2026
Merged

feat(web-player): copy media links with middle-click#737
stackia merged 8 commits into
mainfrom
cursor/copy-media-direct-link-77d2

Conversation

@stackia

@stackia stackia commented Sep 2, 2026

Copy link
Copy Markdown
Owner

Summary

Middle-click a channel in the channel list, or a program in the EPG, to copy a directly requestable HTTP media URL. A toast confirms success.

This addresses the download workflow in #718: IDM cannot sniff MSE playback, but users can now copy the live or catch-up URL into FFmpeg, N_m3u8DL-RE, IDM, or another player.

Copied multicast and RTSP links also include r2h-filename. The daemon emits Content-Disposition: attachment on MPEG-TS responses so a browser download uses a friendly .ts name (channel, source label, program title, time range). The parameter is local to rtp2httpd: it is stripped before upstream RTP/RTSP/HTTP requests and is ignored by HLS/HTTP proxying.

Rebased onto latest main so this shares catch-up helpers from #736:

  • Playback segments and copied program links both call buildCatchupUrl (extracted from the nested parser copy)
  • Copied program windows reuse CATCHUP_MIN_DURATION_MS / CatchupProgramBound from catchup-windows.ts
  • Copy still emits a single program [start, end] URL; it does not use planCatchupSegmentWindows (that planner is for multi-chunk playback)

Behavior:

  • Channel middle-click copies the live URL of the current/last-used source
  • Program middle-click copies the catch-up URL for that program's time range (playseek placeholders filled)
  • On-air programs without catch-up copy the live URL
  • Copied URLs are absolute, $label suffixes are stripped, and r2h-token is preserved when present on the page
  • Copied live/catch-up URLs include r2h-filename; multicast HEAD/GET and RTSP HEAD/GET return Content-Disposition
  • Simple appearance toasts use a dedicated light/dark surface instead of the always-dark video overlay background

Test plan

  • Open /player with a playlist that has live channels and catch-up + EPG
  • Middle-click a channel: toast “Media link copied”, clipboard contains the live HTTP URL with r2h-filename
  • In light + simple, the toast background is light (not slate-900); dark + simple and light + fancy stay as before
  • Middle-click a past/on-air catch-up program: clipboard contains the catch-up URL with that program’s time range and a filename that includes the title/time range
  • Open the copied URL in a browser (or curl -I): Content-Disposition uses the .ts name
  • Middle-click a future program without catch-up: error toast, clipboard unchanged
  • Confirm left-click still selects/plays as before (playback URLs do not add r2h-filename)
  • If the player URL has r2h-token, confirm the copied link includes it
  • pnpm run web-ui:test covers buildCatchupUrl, getProgramMediaUrl, filename sanitizing, and r2h-filename
  • ./scripts/run-e2e.sh covers multicast/RTSP Content-Disposition, header injection sanitizing, empty param omission, and HTTP/RTSP upstream stripping
Open in Web Open in Cursor 

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Documentation preview

The documentation preview has been deployed for this pull request.

@stackia
stackia marked this pull request as ready for review September 2, 2026 09:08

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 74c0b43. Configure here.

Comment thread web-ui/src/lib/media-direct-link.ts
Middle-click a channel to copy its live URL, or a program to copy the
catch-up URL for that timeslot, then show a toast on success.

Co-authored-by: Stackie Jia <jsq2627@gmail.com>
@cursor
cursor Bot force-pushed the cursor/copy-media-direct-link-77d2 branch from 74c0b43 to f68b881 Compare September 2, 2026 09:44
cursoragent and others added 7 commits September 2, 2026 09:44
Co-authored-by: Stackie Jia <jsq2627@gmail.com>
Drop the copy-media-link bullet from the features list; the dedicated section already covers it.

Co-authored-by: Stackie Jia <jsq2627@gmail.com>
Middle-click copy is a hidden gesture; the button title delayed native tooltip on hover.

Co-authored-by: Stackie Jia <jsq2627@gmail.com>
Append-mode copy concatenated `$HD` onto the live path before the query.
Stripping treated `$HD?playseek=…` as one label and dropped the time range.

Co-authored-by: Stackie Jia <jsq2627@gmail.com>
Copied media links now carry a friendly r2h-filename query parameter.
Multicast and RTSP MPEG-TS responses emit Content-Disposition so browsers
save the file with a .ts name. The parameter is stripped before upstream
requests and ignored by HTTP/HLS proxying.

Co-authored-by: Stackie Jia <jsq2627@gmail.com>
strcasecmp() was reading past the sanitized filename, so names that
already ended in .ts could pick up a second suffix.

Co-authored-by: Stackie Jia <jsq2627@gmail.com>
Simple theme was reusing the video overlay background, which is always
slate-900. Give toasts their own semantic surface so light+simple stays
light while dark+simple and fancy are unchanged.

Co-authored-by: Stackie Jia <jsq2627@gmail.com>
@stackia
stackia merged commit 337d827 into main Sep 2, 2026
11 checks passed
@stackia
stackia deleted the cursor/copy-media-direct-link-77d2 branch September 2, 2026 11:34
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.

2 participants