Is it possible to cache Videos? IOS - Swift

2019-03-31 02:31发布

I am trying to download and play videos in a tableView like Instagram, vine or even facebook.

What I am trying to achieve is a tableView where I display the videos and they auto download and play while scrolling. Like Instagram...

So far I have managed most of that, but what I would like to change is the fact that every time I view a cell the video gets downloaded again and again.... Surely there must be a way to cache videos, or only download the same video once.... Like you do with SDWebImages for images.

Also at the moment with it download every time I view the cell, the scrolling is terrible as you can imagine.

Now I cannot seem to figure out how Instagram does it, but I am 100% sure they don't download the same video more than once!!

If anyone has and advice or ideas, I'd love to hear them!!

Many thanks in advance.

2条回答
\"骚年 ilove
2楼-- · 2019-03-31 03:20

Using Haneke, I wasn't able to retrieve file path for cached video. I handled it by saving video in cached directory.

public enum Result<T> {
    case success(T)
    case failure(NSError)
}

class CacheManager {

    static let shared = CacheManager()

    private let fileManager = FileManager.default

    private lazy var mainDirectoryUrl: URL = {

        let documentsUrl = self.fileManager.urls(for: .cachesDirectory, in: .userDomainMask).first!
        return documentsUrl
    }()

    func getFileWith(stringUrl: String, completionHandler: @escaping (Result<URL>) -> Void ) {


        let file = directoryFor(stringUrl: stringUrl)

        //return file path if already exists in cache directory
        guard !fileManager.fileExists(atPath: file.path)  else {
            completionHandler(Result.success(file))
            return
        }

        DispatchQueue.global().async {

            if let videoData = NSData(contentsOf: URL(string: stringUrl)!) {                    
                videoData.write(to: file, atomically: true)

                DispatchQueue.main.async {
                    completionHandler(Result.success(file))
                }
            } else {
                DispatchQueue.main.async {
                    completionHandler(Result.failure(NSError.errorWith(text: "Can't download video")))
                }
            }
        }
    }

    private func directoryFor(stringUrl: String) -> URL {

        let fileURL = URL(string: stringUrl)!.lastPathComponent

        let file = self.mainDirectoryUrl.appendingPathComponent(fileURL)

        return file
    }
}

Sample usage of this class looks like this:

CacheManager.shared.getFileWith(stringUrl: "http://techslides.com/demos/sample-videos/small.mp4") { result in

        switch result {
        case .success(let url):
             // do some magic with path to saved video                
        case .failure(let error):
            // handle errror
        }
    }
查看更多
仙女界的扛把子
3楼-- · 2019-03-31 03:21

great question. You're best bet is to use something open-source and 3rd party on Github. I use them solely for images, but I believe they will load and cache videos for you as well. Here are the links to some popular ones...

https://github.com/onevcat/Kingfisher https://github.com/Haneke/HanekeSwift There is also a good list of libraries you might find useful... https://github.com/Wolg/awesome-swift

Hope this helps!

查看更多
登录 后发表回答