如何获取保存在临时目录中的视频的 url

3 file-management ios swift

我需要将视频文件保存到临时目录并保存对其 URL 的引用。目前我尝试使用 fileManager 创建临时目录,然后 createFile(atPath: tempDirString,contents:vidData,attributes:nil)。但我无法保存对该文件的完整引用。

我尝试过的:

PHCachingImageManager().requestAVAsset(forVideo: (cell?.assetPH)!, options: nil) { (avAsset, _, _) in
    if let avAsset = avAsset {
        print(avAsset, " the avasset?")
        // vidAVAsset = avAsset

        let avPlayerItem = AVPlayerItem(asset: avAsset)
        let avPlayer = AVPlayer(playerItem: avPlayerItem)
        print(avPlayer, "<-- good?")

        let finalURL = self.urlOfCurrentlyPlayingInPlayer(player: avPlayer)
        print(finalURL, "<-- finalURL YEAH EYAHY YEAH?!?!?")
        // newUserTakenVideo.videoURL = finalURL

        let url = self.addVidToTempURL(vidURL: finalURL!)
        newUserTakenVideo.videoURL = url
        // let newUserTakenVideo = SelectedMedia(videoURL: finalURL, phAsset: (cell?.assetPH)!, thumbnailImg: (cell?.imageView.image)!, uniqueCellID: indexPath)
        // GlobalSharedData.shared.arrayOfCurrentCreateMedia.append(newUserTakenVideo)
    } else {
        print("did noot work")
    }
}
Run Code Online (Sandbox Code Playgroud)

这是称为的函数:

func addVidToTempURL(vidURL: URL) -> URL? {
    let fileManager = FileManager.default
    let tempDir = fileManager.temporaryDirectory
    let tempDirString = tempDir.path
    do {
        print( "tempDir: \(tempDir)" )
        print( "tempDirString: \(tempDirString)" )
        if fileManager.fileExists(atPath: tempDirString ) {
            print( "tempDir exists" )
            do {
                try fileManager.createDirectory( at: tempDir, withIntermediateDirectories: true, attributes: nil )
                print( "tempDir created" )
                if fileManager.fileExists(atPath: tempDirString ) {
                    print( "tempDir exists" )
                    let vidData = try Data(contentsOf: vidURL)
                    fileManager.createFile(atPath: tempDirString, contents: vidData, attributes: nil)
                    print(tempDirString, " the stringfsdsda")
                    // fileManager.urls(for: fileManager.temporaryDirectory, in: fileManager.)
                    let url = URL(string: tempDirString)
                    return url
                } else {
                    print( "tempDir STILL DOES NOT exist" )
                    return nil
                }
            } catch {
                print( "tempDir NOT created" )
                return nil
            }
        } else {
            print( "tempDir DOES NOT exist" )
            do {
                try fileManager.createDirectory( at: tempDir, withIntermediateDirectories: true, attributes: nil )
                print( "tempDir created" )
                if fileManager.fileExists(atPath: tempDirString ) {
                    print( "tempDir exists" )
                    let vidData = try Data(contentsOf: vidURL)
                    fileManager.createFile(atPath: tempDirString, contents: vidData, attributes: nil)
                    print(tempDirString, " the fsdfdsdfsdfsfsd")
                    let url = URL(string: tempDirString)
                    return url
                } else {
                    print( "tempDir STILL DOES NOT exist" )
                    return nil
                }
            } catch {
                print( "tempDir NOT created" )
                return nil
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如何获取此文件位置的 URL 引用?

我感谢任何帮助,并且可以根据需要添加更多信息。谢谢,我

小智 6

由于您似乎不希望您的文件对用户可见或在应用程序启动之间保留,因此Temporary directory听起来非常适合您的用例:

var tempVideoFileUrl: URL {
    return FileManager.default.temporaryDirectory.appendingPathComponent("my_video_name")
}

func storeVideoToTemporaryFolder(videoData: Data) {
    guard !FileManager.default.fileExists(atPath: tempVideoFileUrl.path) else {
        return
    }
    do {
        try videoData.write(to: tempVideoFileUrl)
    }
    catch {
        fatalError()
    }
}

func loadVideoFromTemporaryFolder() -> Data? {
    if let data = try? Data(contentsOf: tempVideoFileUrl) {
        return data
    }
    return nil
}
Run Code Online (Sandbox Code Playgroud)

但值得一提的是,系统可能(并且很可能会)在应用程序退出后清除此目录。建议您在不再需要临时目录/文件后将其删除。

因此,就您的情况而言,您只需在完成上传到 Firebase Storage 后将其删除即可:

func deleteVideoFromTemporaryFolder() {
    do {
        try FileManager.default.removeItem(at: videoFileUrl)
    }
    catch {
        fatalError()
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您希望在应用程序启动之间保留文件,则可以使用Application Support directory. 但由于应用程序支持和文档目录会自动备份,您可能需要通过设置其 URLisExcludedFromBackupKey密钥来从 iCloud 备份中排除您的文件:

var applicationSupportVideoFileUrl: URL {
    let applicationSupportFolderUrl = try! FileManager.default.url(for: .applicationSupportDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
    return applicationSupportFolderUrl.appendingPathComponent("my_video_name")
}

func excludeFromCloudBackup(url: URL) {
    var targetUrl = url
    var isAlreadyExcludedFromBackup: Bool
    do {
        let storedRessourceValues = try targetUrl.resourceValues(forKeys: [URLResourceKey.isExcludedFromBackupKey])
        isAlreadyExcludedFromBackup = storedRessourceValues.isExcludedFromBackup ?? false
    }
    catch {
        fatalError()
    }
    guard !isAlreadyExcludedFromBackup else {
        return
    }
    var ressourceValues = URLResourceValues()
    ressourceValues.isExcludedFromBackup = true
    do {
        try targetUrl.setResourceValues(ressourceValues)
    }
    catch {
        fatalError()
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:要从 PHAsset 获取数据,这应该有效:

import Photos

func loadVideoData(phAsset: PHAsset, completion: @escaping (Data?)->()) {
    guard phAsset.mediaType == .video else {
        return completion(nil)
    }
    let options = PHVideoRequestOptions()
    options.isNetworkAccessAllowed = true
    options.deliveryMode = .highQualityFormat
    PHCachingImageManager().requestAVAsset(forVideo: phAsset, options: options) { (avAsset, _, _) in
        guard let avUrlAsset = avAsset as? AVURLAsset else {
            return
        }
        var videoData: Data?
        do {
            videoData = try Data(contentsOf: avUrlAsset.url)
        } catch {
            fatalError()
        }
        DispatchQueue.main.async {
            completion(videoData)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后只需调用此方法并将您的视频存储在临时文件夹中:

loadVideoData(phAsset: yourPhAsset) { [weak self] videoData in
    guard let strongSelf = self else { return }
    guard let videoData = videoData else {
        return
    }
    strongSelf.storeVideoToTemporaryFolder(videoData: videoData)
}
Run Code Online (Sandbox Code Playgroud)