mirror of
https://github.com/yattee/yattee.git
synced 2026-02-21 10:19:46 +00:00
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:
@@ -73,6 +73,9 @@ struct Instance: Identifiable, Codable, Hashable, Sendable {
|
||||
/// Whether to allow invalid/self-signed SSL certificates.
|
||||
var allowInvalidCertificates: Bool
|
||||
|
||||
/// Whether to route video streams through this instance instead of connecting directly to YouTube CDN.
|
||||
var proxiesVideos: Bool
|
||||
|
||||
// MARK: - Initialization
|
||||
|
||||
init(
|
||||
@@ -83,7 +86,8 @@ struct Instance: Identifiable, Codable, Hashable, Sendable {
|
||||
isEnabled: Bool = true,
|
||||
dateAdded: Date = Date(),
|
||||
apiKey: String? = nil,
|
||||
allowInvalidCertificates: Bool = false
|
||||
allowInvalidCertificates: Bool = false,
|
||||
proxiesVideos: Bool = false
|
||||
) {
|
||||
self.id = id
|
||||
self.type = type
|
||||
@@ -93,6 +97,20 @@ struct Instance: Identifiable, Codable, Hashable, Sendable {
|
||||
self.dateAdded = dateAdded
|
||||
self.apiKey = apiKey
|
||||
self.allowInvalidCertificates = allowInvalidCertificates
|
||||
self.proxiesVideos = proxiesVideos
|
||||
}
|
||||
|
||||
init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
id = try container.decode(UUID.self, forKey: .id)
|
||||
type = try container.decode(InstanceType.self, forKey: .type)
|
||||
url = try container.decode(URL.self, forKey: .url)
|
||||
name = try container.decodeIfPresent(String.self, forKey: .name)
|
||||
isEnabled = try container.decode(Bool.self, forKey: .isEnabled)
|
||||
dateAdded = try container.decode(Date.self, forKey: .dateAdded)
|
||||
apiKey = try container.decodeIfPresent(String.self, forKey: .apiKey)
|
||||
allowInvalidCertificates = try container.decode(Bool.self, forKey: .allowInvalidCertificates)
|
||||
proxiesVideos = try container.decodeIfPresent(Bool.self, forKey: .proxiesVideos) ?? false
|
||||
}
|
||||
|
||||
// MARK: - Computed Properties
|
||||
@@ -148,6 +166,11 @@ extension Instance {
|
||||
var supportsPopular: Bool {
|
||||
type == .invidious || type == .yatteeServer
|
||||
}
|
||||
|
||||
/// Whether this instance supports proxying video streams through itself.
|
||||
var supportsVideoProxying: Bool {
|
||||
type == .invidious || type == .piped
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Instance Validation
|
||||
|
||||
@@ -189,6 +189,32 @@ struct StreamResolution: Codable, Hashable, Sendable, Comparable, CustomStringCo
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - URL Rewriting
|
||||
|
||||
extension Stream {
|
||||
/// Creates a copy of this stream with a different URL.
|
||||
/// Used for proxying streams through an instance.
|
||||
func withURL(_ newURL: URL) -> Stream {
|
||||
Stream(
|
||||
url: newURL,
|
||||
resolution: resolution,
|
||||
format: format,
|
||||
videoCodec: videoCodec,
|
||||
audioCodec: audioCodec,
|
||||
bitrate: bitrate,
|
||||
fileSize: fileSize,
|
||||
isAudioOnly: isAudioOnly,
|
||||
isLive: isLive,
|
||||
mimeType: mimeType,
|
||||
audioLanguage: audioLanguage,
|
||||
audioTrackName: audioTrackName,
|
||||
isOriginalAudio: isOriginalAudio,
|
||||
httpHeaders: httpHeaders,
|
||||
fps: fps
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Preview Data
|
||||
|
||||
extension Stream {
|
||||
|
||||
Reference in New Issue
Block a user