Skip to content

[YoutubeBridge] Add option to skip members-only videos#5019

Open
polybjorn wants to merge 1 commit into
RSS-Bridge:masterfrom
polybjorn:youtube-skip-members-only-pr
Open

[YoutubeBridge] Add option to skip members-only videos#5019
polybjorn wants to merge 1 commit into
RSS-Bridge:masterfrom
polybjorn:youtube-skip-members-only-pr

Conversation

@polybjorn

Copy link
Copy Markdown
Contributor

Adds an opt-in skip_members_only checkbox, default off. When enabled, videos that require a paid channel membership are dropped from the feed. With it off the feed is unchanged, so existing users see no difference.

Members-only videos show up in a channel's listing but can't be played without a membership, so they're noise in a feed reader. This lets people who don't want them filter them out.

The filter has to live in this bridge rather than FilterBridge: membership status isn't in the title or description, only in a BADGE_MEMBERS_ONLY badge in YouTube's raw JSON. Members-only items use the lockupViewModel layout (the one parsed since #4982), so wrapLockupViewModel returns null for any item carrying that badge, which drops it.

Only the JSON path is affected (the one used when duration_min/duration_max is set). The Atom path already filters members-only server-side and ignores the parameter.

Test plan

Ran the bridge locally against a channel that currently surfaces members-only content (LMG, channel id UCXuqSBlHAE6Xw-yeJA0Tunw) on the JSON path:

  • Without the flag: 30 items.
  • With &skip_members_only=on: 23 items, the 7 members-only videos dropped and nothing else changed.

Cross-checked the 7 dropped ids against the BADGE_MEMBERS_ONLY markers in that channel's ytInitialData: exact match. php -l passes.

Adds an opt-in checkbox parameter `skip_members_only`, default off. When
enabled, items in the lockupViewModel JSON shape that carry a
`BADGE_MEMBERS_ONLY` badge are dropped, since they require a paid channel
membership to watch. With the option off the feed is unchanged.

Only affects the JSON path (when duration_min/duration_max is set); the
Atom path relies on YouTube's server-side filtering and ignores it.
@github-actions

Copy link
Copy Markdown

Pull request artifacts

Bridge Context Status
Youtube 1 By username (current) ✔️
Youtube 1 By username (pr) ✔️
Youtube 2 By channel id (current) ✔️
Youtube 2 By channel id (pr) ✔️
Youtube 3 By custom name (current) ✔️
Youtube 3 By custom name (pr) ✔️
Youtube 4 By playlist Id (current) Bridge returned error 0! (20633)
Type: ErrorException
Message: Undefined property: stdClass::$playlistVideoListRenderer
Youtube 4 By playlist Id (pr) Bridge returned error 0! (20633)
Type: ErrorException
Message: Undefined property: stdClass::$playlistVideoListRenderer
Youtube 5 Search result (current) ✔️
Youtube 5 Search result (pr) ✔️

last change: Monday 2026-06-29 18:03:58

@polybjorn
polybjorn marked this pull request as ready for review June 29, 2026 18:08
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