5.9 C
New York
Thursday, November 14, 2024

ios – Enjoying video Usin AVAsset participant with Can’t Open


Im attempting to make a cache system in order that cache some movies in splash display to have higher consumer expertise expicially for first time opening the app

here is what I did in my cache supervisor

class CacheManager {static let shared = LocalJackpotsCacheManager()
non-public let fileManager = FileManager.default
non-public let cacheDirectory: URL
non-public let databaseURL: URL
non-public var db: OpaquePointer?

non-public init() {
    // Set cacheDirectory to the Paperwork listing
    cacheDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent("VideoCache")
    databaseURL = cacheDirectory.appendingPathComponent("videoCacheMetadata.sqlite")
    
    createCacheDirectoryIfNeeded()
    setupDatabase()
}

non-public func createCacheDirectoryIfNeeded() {
    if !fileManager.fileExists(atPath: cacheDirectory.path) {
        do {
            strive fileManager.createDirectory(at: cacheDirectory, withIntermediateDirectories: true, attributes: nil)
        } catch {
            print("Did not create cache listing: (error)")
        }
    }
}

non-public func setupDatabase() {
    if sqlite3_open(databaseURL.path, &db) == SQLITE_OK {
        let createTableQuery = """
        CREATE TABLE IF NOT EXISTS VideoCache (
            id TEXT PRIMARY KEY,
            path TEXT,
            lastAccessed INTEGER
        );
        """
        if sqlite3_exec(db, createTableQuery, nil, nil, nil) != SQLITE_OK {
            print("Did not create VideoCache desk")
        }
    } else {
        print("Unable to open database")
    }
}

func cacheVideo(from url: URL, forKey key: String, completion: @escaping () -> Void) {
    let hashedKey = key.sha256()
    let destinationURL = cacheDirectory.appendingPathComponent(hashedKey)
    
    if fileManager.fileExists(atPath: destinationURL.path) {
        completion() // File already cached
        return
    }
    
    let downloadTask = URLSession.shared.downloadTask(with: url) { tempURL, _, error in
        guard let tempURL = tempURL, error == nil else {
            print("Obtain error: (error?.localizedDescription ?? "Unknown error")")
            completion()
            return
        }
        
        do {
            strive self.fileManager.moveItem(at: tempURL, to: destinationURL)
            self.updateDatabase(with: hashedKey, filePath: destinationURL.path)
            completion() // Name completion on success
        } catch {
            print("Error saving video to cache: (error)")
            completion()
        }
    }
    downloadTask.resume()
}

func getCachedURL(forKey key: String) -> URL? {
    let hashedKey = key.sha256()
    let fileURL = cacheDirectory.appendingPathComponent(hashedKey)
    return fileManager.fileExists(atPath: fileURL.path) ? fileURL : nil
}

non-public func updateDatabase(with key: String, filePath: String) {
    let updateQuery = """
    INSERT OR REPLACE INTO VideoCache (id, path, lastAccessed) VALUES (?, ?, ?);
    """
    var assertion: OpaquePointer?
    
    if sqlite3_prepare_v2(db, updateQuery, -1, &assertion, nil) == SQLITE_OK {
        let timestamp = Int(Date().timeIntervalSince1970)
        sqlite3_bind_text(assertion, 1, key, -1, nil)
        sqlite3_bind_text(assertion, 2, filePath, -1, nil)
        sqlite3_bind_int(assertion, 3, Int32(timestamp))
        sqlite3_step(assertion)
    } else {
        print("Error getting ready replace assertion")
    }
    
    sqlite3_finalize(assertion)
}

func cleanOldCache(restrict: Int) {
    let selectOldItemsQuery = """
    SELECT id, path FROM VideoCache ORDER BY lastAccessed ASC LIMIT ?;
    """
    var selectStatement: OpaquePointer?
    
    if sqlite3_prepare_v2(db, selectOldItemsQuery, -1, &selectStatement, nil) == SQLITE_OK {
        sqlite3_bind_int(selectStatement, 1, Int32(restrict))
        
        whereas sqlite3_step(selectStatement) == SQLITE_ROW {
            let id = String(cString: sqlite3_column_text(selectStatement, 0))
            let path = String(cString: sqlite3_column_text(selectStatement, 1))
            
            // Delete the file from disk
            do {
                strive fileManager.removeItem(atPath: path)
            } catch {
                print("Error deleting file from disk: (error)")
            }
            
            // Take away from database
            deleteCacheEntry(withId: id)
        }
    }
    
    sqlite3_finalize(selectStatement)
}

non-public func deleteCacheEntry(withId id: String) {
    let deleteQuery = "DELETE FROM VideoCache WHERE id = ?;"
    var deleteStatement: OpaquePointer?
    
    if sqlite3_prepare_v2(db, deleteQuery, -1, &deleteStatement, nil) == SQLITE_OK {
        sqlite3_bind_text(deleteStatement, 1, id, -1, nil)
        sqlite3_step(deleteStatement)
    } else {
        print("Error getting ready delete assertion")
    }
    
    sqlite3_finalize(deleteStatement)
}

}

and the way Im attempting to make use of it

 if let cachedFileURL = LocalJackpotsCacheManager.shared.getCachedURL(forKey: cacheKey) {
                        // Log cached file particulars for affirmation
                        do {
                            let information = strive Information(contentsOf: cachedFileURL)
                            print("Cached file efficiently loaded into Information object, measurement: (information.depend) bytes")
                        } catch {
                            print("Did not load cached file into Information object: (error.localizedDescription)")
                        }
                        // Put together the video for playback
                        let asset = AVURLAsset(url: cachedFileURL, choices: [AVURLAssetPreferPreciseDurationAndTimingKey: true])
                        let playerItem = AVPlayerItem(asset: asset)
                        let participant = AVPlayer(playerItem: playerItem)
                        
                        // Configure the cell with the participant
                        cell.configure(with: participant)
                        participant.play() // Begin playback instantly if desired
                        
                    } else {
                        // If file is just not cached, obtain and cache it
                        LocalJackpotsCacheManager.shared.cacheVideo(from: videoURL, forKey: cacheKey) {
                            if let cachedFileURL = LocalJackpotsCacheManager.shared.getCachedURL(forKey: cacheKey) {
                                
                                DispatchQueue.most important.async {
                                    // Put together the downloaded video for playback
                                    let asset = AVURLAsset(url: cachedFileURL, choices: [AVURLAssetPreferPreciseDurationAndTimingKey: true])
                                    let playerItem = AVPlayerItem(asset: asset)
                                    let participant = AVPlayer(playerItem: playerItem)
                                    
                                    cell.configure(with: participant)
                                    participant.play()
                                }
                            }
                        }
                    }

dk what precisely unsuitable with this however file loaded and printed it is measurement ! preserve says Can’t open

attempt to cache and play video from native and preserve fails

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles