mirror of
https://github.com/cranci1/Sora.git
synced 2026-03-11 17:45:37 +00:00
Error fixes, Player blur fixed, Crash fixed too?
This commit is contained in:
parent
5835a6ef8f
commit
d6c6e4a1aa
4 changed files with 240 additions and 183 deletions
|
|
@ -997,9 +997,10 @@ class CustomMediaPlayerViewController: UIViewController, UIGestureRecognizerDele
|
|||
}
|
||||
|
||||
private func createCircularBlurBackground(size: CGFloat) -> UIView {
|
||||
let blurEffect = UIBlurEffect(style: .systemMaterial)
|
||||
let blurEffect = UIBlurEffect(style: .systemUltraThinMaterialDark)
|
||||
let blurView = UIVisualEffectView(effect: blurEffect)
|
||||
blurView.translatesAutoresizingMaskIntoConstraints = false
|
||||
blurView.alpha = 0.7
|
||||
blurView.layer.cornerRadius = size / 2
|
||||
blurView.clipsToBounds = true
|
||||
|
||||
|
|
@ -1388,9 +1389,10 @@ class CustomMediaPlayerViewController: UIViewController, UIGestureRecognizerDele
|
|||
holdSpeedIndicator.setTitleColor(.white, for: .normal)
|
||||
holdSpeedIndicator.alpha = 0.0
|
||||
|
||||
let blurEffect = UIBlurEffect(style: .systemUltraThinMaterial)
|
||||
let blurEffect = UIBlurEffect(style: .systemUltraThinMaterialDark)
|
||||
let blurView = UIVisualEffectView(effect: blurEffect)
|
||||
blurView.translatesAutoresizingMaskIntoConstraints = false
|
||||
blurView.alpha = 0.7
|
||||
blurView.layer.cornerRadius = 21
|
||||
blurView.clipsToBounds = true
|
||||
|
||||
|
|
@ -3804,8 +3806,9 @@ class GradientBlurButton: UIButton {
|
|||
}
|
||||
|
||||
private func setupBlurAndGradient() {
|
||||
let blur = UIVisualEffectView(effect: UIBlurEffect(style: .systemUltraThinMaterial))
|
||||
let blur = UIVisualEffectView(effect: UIBlurEffect(style: .systemUltraThinMaterialDark))
|
||||
blur.isUserInteractionEnabled = false
|
||||
blur.alpha = 0.7
|
||||
blur.layer.cornerRadius = 21
|
||||
blur.clipsToBounds = true
|
||||
blur.translatesAutoresizingMaskIntoConstraints = false
|
||||
|
|
|
|||
|
|
@ -31,71 +31,89 @@ extension JSController {
|
|||
}
|
||||
|
||||
Logger.shared.log(html, type: "HTMLStrings")
|
||||
if let parseFunction = self.context.objectForKeyedSubscript("extractStreamUrl"),
|
||||
let resultString = parseFunction.call(withArguments: [html]).toString() {
|
||||
if let data = resultString.data(using: .utf8) {
|
||||
do {
|
||||
if let json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
|
||||
var streamUrls: [String]? = nil
|
||||
var subtitleUrls: [String]? = nil
|
||||
var streamUrlsAndHeaders : [[String:Any]]? = nil
|
||||
if let streamSources = json["streams"] as? [[String:Any]]
|
||||
{
|
||||
streamUrlsAndHeaders = streamSources
|
||||
Logger.shared.log("Found \(streamSources.count) streams and headers", type: "Stream")
|
||||
}
|
||||
else if let streamSource = json["stream"] as? [String:Any]
|
||||
{
|
||||
streamUrlsAndHeaders = [streamSource]
|
||||
Logger.shared.log("Found single stream with headers", type: "Stream")
|
||||
}
|
||||
else if let streamsArray = json["streams"] as? [String] {
|
||||
streamUrls = streamsArray
|
||||
Logger.shared.log("Found \(streamsArray.count) streams", type: "Stream")
|
||||
} else if let streamUrl = json["stream"] as? String {
|
||||
streamUrls = [streamUrl]
|
||||
Logger.shared.log("Found single stream", type: "Stream")
|
||||
}
|
||||
|
||||
if let subsArray = json["subtitles"] as? [String] {
|
||||
subtitleUrls = subsArray
|
||||
Logger.shared.log("Found \(subsArray.count) subtitle tracks", type: "Stream")
|
||||
} else if let subtitleUrl = json["subtitles"] as? String {
|
||||
subtitleUrls = [subtitleUrl]
|
||||
Logger.shared.log("Found single subtitle track", type: "Stream")
|
||||
}
|
||||
|
||||
Logger.shared.log("Starting stream with \(streamUrls?.count ?? 0) sources and \(subtitleUrls?.count ?? 0) subtitles", type: "Stream")
|
||||
DispatchQueue.main.async {
|
||||
completion((streamUrls, subtitleUrls,streamUrlsAndHeaders))
|
||||
}
|
||||
return
|
||||
|
||||
guard let parseFunction = self.context.objectForKeyedSubscript("extractStreamUrl") else {
|
||||
Logger.shared.log("extractStreamUrl function not found in JavaScript context", type: "Error")
|
||||
DispatchQueue.main.async { completion((nil, nil, nil)) }
|
||||
return
|
||||
}
|
||||
|
||||
let result = parseFunction.call(withArguments: [html])
|
||||
|
||||
if let exception = self.context.exception {
|
||||
Logger.shared.log("JavaScript exception in extractStreamUrl: \(exception)", type: "Error")
|
||||
self.context.exception = nil
|
||||
DispatchQueue.main.async { completion((nil, nil, nil)) }
|
||||
return
|
||||
}
|
||||
|
||||
guard let result = result, !result.isNull, !result.isUndefined else {
|
||||
Logger.shared.log("extractStreamUrl returned null or undefined", type: "Error")
|
||||
DispatchQueue.main.async { completion((nil, nil, nil)) }
|
||||
return
|
||||
}
|
||||
|
||||
guard let resultString = result.toString() else {
|
||||
Logger.shared.log("Failed to convert JavaScript result to string", type: "Error")
|
||||
DispatchQueue.main.async { completion((nil, nil, nil)) }
|
||||
return
|
||||
}
|
||||
|
||||
if resultString == "[object Promise]" {
|
||||
Logger.shared.log("Received Promise object instead of resolved value, waiting for proper resolution", type: "Stream")
|
||||
DispatchQueue.main.async { completion((nil, nil, nil)) }
|
||||
return
|
||||
}
|
||||
|
||||
if let data = resultString.data(using: .utf8) {
|
||||
do {
|
||||
if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
|
||||
var streamUrls: [String]? = nil
|
||||
var subtitleUrls: [String]? = nil
|
||||
var streamUrlsAndHeaders : [[String:Any]]? = nil
|
||||
|
||||
if let streamSources = json["streams"] as? [[String:Any]] {
|
||||
streamUrlsAndHeaders = streamSources
|
||||
Logger.shared.log("Found \(streamSources.count) streams and headers", type: "Stream")
|
||||
} else if let streamSource = json["stream"] as? [String:Any] {
|
||||
streamUrlsAndHeaders = [streamSource]
|
||||
Logger.shared.log("Found single stream with headers", type: "Stream")
|
||||
} else if let streamsArray = json["streams"] as? [String] {
|
||||
streamUrls = streamsArray
|
||||
Logger.shared.log("Found \(streamsArray.count) streams", type: "Stream")
|
||||
} else if let streamUrl = json["stream"] as? String {
|
||||
streamUrls = [streamUrl]
|
||||
Logger.shared.log("Found single stream", type: "Stream")
|
||||
}
|
||||
|
||||
if let streamsArray = try? JSONSerialization.jsonObject(with: data, options: []) as? [String] {
|
||||
Logger.shared.log("Starting multi-stream with \(streamsArray.count) sources", type: "Stream")
|
||||
DispatchQueue.main.async { completion((streamsArray, nil,nil)) }
|
||||
return
|
||||
if let subsArray = json["subtitles"] as? [String] {
|
||||
subtitleUrls = subsArray
|
||||
Logger.shared.log("Found \(subsArray.count) subtitle tracks", type: "Stream")
|
||||
} else if let subtitleUrl = json["subtitles"] as? String {
|
||||
subtitleUrls = [subtitleUrl]
|
||||
Logger.shared.log("Found single subtitle track", type: "Stream")
|
||||
}
|
||||
|
||||
Logger.shared.log("Starting stream with \(streamUrls?.count ?? 0) sources and \(subtitleUrls?.count ?? 0) subtitles", type: "Stream")
|
||||
DispatchQueue.main.async {
|
||||
completion((streamUrls, subtitleUrls, streamUrlsAndHeaders))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if let streamsArray = try JSONSerialization.jsonObject(with: data, options: []) as? [String] {
|
||||
Logger.shared.log("Starting multi-stream with \(streamsArray.count) sources", type: "Stream")
|
||||
DispatchQueue.main.async { completion((streamsArray, nil, nil)) }
|
||||
return
|
||||
}
|
||||
} catch {
|
||||
Logger.shared.log("JSON parsing error: \(error.localizedDescription)", type: "Error")
|
||||
}
|
||||
|
||||
// Check if the result is a Promise object and handle it properly
|
||||
if resultString == "[object Promise]" {
|
||||
Logger.shared.log("Received Promise object instead of resolved value, waiting for proper resolution", type: "Stream")
|
||||
// Skip this result - other methods will provide the resolved URL
|
||||
let workItem = DispatchWorkItem { completion((nil, nil, nil)) }
|
||||
DispatchQueue.main.async(execute: workItem)
|
||||
return
|
||||
}
|
||||
|
||||
Logger.shared.log("Starting stream from: \(resultString)", type: "Stream")
|
||||
let workItem = DispatchWorkItem { completion(([resultString], nil, nil)) }
|
||||
DispatchQueue.main.async(execute: workItem)
|
||||
} else {
|
||||
Logger.shared.log("Failed to extract stream URL", type: "Error")
|
||||
let workItem = DispatchWorkItem { completion((nil, nil, nil)) }
|
||||
DispatchQueue.main.async(execute: workItem)
|
||||
}
|
||||
|
||||
Logger.shared.log("Starting stream from: \(resultString)", type: "Stream")
|
||||
DispatchQueue.main.async {
|
||||
completion(([resultString], nil, nil))
|
||||
}
|
||||
}.resume()
|
||||
}
|
||||
|
|
@ -123,81 +141,98 @@ extension JSController {
|
|||
let thenBlock: @convention(block) (JSValue) -> Void = { [weak self] result in
|
||||
guard self != nil else { return }
|
||||
|
||||
if let jsonString = result.toString(),
|
||||
let data = jsonString.data(using: .utf8) {
|
||||
do {
|
||||
if let json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
|
||||
var streamUrls: [String]? = nil
|
||||
var subtitleUrls: [String]? = nil
|
||||
var streamUrlsAndHeaders : [[String:Any]]? = nil
|
||||
if let streamSources = json["streams"] as? [[String:Any]]
|
||||
{
|
||||
streamUrlsAndHeaders = streamSources
|
||||
Logger.shared.log("Found \(streamSources.count) streams and headers", type: "Stream")
|
||||
}
|
||||
else if let streamSource = json["stream"] as? [String:Any]
|
||||
{
|
||||
streamUrlsAndHeaders = [streamSource]
|
||||
Logger.shared.log("Found single stream with headers", type: "Stream")
|
||||
}
|
||||
else if let streamsArray = json["streams"] as? [String] {
|
||||
streamUrls = streamsArray
|
||||
Logger.shared.log("Found \(streamsArray.count) streams", type: "Stream")
|
||||
} else if let streamUrl = json["stream"] as? String {
|
||||
streamUrls = [streamUrl]
|
||||
Logger.shared.log("Found single stream", type: "Stream")
|
||||
}
|
||||
|
||||
if let subsArray = json["subtitles"] as? [String] {
|
||||
subtitleUrls = subsArray
|
||||
Logger.shared.log("Found \(subsArray.count) subtitle tracks", type: "Stream")
|
||||
} else if let subtitleUrl = json["subtitles"] as? String {
|
||||
subtitleUrls = [subtitleUrl]
|
||||
Logger.shared.log("Found single subtitle track", type: "Stream")
|
||||
}
|
||||
|
||||
Logger.shared.log("Starting stream with \(streamUrls?.count ?? 0) sources and \(subtitleUrls?.count ?? 0) subtitles", type: "Stream")
|
||||
DispatchQueue.main.async {
|
||||
completion((streamUrls, subtitleUrls,streamUrlsAndHeaders))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if let streamsArray = try? JSONSerialization.jsonObject(with: data, options: []) as? [String] {
|
||||
Logger.shared.log("Starting multi-stream with \(streamsArray.count) sources", type: "Stream")
|
||||
DispatchQueue.main.async { completion((streamsArray, nil,nil)) }
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let streamUrl = result.toString()
|
||||
Logger.shared.log("Starting stream from: \(streamUrl ?? "nil")", type: "Stream")
|
||||
|
||||
// Check if the result is a Promise object and handle it properly
|
||||
if streamUrl == "[object Promise]" {
|
||||
Logger.shared.log("Received Promise object instead of resolved value, waiting for proper resolution", type: "Stream")
|
||||
// Skip this result - other methods will provide the resolved URL
|
||||
if result.isNull || result.isUndefined {
|
||||
Logger.shared.log("Received null or undefined result from JavaScript", type: "Error")
|
||||
DispatchQueue.main.async { completion((nil, nil, nil)) }
|
||||
return
|
||||
}
|
||||
|
||||
if let resultString = result.toString(), resultString == "[object Promise]" {
|
||||
Logger.shared.log("Received Promise object instead of resolved value, waiting for proper resolution", type: "Stream")
|
||||
return
|
||||
}
|
||||
|
||||
guard let jsonString = result.toString() else {
|
||||
Logger.shared.log("Failed to convert JSValue to string", type: "Error")
|
||||
DispatchQueue.main.async { completion((nil, nil, nil)) }
|
||||
return
|
||||
}
|
||||
|
||||
guard let data = jsonString.data(using: .utf8) else {
|
||||
Logger.shared.log("Failed to convert string to data", type: "Error")
|
||||
DispatchQueue.main.async { completion((nil, nil, nil)) }
|
||||
return
|
||||
}
|
||||
|
||||
do {
|
||||
if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
|
||||
var streamUrls: [String]? = nil
|
||||
var subtitleUrls: [String]? = nil
|
||||
var streamUrlsAndHeaders : [[String:Any]]? = nil
|
||||
|
||||
if let streamSources = json["streams"] as? [[String:Any]] {
|
||||
streamUrlsAndHeaders = streamSources
|
||||
Logger.shared.log("Found \(streamSources.count) streams and headers", type: "Stream")
|
||||
} else if let streamSource = json["stream"] as? [String:Any] {
|
||||
streamUrlsAndHeaders = [streamSource]
|
||||
Logger.shared.log("Found single stream with headers", type: "Stream")
|
||||
} else if let streamsArray = json["streams"] as? [String] {
|
||||
streamUrls = streamsArray
|
||||
Logger.shared.log("Found \(streamsArray.count) streams", type: "Stream")
|
||||
} else if let streamUrl = json["stream"] as? String {
|
||||
streamUrls = [streamUrl]
|
||||
Logger.shared.log("Found single stream", type: "Stream")
|
||||
}
|
||||
|
||||
if let subsArray = json["subtitles"] as? [String] {
|
||||
subtitleUrls = subsArray
|
||||
Logger.shared.log("Found \(subsArray.count) subtitle tracks", type: "Stream")
|
||||
} else if let subtitleUrl = json["subtitles"] as? String {
|
||||
subtitleUrls = [subtitleUrl]
|
||||
Logger.shared.log("Found single subtitle track", type: "Stream")
|
||||
}
|
||||
|
||||
Logger.shared.log("Starting stream with \(streamUrls?.count ?? 0) sources and \(subtitleUrls?.count ?? 0) subtitles", type: "Stream")
|
||||
DispatchQueue.main.async {
|
||||
completion((streamUrls, subtitleUrls, streamUrlsAndHeaders))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if let streamsArray = try JSONSerialization.jsonObject(with: data, options: []) as? [String] {
|
||||
Logger.shared.log("Starting multi-stream with \(streamsArray.count) sources", type: "Stream")
|
||||
DispatchQueue.main.async { completion((streamsArray, nil, nil)) }
|
||||
return
|
||||
}
|
||||
} catch {
|
||||
Logger.shared.log("JSON parsing error: \(error.localizedDescription)", type: "Error")
|
||||
}
|
||||
|
||||
Logger.shared.log("Starting stream from: \(jsonString)", type: "Stream")
|
||||
DispatchQueue.main.async {
|
||||
completion((streamUrl != nil ? [streamUrl!] : nil, nil,nil))
|
||||
completion(([jsonString], nil, nil))
|
||||
}
|
||||
}
|
||||
|
||||
let catchBlock: @convention(block) (JSValue) -> Void = { error in
|
||||
Logger.shared.log("Promise rejected: \(String(describing: error.toString()))", type: "Error")
|
||||
let errorMessage = error.toString() ?? "Unknown JavaScript error"
|
||||
Logger.shared.log("Promise rejected: \(errorMessage)", type: "Error")
|
||||
DispatchQueue.main.async {
|
||||
completion((nil, nil,nil))
|
||||
completion((nil, nil, nil))
|
||||
}
|
||||
}
|
||||
|
||||
let thenFunction = JSValue(object: thenBlock, in: context)
|
||||
let catchFunction = JSValue(object: catchBlock, in: context)
|
||||
|
||||
promise.invokeMethod("then", withArguments: [thenFunction as Any])
|
||||
promise.invokeMethod("catch", withArguments: [catchFunction as Any])
|
||||
guard let thenFunction = thenFunction, let catchFunction = catchFunction else {
|
||||
Logger.shared.log("Failed to create JSValue objects for Promise handling", type: "Error")
|
||||
completion((nil, nil, nil))
|
||||
return
|
||||
}
|
||||
|
||||
promise.invokeMethod("then", withArguments: [thenFunction])
|
||||
promise.invokeMethod("catch", withArguments: [catchFunction])
|
||||
}
|
||||
|
||||
func fetchStreamUrlJSSecond(episodeUrl: String, softsub: Bool = false, module: ScrapingModule, completion: @escaping ((streams: [String]?, subtitles: [String]?,sources: [[String:Any]]? )) -> Void) {
|
||||
|
|
@ -240,71 +275,82 @@ extension JSController {
|
|||
let thenBlock: @convention(block) (JSValue) -> Void = { [weak self] result in
|
||||
guard self != nil else { return }
|
||||
|
||||
if let jsonString = result.toString(),
|
||||
let data = jsonString.data(using: .utf8) {
|
||||
do {
|
||||
if let json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
|
||||
var streamUrls: [String]? = nil
|
||||
var subtitleUrls: [String]? = nil
|
||||
var streamUrlsAndHeaders : [[String:Any]]? = nil
|
||||
if let streamSources = json["streams"] as? [[String:Any]]
|
||||
{
|
||||
streamUrlsAndHeaders = streamSources
|
||||
Logger.shared.log("Found \(streamSources.count) streams and headers", type: "Stream")
|
||||
}
|
||||
else if let streamSource = json["stream"] as? [String:Any]
|
||||
{
|
||||
streamUrlsAndHeaders = [streamSource]
|
||||
Logger.shared.log("Found single stream with headers", type: "Stream")
|
||||
}
|
||||
else if let streamsArray = json["streams"] as? [String] {
|
||||
streamUrls = streamsArray
|
||||
Logger.shared.log("Found \(streamsArray.count) streams", type: "Stream")
|
||||
} else if let streamUrl = json["stream"] as? String {
|
||||
streamUrls = [streamUrl]
|
||||
Logger.shared.log("Found single stream", type: "Stream")
|
||||
}
|
||||
|
||||
if let subsArray = json["subtitles"] as? [String] {
|
||||
subtitleUrls = subsArray
|
||||
Logger.shared.log("Found \(subsArray.count) subtitle tracks", type: "Stream")
|
||||
} else if let subtitleUrl = json["subtitles"] as? String {
|
||||
subtitleUrls = [subtitleUrl]
|
||||
Logger.shared.log("Found single subtitle track", type: "Stream")
|
||||
}
|
||||
|
||||
Logger.shared.log("Starting stream with \(streamUrls?.count ?? 0) sources and \(subtitleUrls?.count ?? 0) subtitles", type: "Stream")
|
||||
DispatchQueue.main.async {
|
||||
completion((streamUrls, subtitleUrls, streamUrlsAndHeaders))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if let streamsArray = try? JSONSerialization.jsonObject(with: data, options: []) as? [String] {
|
||||
Logger.shared.log("Starting multi-stream with \(streamsArray.count) sources", type: "Stream")
|
||||
DispatchQueue.main.async { completion((streamsArray, nil, nil)) }
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let streamUrl = result.toString()
|
||||
Logger.shared.log("Starting stream from: \(streamUrl ?? "nil")", type: "Stream")
|
||||
|
||||
// Check if the result is a Promise object and handle it properly
|
||||
if streamUrl == "[object Promise]" {
|
||||
Logger.shared.log("Received Promise object instead of resolved value, waiting for proper resolution", type: "Stream")
|
||||
// Skip this result - other methods will provide the resolved URL
|
||||
if result.isNull || result.isUndefined {
|
||||
Logger.shared.log("Received null or undefined result from JavaScript", type: "Error")
|
||||
DispatchQueue.main.async { completion((nil, nil, nil)) }
|
||||
return
|
||||
}
|
||||
|
||||
if let resultString = result.toString(), resultString == "[object Promise]" {
|
||||
Logger.shared.log("Received Promise object instead of resolved value, waiting for proper resolution", type: "Stream")
|
||||
return
|
||||
}
|
||||
|
||||
guard let jsonString = result.toString() else {
|
||||
Logger.shared.log("Failed to convert JSValue to string", type: "Error")
|
||||
DispatchQueue.main.async { completion((nil, nil, nil)) }
|
||||
return
|
||||
}
|
||||
|
||||
guard let data = jsonString.data(using: .utf8) else {
|
||||
Logger.shared.log("Failed to convert string to data", type: "Error")
|
||||
DispatchQueue.main.async { completion((nil, nil, nil)) }
|
||||
return
|
||||
}
|
||||
|
||||
do {
|
||||
if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
|
||||
var streamUrls: [String]? = nil
|
||||
var subtitleUrls: [String]? = nil
|
||||
var streamUrlsAndHeaders : [[String:Any]]? = nil
|
||||
|
||||
if let streamSources = json["streams"] as? [[String:Any]] {
|
||||
streamUrlsAndHeaders = streamSources
|
||||
Logger.shared.log("Found \(streamSources.count) streams and headers", type: "Stream")
|
||||
} else if let streamSource = json["stream"] as? [String:Any] {
|
||||
streamUrlsAndHeaders = [streamSource]
|
||||
Logger.shared.log("Found single stream with headers", type: "Stream")
|
||||
} else if let streamsArray = json["streams"] as? [String] {
|
||||
streamUrls = streamsArray
|
||||
Logger.shared.log("Found \(streamsArray.count) streams", type: "Stream")
|
||||
} else if let streamUrl = json["stream"] as? String {
|
||||
streamUrls = [streamUrl]
|
||||
Logger.shared.log("Found single stream", type: "Stream")
|
||||
}
|
||||
|
||||
if let subsArray = json["subtitles"] as? [String] {
|
||||
subtitleUrls = subsArray
|
||||
Logger.shared.log("Found \(subsArray.count) subtitle tracks", type: "Stream")
|
||||
} else if let subtitleUrl = json["subtitles"] as? String {
|
||||
subtitleUrls = [subtitleUrl]
|
||||
Logger.shared.log("Found single subtitle track", type: "Stream")
|
||||
}
|
||||
|
||||
Logger.shared.log("Starting stream with \(streamUrls?.count ?? 0) sources and \(subtitleUrls?.count ?? 0) subtitles", type: "Stream")
|
||||
DispatchQueue.main.async {
|
||||
completion((streamUrls, subtitleUrls, streamUrlsAndHeaders))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if let streamsArray = try JSONSerialization.jsonObject(with: data, options: []) as? [String] {
|
||||
Logger.shared.log("Starting multi-stream with \(streamsArray.count) sources", type: "Stream")
|
||||
DispatchQueue.main.async { completion((streamsArray, nil, nil)) }
|
||||
return
|
||||
}
|
||||
} catch {
|
||||
Logger.shared.log("JSON parsing error: \(error.localizedDescription)", type: "Error")
|
||||
}
|
||||
|
||||
Logger.shared.log("Starting stream from: \(jsonString)", type: "Stream")
|
||||
DispatchQueue.main.async {
|
||||
completion((streamUrl != nil ? [streamUrl!] : nil, nil, nil))
|
||||
completion(([jsonString], nil, nil))
|
||||
}
|
||||
}
|
||||
|
||||
let catchBlock: @convention(block) (JSValue) -> Void = { error in
|
||||
Logger.shared.log("Promise rejected: \(String(describing: error.toString()))", type: "Error")
|
||||
let errorMessage = error.toString() ?? "Unknown JavaScript error"
|
||||
Logger.shared.log("Promise rejected: \(errorMessage)", type: "Error")
|
||||
DispatchQueue.main.async {
|
||||
completion((nil, nil, nil))
|
||||
}
|
||||
|
|
@ -313,8 +359,14 @@ extension JSController {
|
|||
let thenFunction = JSValue(object: thenBlock, in: self.context)
|
||||
let catchFunction = JSValue(object: catchBlock, in: self.context)
|
||||
|
||||
promise.invokeMethod("then", withArguments: [thenFunction as Any])
|
||||
promise.invokeMethod("catch", withArguments: [catchFunction as Any])
|
||||
guard let thenFunction = thenFunction, let catchFunction = catchFunction else {
|
||||
Logger.shared.log("Failed to create JSValue objects for Promise handling", type: "Error")
|
||||
completion((nil, nil, nil))
|
||||
return
|
||||
}
|
||||
|
||||
promise.invokeMethod("then", withArguments: [thenFunction])
|
||||
promise.invokeMethod("catch", withArguments: [catchFunction])
|
||||
}
|
||||
}
|
||||
task.resume()
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ import Foundation
|
|||
|
||||
@MainActor
|
||||
class ModuleManager: ObservableObject {
|
||||
static let shared = ModuleManager()
|
||||
|
||||
@Published var modules: [ScrapingModule] = []
|
||||
@Published var selectedModuleChanged = false
|
||||
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ struct MediaInfoView: View {
|
|||
@AppStorage("selectedAppearance") private var selectedAppearance: Appearance = .system
|
||||
|
||||
@ObservedObject private var jsController = JSController.shared
|
||||
@EnvironmentObject var moduleManager: ModuleManager
|
||||
@EnvironmentObject private var moduleManager: ModuleManager
|
||||
@EnvironmentObject private var libraryManager: LibraryManager
|
||||
@ObservedObject private var navigator = ChapterNavigator.shared
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue