parseAudioInfo() returned isOriginal=false for all streams when the
audioTrack object was present in the API response, preventing xtags
parsing from correctly identifying original tracks. This caused the
player to fall through to codec/bitrate sorting, often picking a
locale dub (e.g. Polish) instead of the original English audio.
Now determines isOriginal from both the audioTrack displayName
("original" keyword) and URL xtags (acont=original) for robustness.
Also adds isDefault to InvidiousAudioTrack for future use.
- InstanceDetector: a single 401 from one probe was over-eagerly concluded
as "credentials invalid" / "credentials required". On instances behind a
reverse proxy where one probe path (e.g. Yattee Server's /info) hits a
same-origin redirect, iOS URLSession strips the Authorization header on
the redirect and the request 401s even with valid credentials. Track 401s
across all probes and only conclude basicAuthRequired/basicAuthInvalid
when no probe matched and at least one returned 401.
- InstanceLoginView: the Invidious/Piped login flow constructed an API
client backed by the shared appEnvironment.httpClient, which has no
per-instance basic-auth headers. For instances behind a reverse proxy,
the login POST 401d before reaching the upstream login endpoint. Build a
per-instance HTTPClient with the basic-auth Authorization header baked in
via setDefaultHeaders, mirroring ContentService.httpClientWithBasicAuth.
- InvidiousAPI.login: the login function constructs its own URLSession (to
capture Set-Cookie via a redirect-blocking delegate), so it never
inherits headers from the injected httpClient. Add an optional
extraHeaders parameter and have InstanceLoginView pass the basic-auth
header through when present. PipedAPI.login uses httpClient.fetch and
inherits defaultHeaders correctly, so no change is needed there.
Adds a "Proxy videos" toggle in instance settings that routes video
streams through the instance instead of connecting directly to YouTube
CDN. Includes auto-detection of 403 blocks and live re-application of
proxy settings without requiring app restart or video reload.
Use URLComponents/URLQueryItem for standard form-URL encoding instead
of manual percent-encoding with CharacterSet.alphanumerics, which
included non-ASCII Unicode letters and had an unsafe raw-value fallback.
Playlists only loaded the first page of videos. Add full pagination for
both Invidious and Piped playlist endpoints (public and authenticated).
Deduplicate Invidious results by playlist index to handle its overlapping
page windows. Also fix URL encoding in Invidious login to use strict
form-encoding charset.