Add video proxy support with live toggle for Invidious/Piped instances

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.
This commit is contained in:
Arkadiusz Fal
2026-02-16 19:40:55 +01:00
parent 1fa6d7a4a5
commit c8b4ae5422
9 changed files with 305 additions and 4 deletions

View File

@@ -34,6 +34,7 @@ private struct EditRemoteServerContent: View {
@State private var name: String
@State private var isEnabled: Bool
@State private var allowInvalidCertificates: Bool
@State private var proxiesVideos: Bool
// Yattee Server credentials
@State private var yatteeServerUsername: String = ""
@@ -68,6 +69,7 @@ private struct EditRemoteServerContent: View {
_name = State(initialValue: instance.name ?? "")
_isEnabled = State(initialValue: instance.isEnabled)
_allowInvalidCertificates = State(initialValue: instance.allowInvalidCertificates)
_proxiesVideos = State(initialValue: instance.proxiesVideos)
}
var body: some View {
@@ -266,6 +268,23 @@ private struct EditRemoteServerContent: View {
Text(String(localized: "sources.footer.allowInvalidCertificates"))
}
if instance.supportsVideoProxying {
Section {
#if os(tvOS)
TVSettingsToggle(
title: String(localized: "sources.field.proxiesVideos"),
isOn: $proxiesVideos
)
#else
Toggle(String(localized: "sources.field.proxiesVideos"), isOn: $proxiesVideos)
#endif
} header: {
Text(String(localized: "sources.header.proxy"))
} footer: {
Text(String(localized: "sources.footer.proxiesVideos"))
}
}
Section {
Button {
testConnection()
@@ -413,6 +432,7 @@ private struct EditRemoteServerContent: View {
updated.name = name.isEmpty ? nil : name
updated.isEnabled = isEnabled
updated.allowInvalidCertificates = allowInvalidCertificates
updated.proxiesVideos = proxiesVideos
// Save Yattee Server credentials if provided
if instance.type == .yatteeServer && !yatteeServerUsername.isEmpty && !yatteeServerPassword.isEmpty {