SoFunction
Updated on 2025-05-16

iOS solution to realize video caching while playing

iOS solution to realize video caching while playing

Updated: May 16, 2025 08:30:59 Author: Chenzai, born in the 1990s
This article mainly introduces how to use AVPlayer, AVAssetResourceLoaderDelegate, URLSession and local cache technology to realize the iOS video caching function while playing. Friends who need it can refer to it

1. Technology implementation ideas

1. Core Components

  • AVPlayer: iOS native video player, supports online video streaming playback.
  • AVAssetResourceLoaderDelegate: Custom resource loader, intercept player requests, and dynamically provide cached data.
  • URLSession: Used to request network and download video data.
  • OutputStream/InputStream: Read and write to local cached files.

2. Implementation process

  • Initialize the player:useAVPlayerandAVURLAssetLoad the video URL.
  • Custom resource loader:passAVAssetResourceLoaderDelegateIntercept player requests and provide cached data dynamically.
  • Network download and cache:useURLSessionDownload the video data and passOutputStreamWrite to local file.
  • Shard cache and breakpoint continuation: According to the player's request range (Range), download and cache video data in chunks.
  • Player and cache collaboration: The player reads cached files in real time, and the network download continues.

2. Core code implementation

1. Initialize the player and cache

import AVFoundation

class VideoPlayerManager {
    private var player: AVPlayer?
    private var cacheURL: URL!
    private var outputStream: OutputStream?
    private var inputStream: InputStream?
    
    func startPlayback(url: URL) {
        // Create cache file path        cacheURL = ("cachedVideo.mp4")
        
        // Initialize the output stream (for writing to cache)        outputStream = OutputStream(toFileAtPath: , append: true)
        outputStream?.open()
        
        // Initialize the input stream (for reading cache)        inputStream = InputStream(url: cacheURL)!
        inputStream?.open()
        
        // Create AVPlayer and bind playback source        let asset = AVURLAsset(url: url)
        let playerItem = AVPlayerItem(asset: asset)
        player = AVPlayer(playerItem: playerItem)
        
        // Custom resource loader        let resourceLoaderDelegate = ResourceLoaderDelegate(outputStream: outputStream, inputStream: inputStream)
        (resourceLoaderDelegate, queue: .main)
        
        // Start playing        player?.play()
        
        // Start the download task        startDownloadTask(url: url)
    }
    
    private func startDownloadTask(url: URL) {
        var request = URLRequest(url: url)
         = "GET"
        
        // Set Range request header (breakpoint continuous transmission)        if let fileData = try? Data(contentsOf: cacheURL),  > 0 {
            let range = "bytes=\()-"
            (range, forHTTPHeaderField: "Range")
        }
        
        let task = (with: request) { [weak self] data, response, error in
            guard let self = self else { return }
            if let data = data {
                // Write the downloaded data to the cache file                (data: data)
            }
        }
        ()
    }
    
    private func writeDataToFile(data: Data) {
        if let outputStream = outputStream {
            let buffer = [UInt8](data)
            (buffer, maxLength: )
            ()
        }
    }
}

2. Custom resource loader

class ResourceLoaderDelegate: NSObject, AVAssetResourceLoaderDelegate {
    private let outputStream: OutputStream?
    private let inputStream: InputStream?
    private var cachedData: Data = Data()
    
    init(outputStream: OutputStream?, inputStream: InputStream?) {
         = outputStream
         = inputStream
    }
    
    func resourceLoader(_ resourceLoader: AVAssetResourceLoader,
                        shouldWaitForLoadingOfRequestedResource loadingRequest: AVAssetResourceLoadingRequest) -> Bool {
        //Read cached data in real time and return it to the player        ().async {
            var buffer = [UInt8](repeating: 0, count: 1024)
            while ?.hasBytesAvailable == true {
                let bytesRead = ?.read(&buffer, maxLength: ) ?? 0
                if bytesRead > 0 {
                    let data = Data(bytes: buffer, count: bytesRead)
                    (with: data)
                }
            }
        }
        return true
    }
    
    func resourceLoader(_ resourceLoader: AVAssetResourceLoader,
                        didCancel loadingRequest: AVAssetResourceLoadingRequest) {
        // Process the cancel request        ()
    }
}

3. Key points analysis

1. Cache Management

  • Local cache:useOutputStreamWrite downloaded video data to local files (such as sandbox directories) to avoid repeated downloads.
  • Sharding cache: According to the player's request range (Range), download and cache video data in chunks to ensure smooth playback.

2. Resuming breakpoint

  • Range request header: By settingRange: bytes=start byte-, realize breakpoint continuous transmission, avoid repeated downloads after network interruption.
  • Cache file check: Check the local cache file size before downloading, and dynamically adjust itRangeRequest header.

3. Player and cache collaboration

  • Real-time read cache:passInputStreamRead downloaded data from local cache files and pass it in real time toAVPlayer
  • Dynamic update cache: During playback, the network download task continues to run to ensure that the cached files are gradually complete.

4. Optimization suggestions

1. Error handling and retry

  • Retry network error: Automatically retry the download task when the network is interrupted to avoid playback interruption.
  • Cache file cleaning: Clean out expired cache files regularly to avoid taking up too much disk space.

2. Performance optimization

  • Asynchronous thread processing:useDispatchQueueAsynchronously handle data reading and writing to avoid blocking the main thread.
  • Memory management: Avoid loading large files into memory at one time, and prioritize the use of local cache.

5. Simplified solution for using KTVHTTPCache

1. Access cache

import KTVHTTPCache

class VideoCacheManager {
    func initCache() {
        do {
            try ()
            let maxLength: Int64 = 300 * 1024 * 1024 // 300MB
            (maxLength)
        } catch {
            print("Proxy Start Failure: $error)")
        }
    }
    
    func playVideo(url: URL) {
        let proxyURLString = (withOriginalURLString: )
        let proxyURL = URL(string: proxyURLString)!
        let player = AVPlayer(url: proxyURL)
        ()
    }
}

2. Implement preloading

func preloadVideos(urls: [URL]) {
    let queue = OperationQueue()
     = 3
    
    for url in urls {
         {
            let proxyURLString = (withOriginalURLString: )
            let proxyURL = URL(string: proxyURLString)!
            let request = URLRequest(url: proxyURL)
            let task = (with: request) { _, _, _ in }
            ()
        }
    }
}

6. Summary

By combiningAVPlayerURLSessionAVAssetResourceLoaderDelegateand local caching technology can efficiently realize the video's playback and cache function. This solution not only improves the user experience, but also effectively reduces network traffic consumption. For complex scenarios (such as HLS streaming, high concurrent downloads), open source libraries can be further combined (such asKTVHTTPCacheorTBPlayer) Simplify the development process.

The above is the detailed content of the solution to enable iOS video caching while playing. For more information about iOS video caching while playing, please pay attention to my other related articles!

  • iOS
  • video
  • Play side by side
  • Side cache

Related Articles

  • Detailed explanation of URL conversion for local routing module URL Rewrite

    This article mainly introduces you to the relevant information about the local routing module URL Rewrite for iOS development. This is a requirement I encountered recently in my work. The example code is introduced in this article in detail, which has certain reference learning value for everyone. Friends who need it, please follow the editor to take a look.
    2017-08-08
  • iOS implements an animation-driven progress bar

    This article mainly introduces the circular progress bar that enables animations in iOS, and also has a digital synchronization effect, which has certain reference value. Interested friends can refer to it.
    2017-01-01
  • Detailed explanation of UIScrollView control for iOS development

    UIScrollView is a very important control that can display contents in a larger area than the device screen. We can view each part of the content view by swiping our fingers, and we can also scale the content view by pinching our fingers. We constantly deal with UIScrollView explicitly or implicitly in development every day. Here is a detailed introduction to the UIScrollView control.
    2016-09-09
  • Full record of real-time remote configuration in iOS

    This article mainly introduces relevant information about real-time remote configuration in iOS. The article introduces the sample code in detail, which has certain reference learning value for iOS developers. Friends who need it, let’s learn together.
    2019-01-01
  • Detailed explanation of IOS image compression processing

    In daily IOS development, I feel that the image size is too large and I want to compress it into smaller pixels. So how to do it? This article uses two concepts and examples of "compression" to tell you how to perform image compression processing.
    2016-07-07
  • iOS Segment with sliding bar switching effect

    This article mainly introduces iOS Segment with sliding bar switching. The sample code in the article is very detailed and has certain reference value. Interested friends can refer to it.
    2022-03-03
  • Implement image cutting and screenshot functions in use of Quartz2D developed by iOS

    This article mainly introduces the method of implementing image cutting and screenshot functions in the use of Quartz2D developed by iOS. The code is based on traditional Objective-C. Friends who need it can refer to it.
    2015-12-12
  • Summary of some special usages of WKWebView in iOS

    This article mainly introduces some special uses of WKWebView in iOS. The article introduces the example code in detail, which has certain reference learning value for everyone to learn or use iOS. If you need it, please learn with the editor below.
    2018-12-12
  • Detailed explanation of various methods for setting the blank top of the UITableview cell in iOS development

    This article mainly introduces the relevant information on the detailed explanation of the various settings of the blank space on the top of the UITableview cell in iOS development. Friends who need it can refer to it.
    2016-04-04
  • ios WeChat browser returns without refreshing the problem perfect solution

    This article mainly introduces the perfect solution to the problem of not refreshing when returning to the ios WeChat browser. Friends who need it can refer to it
    2017-09-09

Latest Comments