Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert Data to AVAsset?

Is there a way to convert Data to AVAsset/AVURLAsset or better AVPlayerItem? I found an answer that converts Data to PHAsset and requires saving it first to the desk. Is there a better way?

like image 520
Elsammak Avatar asked Apr 25 '18 00:04

Elsammak


2 Answers

I managed to do it, here you are for anyone who is interested.

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
    }
}
like image 100
Elsammak Avatar answered Oct 15 '22 19:10

Elsammak


Since I haven't found a way to do it without a temporary file, based on Elsammak's example, here's a little helper class that takes care of deleting the temporary file (keep the TemporaryMediaFile around as long as you are using the AVAsset, the temporary file will be deleted when the object gets deallocated, or you can call .deleteFile() manually on it):

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()
    }
}

Example usage:

    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()
like image 45
Thomas Perl Avatar answered Oct 15 '22 18:10

Thomas Perl