Request playback with non-site player types and swap to backup Usher streams on stitched ad breaks; inject vendored vaft into the legacy WebView and expose a Settings toggle. Co-authored-by: Cursor <cursoragent@cursor.com>
35 lines
1.7 KiB
Markdown
35 lines
1.7 KiB
Markdown
# Design: Twitch ad blocking (vaft) in Frosty fork
|
|
|
|
## Intent
|
|
|
|
Personal Forgejo fork of Frosty blocks Twitch live ads using [TwitchAdSolutions vaft](https://github.com/pixeltris/TwitchAdSolutions) ideas, adapted to Flutter.
|
|
|
|
## Upstream baseline
|
|
|
|
Frosty **did not** ship an adblocker. The native player only **detects** stitched ad breaks (`adBreakStream`) to avoid bad latency/stall recovery. Turbo/sub may get `hide_ads` via linked web GQL session — server-side, not client blocking.
|
|
|
|
## Strategy
|
|
|
|
### Native player (primary — this is the reliable path)
|
|
|
|
1. When `SettingsStore.blockTwitchAds` is true, request `PlaybackAccessToken` with `playerType=popout` (vaft `ForceAccessTokenPlayerType`) instead of `site`.
|
|
2. When the native plugin reports an ad break, resolve a backup Usher URL trying `embed` → `popout` → `autoplay`, preferring playlists whose media m3u8 does not contain `stitched`, then `loadUrl` that stream.
|
|
3. When the ad break ends, restore the primary popout URL.
|
|
4. Overlay shows “Blocking ads” while `_blockingAds` is true.
|
|
|
|
Implementation: `lib/apis/twitch_ad_solutions.dart`, `lib/apis/twitch_gql_api.dart`, `lib/screens/channel/video/native_video_store.dart`.
|
|
|
|
### WebView player (legacy, best-effort)
|
|
|
|
Inject vendored `assets/js/vaft.user.js` on page start/finish. Not true `@run-at document-start` on Android via `webview_flutter`, so native remains preferred. Enabling adblock in Settings forces native on.
|
|
|
|
## Settings
|
|
|
|
- `blockTwitchAds` (default `true`)
|
|
- Turning adblock on sets `useNativePlayer = true`
|
|
|
|
## Non-goals
|
|
|
|
- Upstream PR
|
|
- Full browser Worker prototype rewriting on native
|
|
- Third-party CDN proxies unless player-type swap proves insufficient
|