Closed johndpope closed 3 years ago
Hey, video is on the roadmap – it's way better than GIF for animations. I have a primitive demo that downloads and caches video using Nuke. The problem is, I don't have too much experience with video yet.
@kean - I found this code by @ChrishonWyllie https://github.com/ChrishonWyllie/Celestial
it seems good the trick with avplayer - is if there's no video around then a download task is eagerly kicked off on prefecting but onscrolling / there's now need to take over the download task and stick into avplayer seems like this is handled here
mergeExistingDownloadTask https://github.com/ChrishonWyllie/Celestial/blob/f03a6916c45f1f87cd4b6892af3b25ca228af103/Classes/DownloadManager/DownloadTaskManager.swift
@ChrishonWyllie https://chrishonwyllie.com/docs/celestial/caching-videos/displaying-in-cells
important to point out - uicollectionview has some smarts out of the box for prefetching. cv.prefetchDataSource = self cv.isPrefetchingEnabled = true
There's a final bit of sugar to squeeze performance that I've seen from another repo @GeekTree0101 https://github.com/GeekTree0101/TextureAVAssetVideoFeed/blob/173a048a4dbbb170f0fbf861f51265d8d7ee408b/TextureAVAssetFeed/Views/GTVideoNode.swift#L51
GeekTree0101 cancels the downloading after 3 seconds - thus leaving enough video to start showing / but not over doing it.
fyi - @bkg866
this seems to get performance like tiktok to eagerly download videos (5-6 videos queued up on first (and subsequent) presentations of the fullscreen cell) tikTok will eagerly fetch ahead of time as soon as the user loads video. https://gist.github.com/johndpope/8d4ecbdeb1ecb3188b55afc5282d544e
I'm planning to add improved support for downloading videos ahead of time in Nuke 10 – the same way it currently works for animated GIFs. There will be an option to enable synchronous disk writes, and you'll receive a file URL in the response that you can immediately start playing from disk.
Progressive download is going to be more complicated, but doable. I haven't put much thought into it yet, but if someone would come up with a proposal that ideally doesn't over-complicate the existing APIs, I'm all for it.
some design considerations I've had to overcome to achieve this when pushing and popping a vc - you want to be able to cancel all the queued up eager downloads. I attempted with different repos - but ended up using an updated fork of Digger. (main repo last update 4 years ago) https://github.com/cornerAnt/Digger/issues/29
If internet connection is really bad - need to be able back off eager fetching - and just get the video / and don't even bother caching it - just play it. assumption of only ever playing a video directly from cache - is eroneous. Having the downloader infrastructure is half the battle - cell recycling / reuse with uikit is the other part. if you use too many avplayers (will work fine on simulator / but depending on the physical device/ hardeware) - you can reach a condition where the avplayer konks out due to too many avplayers. it won't play / fetch / buffer. It also spills over to native photo apps I've found too on 14.5
The cells in a collection view / and their associated playable state / and the eager fetching happening in background from - needs careful orchestration. Dequeueing of cells / and having them choose to play from the cache - or go out bound directly to the web - other battle. I have some logic from private repo can share / just drop an email. If a playing video refuses to play - does the file exist on cache already..... Should the video automatically play as soon as it's loaded? Not according to tiktok - you have to scroll to just when the video is finished scrolling before playing.
Other time wasters - loading state / show a progress loader / hide the loader. (dont hide it / better to remove it)
KVO Observsations and their removal of avplayer state /avplayeritem - also add to complexity here. Does this / should this live in the cell ? when you build a collection view - and instantiate avplayers / when cell is recycled - you can recreate that player - or create a new one. you have to tear down / and remove things.
I built basic video playback support in NukeUI. Unlike the old prototype from the demo project, the new version now uses AVAssetResourceLoaderDelegate
to play video from memory – should be pretty efficient now.
Ideally, it should also have progressive playback support, but it's a start. The current model is simple: fetch the whole thing (assuming videos are small and are used as a more efficient replacement for GIFs) and play it. No sound. So pretty much what you would expect when you are replicating GIF behavior.
you can reach a condition where the avplayer konks out due to too many avplayers
Interesting, I'll need to look into it.
Not according to tiktok - you have to scroll to just when the video is finished scrolling before playing.
A "proper" video player like in TikTok would require something completely different. I don't think Nuke is a good place to implement it.
I made a bunch of improvements to video support in NukeUI in 0.2.0. I described how it works here. I think it's a great replacement for GIFs and it's not meant to be a complete video player.
I'm going to close this issue. If you'd like to see more improvements or features related to "video as GIF replacement", please feel free to open an issue or start a discussion in NukeUI.
fyi - found this just today - it actually is quite helpful for my use case. https://github.com/eroscai/SZAVPlayer
I've been faffing around with different swift caching video frameworks - without really coming to a solution. It's a space where maybe caching of videos is not a thing. Some design condiserations - Being able to be able to cancel video loads
I'm ok for this issue to be closed - but if there's so many eyeballs on this repo - any more combined efforts to solve this caching problem would be a blessing.
https://github.com/wxxsw/GSPlayer/issues/39 https://github.com/mazz/Digger/ https://github.com/JasonGoodney/wikio-ki/blob/eda8f3bff79b87ecd178a3a7937f658a8e30c058/picture/CachingPlayerItem.swift