IOS 的 Firebase 存储未从相机胶卷上传 .MOV

Firebase Storage for IOS not uploading .MOV from Camera Roll

我正在从 PHAsset 对象中检索 URL (file:///var/mobile/Media/DCIM/100APPLE/IMG_0840.MOV),并且能够在设备上正常重放视频。但是,当需要在 Firebase 存储上 upload/putfile 时,我什至没有找回我的 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)
                } 
            }

如果我使用本地 url 从 AVFoundation 捕获上传 .mp4 文件,(file:///var/mobile/Containers/Data/Application/209BB017-13C7-4432-AFE4-EC3A13469900/Documents/ff49bbc9ac794ed28d6f25944f128933.mp4),它工作正常。

我也试过在 Firebase 存储控制台上上传一个 .MOV 文件,这也有效。

谢谢

有时 PHAssets 不会 returns 我们使用 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)
}

希望对您有所帮助。