From cee4f59ea43fc6d6840b2315851503b55071d2f5 Mon Sep 17 00:00:00 2001 From: Francesco <100066266+cranci1@users.noreply.github.com> Date: Tue, 3 Jun 2025 18:06:09 +0200 Subject: [PATCH] Revert "Multi-Stream Download Support (#150)" This reverts commit c37879fa317e7659adc5104b3efea1cff7ba6422. --- .../EpisodeCell/EpisodeCell.swift | 156 ++------------- Sora/Views/MediaInfoView/MediaInfoView.swift | 186 ++++-------------- 2 files changed, 58 insertions(+), 284 deletions(-) diff --git a/Sora/Views/MediaInfoView/EpisodeCell/EpisodeCell.swift b/Sora/Views/MediaInfoView/EpisodeCell/EpisodeCell.swift index 28ddb12..4433986 100644 --- a/Sora/Views/MediaInfoView/EpisodeCell/EpisodeCell.swift +++ b/Sora/Views/MediaInfoView/EpisodeCell/EpisodeCell.swift @@ -479,156 +479,40 @@ struct EpisodeCell: View { return } - // Handle sources with headers first (more complex format) - if let sources = result.sources, !sources.isEmpty { - if sources.count > 1 { - // Multiple sources available - show selection dialog - print("[Download] Method #\(methodIndex+1) returned \(sources.count) stream sources, showing selection") - showDownloadStreamSelectionAlert(streams: sources, downloadID: downloadID, subtitleURL: result.subtitles?.first) - return - } else if let streamUrl = sources[0]["streamUrl"] as? String, let url = URL(string: streamUrl) { - // Single source - proceed directly - print("[Download] Method #\(methodIndex+1) returned valid stream URL with headers: \(streamUrl)") - - let subtitleURLString = sources[0]["subtitle"] as? String - let subtitleURL = subtitleURLString.flatMap { URL(string: $0) } - if let subtitleURL = subtitleURL { - print("[Download] Found subtitle URL: \(subtitleURL.absoluteString)") - } - - startActualDownload(url: url, streamUrl: streamUrl, downloadID: downloadID, subtitleURL: subtitleURL) - return - } - } - - // Handle simple streams array - if let streams = result.streams, !streams.isEmpty { - // Check for Promise object + if let streams = result.streams, !streams.isEmpty, let url = URL(string: streams[0]) { if streams[0] == "[object Promise]" { print("[Download] Method #\(methodIndex+1) returned a Promise object, trying next method") tryNextDownloadMethod(methodIndex: methodIndex + 1, downloadID: downloadID, softsub: softsub) return } - if streams.count > 1 { - // Multiple streams available - show selection dialog - print("[Download] Method #\(methodIndex+1) returned \(streams.count) streams, showing selection") - showDownloadStreamSelectionAlert(streams: streams, downloadID: downloadID, subtitleURL: result.subtitles?.first) - return - } else if let url = URL(string: streams[0]) { - // Single stream - proceed directly - print("[Download] Method #\(methodIndex+1) returned valid stream URL: \(streams[0])") - - let subtitleURL = result.subtitles?.first.flatMap { URL(string: $0) } - if let subtitleURL = subtitleURL { - print("[Download] Found subtitle URL: \(subtitleURL.absoluteString)") - } - - startActualDownload(url: url, streamUrl: streams[0], downloadID: downloadID, subtitleURL: subtitleURL) - return - } - } - - // No valid streams found - try next method - print("[Download] Method #\(methodIndex+1) did not return valid streams, trying next method") - tryNextDownloadMethod(methodIndex: methodIndex + 1, downloadID: downloadID, softsub: softsub) - } - - private func showDownloadStreamSelectionAlert(streams: [Any], downloadID: UUID, subtitleURL: String? = nil) { - DispatchQueue.main.async { - let alert = UIAlertController(title: "Select Download Server", message: "Choose a server to download from", preferredStyle: .actionSheet) + print("[Download] Method #\(methodIndex+1) returned valid stream URL: \(streams[0])") - var index = 0 - var streamIndex = 1 - - while index < streams.count { - var title: String = "" - var streamUrl: String = "" - - if let streams = streams as? [String] { - // Parse string array format - if index + 1 < streams.count { - if !streams[index].lowercased().contains("http") { - title = streams[index] // First element is title - streamUrl = streams[index + 1] // Second is URL - index += 2 - } else { - title = "Server \(streamIndex)" - streamUrl = streams[index] - index += 1 - } - } else { - title = "Server \(streamIndex)" - streamUrl = streams[index] - index += 1 - } - } else if let streams = streams as? [[String: Any]] { - // Parse object array format - if let currTitle = streams[index]["title"] as? String { - title = currTitle - } else { - title = "Server \(streamIndex)" - } - streamUrl = (streams[index]["streamUrl"] as? String) ?? "" - index += 1 - } - - alert.addAction(UIAlertAction(title: title, style: .default) { _ in - guard let url = URL(string: streamUrl) else { - DropManager.shared.error("Invalid stream URL selected") - self.isDownloading = false - return - } - - let subtitleURLObj = subtitleURL.flatMap { URL(string: $0) } - self.startActualDownload(url: url, streamUrl: streamUrl, downloadID: downloadID, subtitleURL: subtitleURLObj) - }) - - streamIndex += 1 + let subtitleURL = result.subtitles?.first.flatMap { URL(string: $0) } + if let subtitleURL = subtitleURL { + print("[Download] Found subtitle URL: \(subtitleURL.absoluteString)") } - alert.addAction(UIAlertAction(title: "Cancel", style: .cancel) { _ in - self.isDownloading = false - }) + startActualDownload(url: url, streamUrl: streams[0], downloadID: downloadID, subtitleURL: subtitleURL) + } else if let sources = result.sources, !sources.isEmpty, + let streamUrl = sources[0]["streamUrl"] as? String, + let url = URL(string: streamUrl) { - // Present the alert - if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene, - let window = windowScene.windows.first, - let rootVC = window.rootViewController { - - if UIDevice.current.userInterfaceIdiom == .pad { - if let popover = alert.popoverPresentationController { - popover.sourceView = window - popover.sourceRect = CGRect( - x: UIScreen.main.bounds.width / 2, - y: UIScreen.main.bounds.height / 2, - width: 0, - height: 0 - ) - popover.permittedArrowDirections = [] - } - } - - self.findTopViewController(rootVC).present(alert, animated: true) + print("[Download] Method #\(methodIndex+1) returned valid stream URL with headers: \(streamUrl)") + + let subtitleURLString = sources[0]["subtitle"] as? String + let subtitleURL = subtitleURLString.flatMap { URL(string: $0) } + if let subtitleURL = subtitleURL { + print("[Download] Found subtitle URL: \(subtitleURL.absoluteString)") } + + startActualDownload(url: url, streamUrl: streamUrl, downloadID: downloadID, subtitleURL: subtitleURL) + } else { + print("[Download] Method #\(methodIndex+1) did not return valid streams, trying next method") + tryNextDownloadMethod(methodIndex: methodIndex + 1, downloadID: downloadID, softsub: softsub) } } - private func findTopViewController(_ controller: UIViewController) -> UIViewController { - if let navigationController = controller as? UINavigationController { - return findTopViewController(navigationController.visibleViewController!) - } - if let tabController = controller as? UITabBarController { - if let selected = tabController.selectedViewController { - return findTopViewController(selected) - } - } - if let presented = controller.presentedViewController { - return findTopViewController(presented) - } - return controller - } - private func startActualDownload(url: URL, streamUrl: String, downloadID: UUID, subtitleURL: URL? = nil) { var headers: [String: String] = [:] diff --git a/Sora/Views/MediaInfoView/MediaInfoView.swift b/Sora/Views/MediaInfoView/MediaInfoView.swift index 2b33e51..e159a6c 100644 --- a/Sora/Views/MediaInfoView/MediaInfoView.swift +++ b/Sora/Views/MediaInfoView/MediaInfoView.swift @@ -1113,7 +1113,7 @@ struct MediaInfoView: View { if let sources = result.sources, !sources.isEmpty { if sources.count > 1 { - self.showStreamSelectionAlert(sources: sources, fullURL: href, subtitles: result.subtitles?.first, fetchID: fetchID) + self.showStreamSelectionAlert(streams: sources, fullURL: href, subtitles: result.subtitles?.first, fetchID: fetchID) } else if let streamUrl = sources[0]["streamUrl"] as? String { let headers = sources[0]["headers"] as? [String: String] self.playStream(url: streamUrl, fullURL: href, subtitles: result.subtitles?.first, headers: headers, fetchID: fetchID) @@ -1122,7 +1122,7 @@ struct MediaInfoView: View { } } else if let streams = result.streams, !streams.isEmpty { if streams.count > 1 { - self.showStreamSelectionAlert(sources: streams, fullURL: href, subtitles: result.subtitles?.first, fetchID: fetchID) + self.showStreamSelectionAlert(streams: streams, fullURL: href, subtitles: result.subtitles?.first, fetchID: fetchID) } else { self.playStream(url: streams[0], fullURL: href, subtitles: result.subtitles?.first, fetchID: fetchID) } @@ -1171,7 +1171,7 @@ struct MediaInfoView: View { } } - func showStreamSelectionAlert(sources: [Any], fullURL: String, subtitles: String? = nil, fetchID: UUID) { + func showStreamSelectionAlert(streams: [Any], fullURL: String, subtitles: String? = nil, fetchID: UUID) { guard self.activeFetchID == fetchID else { return } @@ -1189,41 +1189,41 @@ struct MediaInfoView: View { var index = 0 var streamIndex = 1 - while index < sources.count { + while index < streams.count { var title: String = "" var streamUrl: String = "" var headers: [String:String]? = nil - if let sources = sources as? [String] + if let streams = streams as? [String] { - if index + 1 < sources.count { - if !sources[index].lowercased().contains("http") { - title = sources[index] - streamUrl = sources[index + 1] + if index + 1 < streams.count { + if !streams[index].lowercased().contains("http") { + title = streams[index] + streamUrl = streams[index + 1] index += 2 } else { title = "Stream \(streamIndex)" - streamUrl = sources[index] + streamUrl = streams[index] index += 1 } } else { title = "Stream \(streamIndex)" - streamUrl = sources[index] + streamUrl = streams[index] index += 1 } } - else if let sources = sources as? [[String: Any]] + else if let streams = streams as? [[String: Any]] { - if let currTitle = sources[index]["title"] as? String + if let currTitle = streams[index]["title"] as? String { title = currTitle - streamUrl = (sources[index]["streamUrl"] as? String) ?? "" + streamUrl = (streams[index]["streamUrl"] as? String) ?? "" } else { title = "Stream \(streamIndex)" - streamUrl = (sources[index]["streamUrl"] as? String)! + streamUrl = (streams[index]["streamUrl"] as? String)! } - headers = sources[index]["headers"] as? [String:String] ?? [:] + headers = streams[index]["headers"] as? [String:String] ?? [:] index += 1 } @@ -1613,149 +1613,39 @@ struct MediaInfoView: View { } private func handleBulkDownloadResult(_ result: (streams: [String]?, subtitles: [String]?, sources: [[String:Any]]?), episode: EpisodeLink, methodIndex: Int, softsub: Bool, continuation: CheckedContinuation) { - - // Handle sources with headers first (more complex format) - if let sources = result.sources, !sources.isEmpty { - if sources.count > 1 { - // Multiple sources available - show selection dialog - print("[Bulk Download] Method #\(methodIndex+1) returned \(sources.count) stream sources, showing selection") - showBulkDownloadStreamSelectionAlert(sources: sources, episode: episode, continuation: continuation) - return - } else if let streamUrl = sources[0]["streamUrl"] as? String, let url = URL(string: streamUrl) { - // Single source - proceed directly - print("[Bulk Download] Method #\(methodIndex+1) returned valid stream URL with headers: \(streamUrl)") - - let subtitleURLString = sources[0]["subtitle"] as? String - let subtitleURL = subtitleURLString.flatMap { URL(string: $0) } - if let subtitleURL = subtitleURL { - print("[Bulk Download] Found subtitle URL: \(subtitleURL.absoluteString)") - } - - startEpisodeDownloadWithProcessedStream(episode: episode, url: url, streamUrl: streamUrl, subtitleURL: subtitleURL) - continuation.resume(returning: true) - return - } - } - - // Handle simple streams array - if let streams = result.streams, !streams.isEmpty { - // Check for Promise object + if let streams = result.streams, !streams.isEmpty, let url = URL(string: streams[0]) { if streams[0] == "[object Promise]" { print("[Bulk Download] Method #\(methodIndex+1) returned a Promise object, trying next method") tryNextDownloadMethodForBulk(episode: episode, methodIndex: methodIndex + 1, softsub: softsub, continuation: continuation) return } - if streams.count > 1 { - // Multiple streams available - show selection dialog - print("[Bulk Download] Method #\(methodIndex+1) returned \(streams.count) streams, showing selection") - showBulkDownloadStreamSelectionAlert(sources: streams, episode: episode, continuation: continuation) - return - } else if let url = URL(string: streams[0]) { - // Single stream - proceed directly - print("[Bulk Download] Method #\(methodIndex+1) returned valid stream URL: \(streams[0])") - - let subtitleURL = result.subtitles?.first.flatMap { URL(string: $0) } - if let subtitleURL = subtitleURL { - print("[Bulk Download] Found subtitle URL: \(subtitleURL.absoluteString)") - } - - startEpisodeDownloadWithProcessedStream(episode: episode, url: url, streamUrl: streams[0], subtitleURL: subtitleURL) - continuation.resume(returning: true) - return - } - } - - // No valid streams found - try next method - print("[Bulk Download] Method #\(methodIndex+1) did not return valid streams, trying next method") - tryNextDownloadMethodForBulk(episode: episode, methodIndex: methodIndex + 1, softsub: softsub, continuation: continuation) - } - - private func showBulkDownloadStreamSelectionAlert(sources: [Any], episode: EpisodeLink, continuation: CheckedContinuation) { - DispatchQueue.main.async { - let alert = UIAlertController(title: "Select Download Server", message: "Choose a server to download Episode \(episode.number) from", preferredStyle: .actionSheet) + print("[Bulk Download] Method #\(methodIndex+1) returned valid stream URL: \(streams[0])") - var index = 0 - var streamIndex = 1 - - while index < sources.count { - var title: String = "" - var streamUrl: String = "" - var headers: [String:String]? = nil - - if let sources = sources as? [String] { - // Parse string array format - if index + 1 < sources.count { - if !sources[index].lowercased().contains("http") { - title = sources[index] // First element is title - streamUrl = sources[index + 1] // Second is URL - index += 2 - } else { - title = "Server \(streamIndex)" - streamUrl = sources[index] - index += 1 - } - } else { - title = "Server \(streamIndex)" - streamUrl = sources[index] - index += 1 - } - } else if let sources = sources as? [[String: Any]] { - // Parse object array format - if let currTitle = sources[index]["title"] as? String { - title = currTitle - } else { - title = "Server \(streamIndex)" - } - streamUrl = (sources[index]["streamUrl"] as? String) ?? "" - index += 1 - } - - alert.addAction(UIAlertAction(title: title, style: .default) { _ in - guard let url = URL(string: streamUrl) else { - DropManager.shared.error("Invalid stream URL selected") - continuation.resume(returning: false) - return - } - - // Extract subtitle URL from the sources if available - var subtitleURL: URL? = nil - if let sources = sources as? [[String: Any]], - let subtitleURLString = sources[index-1]["subtitle"] as? String { - subtitleURL = URL(string: subtitleURLString) - } - - self.startEpisodeDownloadWithProcessedStream(episode: episode, url: url, streamUrl: streamUrl, subtitleURL: subtitleURL) - continuation.resume(returning: true) - }) - - streamIndex += 1 + let subtitleURL = result.subtitles?.first.flatMap { URL(string: $0) } + if let subtitleURL = subtitleURL { + print("[Bulk Download] Found subtitle URL: \(subtitleURL.absoluteString)") } - alert.addAction(UIAlertAction(title: "Cancel", style: .cancel) { _ in - continuation.resume(returning: false) - }) + startEpisodeDownloadWithProcessedStream(episode: episode, url: url, streamUrl: streams[0], subtitleURL: subtitleURL) + continuation.resume(returning: true) - // Present the alert - if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene, - let window = windowScene.windows.first, - let rootVC = window.rootViewController { - - if UIDevice.current.userInterfaceIdiom == .pad { - if let popover = alert.popoverPresentationController { - popover.sourceView = window - popover.sourceRect = CGRect( - x: UIScreen.main.bounds.width / 2, - y: UIScreen.main.bounds.height / 2, - width: 0, - height: 0 - ) - popover.permittedArrowDirections = [] - } - } - - findTopViewController.findViewController(rootVC).present(alert, animated: true) + } else if let sources = result.sources, !sources.isEmpty, let streamUrl = sources[0]["streamUrl"] as? String, let url = URL(string: streamUrl) { + + print("[Bulk Download] Method #\(methodIndex+1) returned valid stream URL with headers: \(streamUrl)") + + let subtitleURLString = sources[0]["subtitle"] as? String + let subtitleURL = subtitleURLString.flatMap { URL(string: $0) } + if let subtitleURL = subtitleURL { + print("[Bulk Download] Found subtitle URL: \(subtitleURL.absoluteString)") } + + startEpisodeDownloadWithProcessedStream(episode: episode, url: url, streamUrl: streamUrl, subtitleURL: subtitleURL) + continuation.resume(returning: true) + + } else { + print("[Bulk Download] Method #\(methodIndex+1) did not return valid streams, trying next method") + tryNextDownloadMethodForBulk(episode: episode, methodIndex: methodIndex + 1, softsub: softsub, continuation: continuation) } }