chrishonwyllie / celestial Goto Github PK
View Code? Open in Web Editor NEWA Caching service for multimedia
License: MIT License
A Caching service for multimedia
License: MIT License
isEmpty apparently is more efficient than checking the count of an array
As mentioned in another issue, the video player (or the containing superView) will force a particular video format size without taking into account the original size of the video
Ah yes, I see its in the 9:16 format. I'll spend some time to correct this.
Thank you for pointing this out.
Originally posted by @ChrishonWyllie in #15 (comment)
Is your feature request related to a problem? Please describe.
there are a lot of cases when you setup UIImageView
inside xib file but your lib forbids that
Describe the solution you'd like
support xibs. Currently your lib fails on:
required public init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
Describe alternatives you've considered
Alternative libraries support that
A mistake has been made. The store to memory cache incorrectly uses the file system cache
When I was using digger - it used this technique to simplify the name of url.
N.B. it's using md5.
static func tempPath(url: URL ) -> String {
return url.absoluteString.md5.tmpDir
}
internal func constructFormattedURL(from sourceURL: URL, expectedDirectoryURL: URL, size: CGSize?) -> URL {
// size: CGSize(width: 327.0, height: 246.0)
// image name 1: URL: https://picsum.photos/id/0/5616/3744 -> becomes -> 3744-size-327.0-246.0 (no extension)
// image name 2: URL: https://server/url/to/your/image.png -> becomes -> image-size-327-0-246-0.png
var formattedFileName = sourceURL.localUniqueFileName()
let fileExtension = sourceURL.pathExtension
if let size = size {
let width = String(describing: size.width).replacingOccurrences(of: ".", with: "-")
let height = String(describing: size.height).replacingOccurrences(of: ".", with: "-")
let sizePathComponent: String = "-size-\(width)-\(height)"
formattedFileName += sizePathComponent
}
let sizeFormattedURL = expectedDirectoryURL
.appendingPathComponent(formattedFileName)
.appendingPathExtension(fileExtension)
DebugLogger.shared.addDebugMessage("\(String(describing: type(of: self))) - Constructing formatted URL: \(sizeFormattedURL)")
return sizeFormattedURL. /// WE NEED TO USE md5 here.
}
urlVideoPlayerIsReadyToPlay :Optional("https://d21m91m763fb64.cloudfront.net/videos-360p/a9731a30-a15f-11eb-8337-67b105f10dfa-.mp4")
2021-07-26 11:14:09.726182+1000 8secondz[3502:1036162] DownloadTaskManager - finished download for url: https://d21m91m763fb64.cloudfront.net/videos-360p/a9731a30-a15f-11eb-8337-67b105f10dfa-.mp4 - local file name: https:__d21m91m763fb64.cloudfront.net_videos-360p_a9731a30-a15f-11eb-8337-67b105f10dfa-. DownloadTask: BackgroundDownloadTask <14777A73-6827-45B1-BFC4-D3B32376EA46>.<1>. Temporary file location: file:///private/var/mobile/Containers/Data/Application/ABAE01F4-0A9D-487E-A39F-606A81A234FA/Library/Caches/com.apple.nsurlsessiond/Downloads/app.8secondz.ios/CFNetworkDownload_EuG8OL.tmp
2021-07-26 11:14:09.728414+1000 8secondz[3502:1036162] FileStorageManager - Attempting to delete file for path: /private/var/mobile/Containers/Data/Application/ABAE01F4-0A9D-487E-A39F-606A81A234FA**/tmp/https:__d21**m91m763fb64.cloudfront.net_videos-360p_a9731a30-a15f-11eb-8337-67b105f10dfa-.mp4
2021-07-26 11:14:09.731695+1000 8secondz[3502:1036162] DownloadTaskManager - Moved to intermediate temporary file url: file:///private/var/mobile/Containers/Data/Application/ABAE01F4-0A9D-487E-A39F-606A81A234FA/tmp/https:__d21m91m763fb64.cloudfront.net_videos-360p_a9731a30-a15f-11eb-8337-67b105f10dfa-.mp4
2021-07-26 11:14:09.733670+1000 8secondz[3502:1036162] FileStorageManager - Constructing formatted URL: file:///var/mobile/Containers/Data/Application/ABAE01F4-0A9D-487E-A39F-606A81A234FA/Documents/Celestial/CachedVideos/https:__d21m91m763fb64.cloudfront.net_videos-360p_a9731a30-a15f-11eb-8337-67b105f10dfa-.mp4
2021-07-26 11:14:09.734680+1000 8secondz[3502:1036162] FileStorageManager - Attempting to delete file for path: /var/mobile/Containers/Data/Application/ABAE01F4-0A9D-487E-A39F-606A81A234FA/Documents/Celestial/CachedVideos/https:__d21m91m763fb64.cloudfront.net_videos-360p_a9731a30-a15f-11eb-8337-67b105f10dfa-.mp4
2021-07-26 11:14:09.740544+1000 8secondz[3502:1036162] Optional - Error storing the downloaded video to the file cache Error Domain=NSCocoaErrorDomain Code=4 "“https/__d21m91m763fb64.cloudfront.net_videos-360p_a9731a30-a15f-11eb-8337-67b105f10dfa-.mp4” couldn’t be moved to “CachedVideos” because either the former doesn’t exist, or the folder containing the latter doesn’t exist."
When a video has been downloaded and ready to be cached to the file system, it first determines if the video should be exported a lower quality.
If not, the downloaded file is expected to be moved from its temporary download location (which is apparently random and provided by URLSession DownloadTask) to a more permanent location.
However, simply moving the file has the unintended possibility of collision. You can't move an item to a URL that already contains an item as evidenced by this error:
Error Domain=NSCocoaErrorDomain Code=516 "{FILE_NAME}"
couldn’t be moved to “{DIRECTORY_NAME}” because an item with the same name already exists."
UserInfo={NSSourceFilePathErrorKey={FILE_PATH}, NSUserStringVariant=(
Move
),
NSDestinationFilePath={DESTINATION_FILE_PATH}, NSFilePath={TEMPORARY_FILE_PATH}, NSUnderlyingError=0x280871860 {Error Domain=NSPOSIXErrorDomain Code=17 "File exists"}}
First check if the file exists or delete any files at that path before using the moveItem
function
Add some descriptions/documentation when option-clicking on functions, properties and classes
extension TheatreVideoVC: UICollectionViewDataSourcePrefetching {
// TikTok eager download - fetch 5 movies as soon as possible on app start
// get the next X videos / start downloading them...
func collectionView(_ collectionView: UICollectionView, prefetchItemsAt indexPaths: [IndexPath]) {
if indexPaths.count >= 1 {
let indexPath = indexPaths[0]
let idx0 = IndexPath(row: indexPath.row, section: 0)
let idx1 = IndexPath(row: indexPath.row+1, section: 0)
let idx2 = IndexPath(row: indexPath.row+2, section: 0)
let idx3 = IndexPath(row: indexPath.row+3, section: 0)
let idx4 = IndexPath(row: indexPath.row+4, section: 0)
let prefetchIndexPaths = [idx0, idx1, idx2, idx3, idx4]
for idx in prefetchIndexPaths {
self.prefetchItem(idx: idx)
}
}
}
private func prefetchItem(idx: IndexPath) {
print("INFO:prefetchItem \(idx)")
if self.feedCollectionView != nil {
if self.feedCollectionView.isValid(indexPath: idx) {
if let video = self.theatreDataSource?.itemIdentifier(for: idx) as? Video {
Celestial.shared.startDownload(for: video.url)
}
}
}
}
I used this mistakenly Celestial.shared.prefetchResources(at: [url]) - and performance was crap. Was prepared to throw in bin - but when I switched to simple Celestial.shared.startDownload(for: video.url) - it's all good AND smooth. I think it's the sync calls in prefetch that cause scrolling to come unstuck.
Non secure URLs such as http://.....
will not be loaded unless the developer adds the App Transport Security Key to their Info.plist.
This should be explained in proper detail
The AssetExportManager
has no need to be a singleton
For files without a file extension, the AVURLAsset initializer/exportSession fails. Resulting in a fatalError
Sometimes the play status will change to readyToPlay a second time, resulting in videos being played but not seen.
A standard CHANGLOG file for labeling all major changes with each release
I've noticed that I use completion blocks that return optional URLs and Errors very frequently. These could be refactored into a common type alias.
This warning is now displayed:
warning: using 'class' keyword for protocol inheritance is deprecated; use 'AnyObject' instead
However, this apparently may not be new
The URLVideoPlayerView
has a completion block that should be called even when the video already exists in the cache. Currently, this completion is only called when the download for new items finishes.
Include things like minimum iOS deployment target, pictures, videos and maybe an icon (space related)
Compressing Data requires iOS 13.0, which may be too restricting.
Additionally, it seems that compressing Data results in a larger file so it seems unnecessary given the original file size
There has been at least one issue where a new download has started for a video that has already been cached.
Make sure the resource identifier is set, and check all internal file URLs for nil
Currently, there is no mention of how to pause and resume an individual download.
Specifically, documentation is missing on these functions which have already been implemented:
Celestial.shared.pauseDownload(for: someURL)
Celestial.shared.resumeDownload(for: someURL)
https://github.com/wxxsw/GSPlayer)](https://github.com/wxxsw/GSPlayer
https://github.com/wxxsw/GSPlayer/blob/257f1fca3860fdbbad112b0524a90985589437fd/GSPlayer/Classes/Loader/VideoPreloadManager.swift#L15
public var preloadByteCount: Int = 1024 * 1024 // = 1M
Why: performing tasks on the background thread may never run if the device is in low power mode.
Check out these posts/articles:
Implement a similar functionality (or near to it as possible) for caching videos
background -
I've still got errors with files moving around - but I wonder why we would want to move the videos to the users' documents, as this will be backed up????!!! Of course, the videos can deleted on each run - but still - it's possible the videos will be uploaded / backed up.
This is not desirable.
Optional
UPDATE - I definitely have the file - 3d670aed625fd22d2bee581128a1477f.mp4
not sure what's going wrong...
could it be a sandbox issue? isn't the tmp folder sufficient for housing this content?
downloaded file with local file name: 3d670aed625fd22d2bee581128a1477f exists in file system directory: file:///private/var/mobile/Containers/Data/Application/54D5E245-B9D6-424B-A5A8-B61B2FF3A53F/tmp/. Directory contents: ["httpsd21m91m763fb64.cloudfront.netvideos-540p4595f3a0-4c4d-11eb-b966-11af6d636bea-.mp4", "httpsd21m91m763fb64.cloudfront.netvideos-540pa1f55040-8a1f-11eb-8bc7-65134f4b7bab-.mp4", "3d670aed625fd22d2bee581128a1477f.mp4", "httpsd21m91m763fb64.cloudfront.netvideos-540p19f1efb0-8a1e-11eb-8bc7-65134f4b7bab-.mp4", "https:__d21m91m763fb64.cloudfront.net_videos-540p_d9379510-903f-11eb-9a88-f5ff80ee2719-.mp4", "https:__d21m91m763fb64.cloudfront.net_videos-540p_9edc1cd0-a9f1-11eb-b98a-69bcf457ca9a-.mp4", "httpsd21m91m763fb64.cloudfront.netvideos-540pfd292d70-89f1-11eb-bbdc-672a9fc57f81-.mp4", "ecc055b46ee87f987d14cb00a75a0d68.mp4", "httpsd21m91m763fb64.cloudfront.netvideos-540pe4b390e0-8560-11eb-822b-3bb0ffb6770c-.mp4", "stack-logs.3879.10a42c000.8secondz.g3", "28ed6
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.