Skip to content

Commit

Permalink
Add cancelDownload method on CachingPlayerItem
Browse files Browse the repository at this point in the history
  • Loading branch information
sukov committed Aug 12, 2024
1 parent c9e6c00 commit 93f5438
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 10 deletions.
21 changes: 16 additions & 5 deletions Source/CachingPlayerItem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public final class CachingPlayerItem: AVPlayerItem {
}

/**
Play and cache remote media on a local file. `saveFilePath` is **radomly** generated. Requires `url.pathExtension` to not be empty otherwise the player will fail playing.
Play and cache remote media on a local file. `saveFilePath` is **randomly** generated. Requires `url.pathExtension` to not be empty otherwise the player will fail playing.

- parameter url: URL referencing the media file.

Expand All @@ -68,7 +68,7 @@ public final class CachingPlayerItem: AVPlayerItem {
}

/**
Play and cache remote media on a local file. `saveFilePath` is **radomly** generated.
Play and cache remote media on a local file. `saveFilePath` is **randomly** generated.

- parameter url: URL referencing the media file.

Expand Down Expand Up @@ -202,11 +202,11 @@ public final class CachingPlayerItem: AVPlayerItem {
deinit {
removeObservers()

// Don't reference lazy `resourceLoaderDelegate` if it hasn't been called before.
// Cancel download only for caching inits
guard initialScheme != nil else { return }

// Otherwise the ResourceLoaderDelegate wont deallocate and will keep downloading.
resourceLoaderDelegate.invalidateAndCancelSession()
cancelDownload()
}

// MARK: Public methods
Expand All @@ -215,13 +215,24 @@ public final class CachingPlayerItem: AVPlayerItem {
public func download() {
// Make sure we are not initilalized with a filePath or non-caching init.
guard initialScheme != nil else {
assertionFailure("CachingPlayerItem error: Download method used on a non caching instance")
assertionFailure("CachingPlayerItem error: `download` method used on a non caching instance")
return
}

resourceLoaderDelegate.startDataRequest(with: url)
}

/// Cancels the download of the media file and deletes the incomplete cached file. Works only with the initializers intended for play and cache.
public func cancelDownload() {
// Make sure we are not initilalized with a filePath or non-caching init.
guard initialScheme != nil else {
assertionFailure("CachingPlayerItem error: `cancelDownload` method used on a non caching instance")
return
}

resourceLoaderDelegate.invalidateAndCancelSession()
}

// MARK: KVO

private var playerItemContext = 0
Expand Down
15 changes: 10 additions & 5 deletions Source/ResourceLoaderDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,14 @@ final class ResourceLoaderDelegate: NSObject, AVAssetResourceLoaderDelegate, URL

func invalidateAndCancelSession() {
session?.invalidateAndCancel()
session = nil
bufferData = Data()
pendingRequests.removeAll()

// We need to only remove the file if it hasn't been fully downloaded
guard isDownloadComplete == false else { return }

fileHandle.deleteFile()
}

// MARK: Private methods
Expand Down Expand Up @@ -206,17 +214,14 @@ final class ResourceLoaderDelegate: NSObject, AVAssetResourceLoaderDelegate, URL
}

private func downloadFailed(with error: Error) {
fileHandle.deleteFile()
invalidateAndCancelSession()

DispatchQueue.main.async {
self.owner?.delegate?.playerItem?(self.owner!, downloadingFailedWith: error)
}
}

@objc private func handleAppWillTerminate() {
// We need to only remove the file if it hasn't been fully downloaded
guard isDownloadComplete == false else { return }

fileHandle.deleteFile()
invalidateAndCancelSession()
}
}

0 comments on commit 93f5438

Please sign in to comment.