mirror of
https://github.com/cranci1/Sora.git
synced 2026-03-11 17:45:37 +00:00
parent
88a5df88bf
commit
e83ec3343c
3 changed files with 31 additions and 126 deletions
|
|
@ -399,67 +399,6 @@ struct ActiveDownload: Identifiable, Equatable {
|
|||
}
|
||||
}
|
||||
|
||||
// MARK: - JS Active Download Model
|
||||
struct JSActiveDownload: Identifiable, Equatable {
|
||||
let id: UUID
|
||||
let originalURL: URL
|
||||
var progress: Double
|
||||
let task: AVAssetDownloadTask? // For HLS downloads
|
||||
let mp4Task: URLSessionDownloadTask? // For MP4 downloads
|
||||
let type: DownloadType
|
||||
var metadata: AssetMetadata?
|
||||
var title: String?
|
||||
var imageURL: URL?
|
||||
var subtitleURL: URL?
|
||||
var queueStatus: DownloadQueueStatus
|
||||
var asset: AVURLAsset?
|
||||
var headers: [String: String]
|
||||
var module: ScrapingModule?
|
||||
|
||||
static func == (lhs: JSActiveDownload, rhs: JSActiveDownload) -> Bool {
|
||||
return lhs.id == rhs.id &&
|
||||
lhs.originalURL == rhs.originalURL &&
|
||||
lhs.progress == rhs.progress &&
|
||||
lhs.type == rhs.type &&
|
||||
lhs.title == rhs.title &&
|
||||
lhs.imageURL == rhs.imageURL &&
|
||||
lhs.subtitleURL == rhs.subtitleURL &&
|
||||
lhs.queueStatus == rhs.queueStatus
|
||||
}
|
||||
|
||||
init(
|
||||
id: UUID = UUID(),
|
||||
originalURL: URL,
|
||||
progress: Double = 0,
|
||||
task: AVAssetDownloadTask? = nil,
|
||||
mp4Task: URLSessionDownloadTask? = nil,
|
||||
queueStatus: DownloadQueueStatus = .queued,
|
||||
type: DownloadType = .movie,
|
||||
metadata: AssetMetadata? = nil,
|
||||
title: String? = nil,
|
||||
imageURL: URL? = nil,
|
||||
subtitleURL: URL? = nil,
|
||||
asset: AVURLAsset? = nil,
|
||||
headers: [String: String] = [:],
|
||||
module: ScrapingModule? = nil
|
||||
) {
|
||||
self.id = id
|
||||
self.originalURL = originalURL
|
||||
self.progress = progress
|
||||
self.task = task
|
||||
self.mp4Task = mp4Task
|
||||
self.type = type
|
||||
self.metadata = metadata
|
||||
self.title = title
|
||||
self.imageURL = imageURL
|
||||
self.subtitleURL = subtitleURL
|
||||
self.queueStatus = queueStatus
|
||||
self.asset = asset
|
||||
self.headers = headers
|
||||
self.module = module
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Asset Metadata
|
||||
struct AssetMetadata: Codable {
|
||||
let title: String
|
||||
|
|
|
|||
|
|
@ -75,6 +75,23 @@ extension JSController {
|
|||
let filename = "\(sanitizedTitle)_\(downloadID.uuidString.prefix(8)).mp4"
|
||||
let destinationURL = downloadDirectory.appendingPathComponent(filename)
|
||||
|
||||
// Create an active download object
|
||||
let activeDownload = JSActiveDownload(
|
||||
id: downloadID,
|
||||
originalURL: url,
|
||||
task: nil,
|
||||
queueStatus: .downloading,
|
||||
type: downloadType,
|
||||
metadata: metadata,
|
||||
title: title,
|
||||
imageURL: imageURL,
|
||||
subtitleURL: subtitleURL,
|
||||
headers: headers
|
||||
)
|
||||
|
||||
// Add to active downloads
|
||||
activeDownloads.append(activeDownload)
|
||||
|
||||
// Create request with headers
|
||||
var request = URLRequest(url: url)
|
||||
request.timeoutInterval = 30.0
|
||||
|
|
@ -187,32 +204,16 @@ extension JSController {
|
|||
}
|
||||
}
|
||||
|
||||
// Create an active download object with the mp4Task
|
||||
let activeDownload = JSActiveDownload(
|
||||
id: downloadID,
|
||||
originalURL: url,
|
||||
task: nil,
|
||||
mp4Task: downloadTask, // Add the MP4 download task
|
||||
queueStatus: .downloading,
|
||||
type: downloadType,
|
||||
metadata: metadata,
|
||||
title: title,
|
||||
imageURL: imageURL,
|
||||
subtitleURL: subtitleURL,
|
||||
headers: headers
|
||||
)
|
||||
// Set up progress observation
|
||||
setupProgressObservation(for: downloadTask, downloadID: downloadID)
|
||||
|
||||
// Add to active downloads and map
|
||||
activeDownloads.append(activeDownload)
|
||||
activeDownloadMap[downloadTask] = downloadID
|
||||
|
||||
// Store session reference
|
||||
storeSessionReference(session: customSession, for: downloadID)
|
||||
|
||||
// Set initial task state to running
|
||||
// Start download
|
||||
downloadTask.resume()
|
||||
print("MP4 Download: Task started for \(filename)")
|
||||
|
||||
|
||||
// Initial success callback
|
||||
completionHandler?(true, "Download started")
|
||||
}
|
||||
|
|
@ -229,39 +230,14 @@ extension JSController {
|
|||
}
|
||||
|
||||
private func setupProgressObservation(for task: URLSessionDownloadTask, downloadID: UUID) {
|
||||
// Create a dispatch queue for progress updates
|
||||
let progressQueue = DispatchQueue(label: "com.sora.download.progress")
|
||||
|
||||
let observation = task.progress.observe(\.fractionCompleted) { [weak self] progress, _ in
|
||||
progressQueue.async {
|
||||
DispatchQueue.main.async {
|
||||
guard let self = self else { return }
|
||||
|
||||
// Only update if enough time has passed since last update
|
||||
let currentTime = Date()
|
||||
let lastUpdate = JSController.lastProgressUpdateTime[downloadID] ?? .distantPast
|
||||
|
||||
if currentTime.timeIntervalSince(lastUpdate) >= JSController.progressUpdateInterval {
|
||||
DispatchQueue.main.async {
|
||||
self.updateDownloadProgress(downloadID: downloadID, progress: progress.fractionCompleted)
|
||||
JSController.lastProgressUpdateTime[downloadID] = currentTime
|
||||
|
||||
// Find and update the download object
|
||||
if let index = self.activeDownloads.firstIndex(where: { $0.id == downloadID }) {
|
||||
let download = self.activeDownloads[index]
|
||||
// Post progress notification with episode info if available
|
||||
if let episodeNumber = download.metadata?.episode {
|
||||
self.postDownloadNotification(.progress, userInfo: [
|
||||
"episodeNumber": episodeNumber,
|
||||
"progress": progress.fractionCompleted,
|
||||
"status": "downloading"
|
||||
])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
self.updateDownloadProgress(downloadID: downloadID, progress: progress.fractionCompleted)
|
||||
NotificationCenter.default.post(name: NSNotification.Name("downloadProgressUpdated"), object: nil)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if mp4ProgressObservations == nil {
|
||||
mp4ProgressObservations = [:]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -555,7 +555,7 @@ struct DownloadSectionView: View {
|
|||
|
||||
struct DownloadSummaryCard: View {
|
||||
let totalShows: Int
|
||||
let totalEpisodes: Int64
|
||||
let totalEpisodes: Int
|
||||
let totalSize: Int64
|
||||
|
||||
var body: some View {
|
||||
|
|
@ -733,7 +733,7 @@ struct EnhancedActiveDownloadCard: View {
|
|||
init(download: JSActiveDownload) {
|
||||
self.download = download
|
||||
_currentProgress = State(initialValue: download.progress)
|
||||
_taskState = State(initialValue: download.mp4Task?.state ?? download.task?.state ?? .suspended)
|
||||
_taskState = State(initialValue: download.task?.state ?? .suspended)
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
|
|
@ -877,21 +877,11 @@ struct EnhancedActiveDownloadCard: View {
|
|||
|
||||
private func toggleDownload() {
|
||||
if taskState == .running {
|
||||
if let hlsTask = download.task {
|
||||
hlsTask.suspend()
|
||||
taskState = .suspended
|
||||
} else if let mp4Task = download.mp4Task {
|
||||
mp4Task.suspend()
|
||||
taskState = .suspended
|
||||
}
|
||||
download.task?.suspend()
|
||||
taskState = .suspended
|
||||
} else if taskState == .suspended {
|
||||
if let hlsTask = download.task {
|
||||
hlsTask.resume()
|
||||
taskState = .running
|
||||
} else if let mp4Task = download.mp4Task {
|
||||
mp4Task.resume()
|
||||
taskState = .running
|
||||
}
|
||||
download.task?.resume()
|
||||
taskState = .running
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue