Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/110.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用于IOS的Firebase存储未从摄像机卷上载.MOV_Ios_Swift_Firebase_Firebase Storage_Phasset - Fatal编程技术网

用于IOS的Firebase存储未从摄像机卷上载.MOV

用于IOS的Firebase存储未从摄像机卷上载.MOV,ios,swift,firebase,firebase-storage,phasset,Ios,Swift,Firebase,Firebase Storage,Phasset,我正在检索URL(file:///var/mobile/Media/DCIM/100APPLE/IMG_0840.MOV)从PHAsset对象,我可以在设备上精细回放视频。然而,当需要在Firebase存储上上载/放置文件时,我甚至都没有找回completionHandler //requesting url from asset PHImageManager.default().requestAVAsset(forVideo: asset, options: options,

我正在检索URL(file:///var/mobile/Media/DCIM/100APPLE/IMG_0840.MOV)从PHAsset对象,我可以在设备上精细回放视频。然而,当需要在Firebase存储上上载/放置文件时,我甚至都没有找回completionHandler

    //requesting url from asset
    PHImageManager.default().requestAVAsset(forVideo: asset, options: options, resultHandler: { (videoAsset, audioMix, info) in

            if let assetURL = videoAsset as? AVURLAsset {

               let url = assetURL.url

               //upload from url
            let storageRef = Storage.storage().reference().child("videos").child("\(memory.ID!)")
            let uploadMetaData = StorageMetadata()
            uploadMetaData.contentType = "video/quicktime" 
               self.storageRef.putFile(from: url, metadata: uploadMetaData) { (metaData, error) in

                if error != nil {
                    print(error!.localizedDescription)
                } 
            }
如果我从AVFoundation capture上传一个.mp4文件,带有这样的本地url(file:///var/mobile/Containers/Data/Application/209BB017-13C7-4432-AFE4-EC3A13469900/Documents/ff49bbc9ac794ed28d6f25944f128933.mp4),它工作得很好

我还尝试在Firebase存储控制台上上载.MOV文件,这也很有效


谢谢

有时,PHAssets不会返回URLAsset,因此我们必须检查给定的资产是否为AVURLAsset,如果不是,我们必须将此资产保存在文档目录中,然后从文档目录获取url

func uploadVideoToFirebase(content: PHAsset) {
    let options = PHVideoRequestOptions()
    options.isNetworkAccessAllowed = true
    PHImageManager.default().requestAVAsset(forVideo: content, options: options) { (asset, mix, args) in
        if let asset = asset as? AVURLAsset {
            let url = asset.url
            // URL OF THE VIDEO IS GOT HERE
        } else {
            guard let asset = asset else {return}
            self.startAnimating(message: "Processing.")
            self.saveVideoInDocumentsDirectory(withAsset: asset, completion: { (url, error) in
                if let error = error {
                    print(error.localizedDescription)
                }
                if let url = url {
                    // SAVED IN DOCUMENTS DIRECTORY AND URL IS GOT HERE
                }
            })
        }
    }
}
保存到文档目录:

func saveVideoInDocumentsDirectory(withAsset asset: AVAsset, completion: @escaping (_ url: URL?,_ error: Error?) -> Void) {
    let manager = FileManager.default
    guard let documentDirectory = try? manager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true) else {return}
    var outputURL = documentDirectory.appendingPathComponent("output")
    do {
        try manager.createDirectory(at: outputURL, withIntermediateDirectories: true, attributes: nil)
        let name = NSUUID().uuidString
        outputURL = outputURL.appendingPathComponent("\(name).mp4")
    }catch let error {
        print(error.localizedDescription)
    }
    //Remove existing file
    _ = try? manager.removeItem(at: outputURL)
    guard let exportSession = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetMediumQuality) else {return}
    exportSession.outputURL = outputURL
    exportSession.outputFileType = AVFileTypeMPEG4
    exportSession.exportAsynchronously {
        switch exportSession.status {
        case .completed:
            print("exported at \(outputURL)")
            completion(outputURL, exportSession.error)
        case .failed:
            print("failed \(exportSession.error?.localizedDescription ?? "")")
            completion(nil, exportSession.error)
        case .cancelled:
            print("cancelled \(exportSession.error?.localizedDescription ?? "")")
            completion(nil, exportSession.error)
        default: break
        }
    }
}
我们必须在成功上传后清除此不需要的视频,或者在下一次应用程序发布时清除它。我在下一次应用程序启动时使用此方法清除了它

func clearDocumentsDirectory() {
    let manager = FileManager.default
    guard let documentDirectory = try? manager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true) else {return}
    let outputURL = documentDirectory.appendingPathComponent("output")
    //Remove existing file
    _ = try? manager.removeItem(at: outputURL)
}
希望这有帮助