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

Posted

技术标签:

【中文标题】如何获取保存在临时目录中的视频的 url【英文标题】:How to get the url for a video saved in temporary directory 【发布时间】:2020-05-31 04:22:42 【问题描述】:

我需要将视频文件保存到临时目录并保存对它的引用 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")
                                
                            

这是调用的函数:

       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
                    
                
            

        

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

感谢您的帮助,如果需要,可以添加更多信息。谢谢,我

【问题讨论】:

顾名思义,它是临时的,因此一旦您的方法完成,系统可能(并且将)删除它。因此,您有责任在返回 url 之前将您的项目复制/移动到常规文件夹。不要从 tmp 位置返回 url。你不会在那里找到文件了 那么我怎样才能将这个视频文件存储在某个地方以便以后检索呢?它是一个 PHAsset,来自用户的 cam roll,因此除非保存,否则它似乎会消失。 @LeoDabus 您有很多选择,这完全取决于您是否希望用户可以访问您的文件developer.apple.com/library/archive/documentation/… @LeoDabus “取决于您是否希望用户可以访问您的文件”不。我会将视频上传到 firebase 您可以使用应用支持目录***.com/a/34701970/2303865 【参考方案1】:

由于您似乎不希望您的文件对用户可见或在应用启动之间保留,因此 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

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

因此,在您的情况下,您可以在完成上传到 Firebase 存储后将其删除:

func deleteVideoFromTemporaryFolder() 
    do 
        try FileManager.default.removeItem(at: videoFileUrl)
    
    catch 
        fatalError()
    

如果您希望在应用启动之间保留文件,您可以使用 Application Support directory。但由于 Application Support 和 Documents 目录会自动备份,您可能希望通过设置 URL 的 isExcludedFromBackupKey 键将文件从 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()
    

编辑:要从您的 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)
        
    

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

loadVideoData(phAsset: yourPhAsset)  [weak self] videoData in
    guard let strongSelf = self else  return 
    guard let videoData = videoData else 
        return
    
    strongSelf.storeVideoToTemporaryFolder(videoData: videoData)

【讨论】:

我尝试了第一个,但它仍然不起作用:let data = NSData(contentsOf: finalURL!) let newData = Data(referencing: data!) self.storeVideoToTemporaryFolder(videoData: newData) newUserTakenVideo. videoURL = self.tempVideoFileUrl 你能告诉我更多关于什么不起作用的细节吗?我发布的用于读取/写入临时文件夹的代码工作正常,所以您的代码中肯定有不同的问题,让我们找出它是什么! 另外,不使用 NSData,只需使用 Data(contentsOf: yourUrl) 好吧,我运行了我刚刚发送给你的代码,让 finalURL = self 在 PHCachingImageManager().requestAVAsset 代码中,你可以在我上面的 Q 中找到。然后我运行,选择一个视频,然后按 next ,视频应该在视图中播放。然而,有一个声称视频 URL 为 nil 的崩溃 我刚刚编辑了我的答案,向您展示了一个关于如何从 PHAsset 获取数据,然后将其存储在 Temp 文件夹中的工作示例,让我知道它是如何进行的 :)

以上是关于如何获取保存在临时目录中的视频的 url的主要内容,如果未能解决你的问题,请参考以下文章

如何在颤动中获取临时存储目录?

如何将视频保存到相机胶卷并获取资产 URL?

如何将文件保存到无临时目录并查看该目录中文件的内容?

急!加分!如何获取网页视频中的URL地址?如优酷、腾讯这些在线的URL格式。

如何从 PHAsset 获取图像 URL?是不是可以使用 PHAsset URL 将图像保存到文档目录?

如何获取我频道中的所有 youtube 视频 URL?