10

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 Answers2

21

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
        }
    }
mkkrolik
  • 1,078
  • 11
  • 20
0

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!

justColbs
  • 1,107
  • 14
  • 25