Воспроизведение видео с помощью проигрывателя AVAsset с возможностью открытияIOS

Программируем под IOS
Ответить Пред. темаСлед. тема
Anonymous
 Воспроизведение видео с помощью проигрывателя AVAsset с возможностью открытия

Сообщение Anonymous »

Я пытаюсь создать систему кэширования, чтобы кэшировать некоторые видео на экране-заставке, чтобы улучшить взаимодействие с пользователем при первом открытии приложения.
вот что я сделал в своем диспетчере кэша< /p>

Код: Выделить всё

class CacheManager {static let shared = LocalJackpotsCacheManager()

Код: Выделить всё

private let fileManager = FileManager.default
private let cacheDirectory: URL
private let databaseURL: URL
private var db: OpaquePointer?

private init() {
// Set cacheDirectory to the Documents directory
cacheDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent("VideoCache")
databaseURL = cacheDirectory.appendingPathComponent("videoCacheMetadata.sqlite")

createCacheDirectoryIfNeeded()
setupDatabase()
}

private func createCacheDirectoryIfNeeded() {
if !fileManager.fileExists(atPath: cacheDirectory.path) {
do {
try fileManager.createDirectory(at: cacheDirectory, withIntermediateDirectories: true, attributes: nil)
} catch {
print("Failed to create cache directory: \(error)")
}
}
}

private 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("Failed to create VideoCache table")
}
} 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("Download error: \(error?.localizedDescription ?? "Unknown error")")
completion()
return
}

do {
try self.fileManager.moveItem(at: tempURL, to: destinationURL)
self.updateDatabase(with: hashedKey, filePath: destinationURL.path)
completion() // Call 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
}

private func updateDatabase(with key: String, filePath: String) {
let updateQuery = """
INSERT OR REPLACE INTO VideoCache (id, path, lastAccessed) VALUES (?, ?, ?);
"""
var statement: OpaquePointer?

if sqlite3_prepare_v2(db, updateQuery, -1, &statement, nil) == SQLITE_OK {
let timestamp = Int(Date().timeIntervalSince1970)
sqlite3_bind_text(statement, 1, key, -1, nil)
sqlite3_bind_text(statement, 2, filePath, -1, nil)
sqlite3_bind_int(statement, 3, Int32(timestamp))
sqlite3_step(statement)
} else {
print("Error preparing update statement")
}

sqlite3_finalize(statement)
}

func cleanOldCache(limit: 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(limit))

while 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 {
try fileManager.removeItem(atPath: path)
} catch {
print("Error deleting file from disk: \(error)")
}

// Remove from database
deleteCacheEntry(withId: id)
}
}

sqlite3_finalize(selectStatement)
}

private 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 preparing delete statement")
}

sqlite3_finalize(deleteStatement)
}
и как я пытаюсь его использовать

Код: Выделить всё

 if let cachedFileURL = LocalJackpotsCacheManager.shared.getCachedURL(forKey: cacheKey) {
// Log cached file details for confirmation
do {
let data = try Data(contentsOf: cachedFileURL)
print("Cached file successfully loaded into Data object, size: \(data.count) bytes")
} catch {
print("Failed to load cached file into Data object: \(error.localizedDescription)")
}
// Prepare the video for playback
let asset = AVURLAsset(url: cachedFileURL, options: [AVURLAssetPreferPreciseDurationAndTimingKey: true])
let playerItem = AVPlayerItem(asset: asset)
let player = AVPlayer(playerItem: playerItem)

// Configure the cell with the player
cell.configure(with: player)
player.play() // Start playback immediately if desired

} else {
// If file is not cached, download and cache it
LocalJackpotsCacheManager.shared.cacheVideo(from: videoURL, forKey: cacheKey) {
if let cachedFileURL = LocalJackpotsCacheManager.shared.getCachedURL(forKey: cacheKey) {

DispatchQueue.main.async {
// Prepare the downloaded video for playback
let asset = AVURLAsset(url: cachedFileURL, options: [AVURLAssetPreferPreciseDurationAndTimingKey: true])
let playerItem = AVPlayerItem(asset: asset)
let player = AVPlayer(playerItem: playerItem)

cell.configure(with:  player)
player.play()
}
}
}
}
знаю, что именно с этим не так, но файл загружен и распечатан его размера! Keep говорит: «Невозможно открыть».
попытайтесь кэшировать и воспроизвести видео с локального компьютера, но сохранить не удалось.

Подробнее здесь: https://stackoverflow.com/questions/791 ... annot-open
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «IOS»