ios - IOS 的 Firebase 存储不从相机胶卷上传 .MOV

标签 ios swift firebase firebase-storage phasset

我正在从 PHAsset 对象中检索 URL (file:///var/mobile/Media/DCIM/100APPLE/IMG_0840.MOV),并且能够在设备上很好地重播视频。但是,当需要在 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)
                } 
            }

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

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

谢谢

最佳答案

有时 PHAssets 不会返回 URLAsset,因此我们必须检查给定的 Assets 是否是 AVURLAsset,如果不是,我们必须将此 Assets 保存在我们的文档目录中,然后从文档目录获取 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)
}

希望这对您有所帮助。

关于ios - IOS 的 Firebase 存储不从相机胶卷上传 .MOV,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47682192/

相关文章:

ios - 如何从主视图 Controller 访问 ScrollView 子类(初学者)

ios - 如何在具有方法的 SOAP Web 服务中传递参数?

ios - 如何在 firebase 中更新当前用户的电子邮件和密码(在用户节点和身份验证中)?

ios - 函数签名特化 <Arg[0] = Owned To Guaranteed, Arg[1] = Owned To Guaranteed>

angular - 如何使用 AngularFire、Firestore 和 Firebase 分页到上一页

swift - Firebase 删除值无法正常工作

reactjs - 尝试获取超出范围索引 NaN 的框架(实时数据库)

ios - 如何在 Swift 中使用 MarqueeLabel?

ios - 如何解决错误“viewController 对 swift 协议(protocol) UIScrollViewDelegate 的冗余一致性?

swift - 获取时出现键值编码兼容错误