Как конвертировать данные в AVAsset?

Есть ли способ конвертировать данные в AVAsset/AVURLAsset или лучше в AVPlayerItem? Я нашел ответ, который преобразует данные в PHAsset и требует сначала сохранить его на рабочем столе. Есть ли способ лучше?


person Elsammak    schedule 25.04.2018    source источник


Ответы (3)


Поскольку я не нашел способа сделать это без временного файла, основываясь на примере Эльсаммака, вот небольшой вспомогательный класс, который позаботится об удалении временного файла (держите TemporaryMediaFile рядом, пока вы используете AVAsset, временный файл будет удален, когда объект будет освобожден, или вы можете вызвать .deleteFile() вручную для него):

import Foundation
import AVKit

class TemporaryMediaFile {
    var url: URL?

    init(withData: Data) {
        let directory = FileManager.default.temporaryDirectory
        let fileName = "\(NSUUID().uuidString).mov"
        let url = directory.appendingPathComponent(fileName)
        do {
            try withData.write(to: url)
            self.url = url
        } catch {
            print("Error creating temporary file: \(error)")
        }
    }

    public var avAsset: AVAsset? {
        if let url = self.url {
            return AVAsset(url: url)
        }

        return nil
    }

    public func deleteFile() {
        if let url = self.url {
            do {
                try FileManager.default.removeItem(at: url)
                self.url = nil
            } catch {
                print("Error deleting temporary file: \(error)")
            }
        }
    }

    deinit {
        self.deleteFile()
    }
}

Пример использования:

    let data = Data(bytes: ..., count: ...)

    let tempFile = TemporaryMediaFile(withData: data)
    if let asset = tempFile.avAsset {
        self.player = AVPlayer(playerItem: AVPlayerItem(asset: asset))
    }

    // ..keep "tempFile" around while it's playing..

    tempFile.deleteFile()
person Thomas Perl    schedule 23.06.2020

У меня получилось, вот кому интересно.

extension Data {
    func getAVAsset() -> AVAsset {
        let directory = NSTemporaryDirectory()
        let fileName = "\(NSUUID().uuidString).mov"
        let fullURL = NSURL.fileURL(withPathComponents: [directory, fileName])
        try! self.write(to: fullURL!)
        let asset = AVAsset(url: fullURL!)
        return asset
    }
}
person Elsammak    schedule 25.04.2018
comment
Автор спрашивает, может ли он инициализировать AVAsset из данных без создания временного файла. - person vahotm; 30.05.2018

Вы можете сделать следующее: 1. Используйте AVAssetExportSession для экспорта объекта AVAsset в URL-адрес пути к файлу. 2. Преобразуйте его в NSData, используя его метод dataWithContentsOfURL.

NSURL *fileURL = nil;
__block NSData *assetData = nil;
// asset is you AVAsset object
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:asset presetName:AVAssetExportPresetHighestQuality];

exportSession.outputURL = fileURL;
// e.g .mov type 
exportSession.outputFileType = AVFileTypeQuickTimeMovie; 

[exportSession exportAsynchronouslyWithCompletionHandler:^{
    assetData = [NSData dataWithContentsOfURL:fileURL];
    NSLog(@"AVAsset saved to NSData.");
}];

Не забудьте очистить выходной файл после того, как сделаете с ним все, что вам нужно;)

person manish    schedule 25.04.2018
comment
Автор спрашивает, может ли он инициализировать AVAsset из данных, а не наоборот - person vahotm; 30.05.2018