当我在 buttonTapped 函数或 AV fileOutput 中使用它上传视频时,函数的不同行为

Different behavior in a function when I use it in a buttonTapped function or in AV fileOutput to upload a video

我要上传一个视频,是AV录制的。

当我在 func fileOutput() 中使用我的 API 函数时它有效。

var urlToUpload: URL?

/// - Tag: DidFinishRecording
func fileOutput(_ output: AVCaptureFileOutput,
                didFinishRecordingTo outputFileURL: URL,
                from connections: [AVCaptureConnection],
                error: Error?) {


    urlToUpload = outputFileURL

    PostApi.shared.uploadTOFireBaseVideo(url: urlToUpload!, userUid: "huhu", success: {

    }) {

    }

然而,当我这样称呼它时:

// Upload a post to Firestore
@IBAction func buttonSendPostTapped(_ sender: RoundedButton) {
    print(urlToUpload!)
    -> (Optional(file:///private/var/mobile/Containers/Data/Application/60C494F1-2C08-476A-81C2-052A51987682/tmp/517523BC-B84B-460D-81C9-2D8FDB4051BA.mov))

    PostApi.shared.uploadTOFireBaseVideo(url: urlToUpload!, userUid: "huhu", success: {

    }) {

    }
}

它不会工作。

我如何上传数据:

let data = NSData(contentsOf: ur as URL) <- "data" 为零,当我从 buttonTapped 调用它并正常工作时,如果我从 fileOutput() 调用它.

为什么我的数据是零,当我从按钮点击时调用它?

// Upload media to firestore
func uploadTOFireBaseVideo(url: URL, userUid: String, success : @escaping () -> Void, failure : @escaping () -> Void) {

    let db = Firestore.firestore()
    let name = "\(Int(Date().timeIntervalSince1970)).mp4"
    let dispatchgroup = DispatchGroup()

    dispatchgroup.enter()

    let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
    let outputurl = documentsURL.appendingPathComponent(name)
    var ur = outputurl

    print(ur)

    self.convertVideo(toMPEG4FormatForVideo: url as URL, outputURL: outputurl) { (session) in
        ur = session.outputURL!
        dispatchgroup.leave()
    }

    dispatchgroup.wait()

    let data = NSData(contentsOf: ur as URL)
    let storageRef = Storage.storage().reference().child("Media").child(name)

    if let uploadData = data as Data? {

        print("if let uploaded data")

        storageRef.putData(uploadData, metadata: nil) { (metadata, error) in
            if error != nil {
                print(error!)
                return
            }

            storageRef.downloadURL(completion: { (url, error) in
                if error != nil {
                    print(error!)
                    return
                }
                    let mediaUrl = url?.absoluteString
                    let dic = ["userUid" : userUid, "postMediaUrl" : mediaUrl ?? "No Media"] as [String : Any]

                    db.collection("posts-media").document(userUid).setData(dic)
                    { err in
                        if let err = err {
                            print("Error adding document: \(err)")
                            failure()
                            return
                        } else {
                            print("Document added")
                            success()
                        }
                    }
                })
            }
        }
    }

// Additional function to convert a video to mp4
func convertVideo(toMPEG4FormatForVideo inputURL: URL, outputURL: URL, handler: @escaping (AVAssetExportSession) -> Void) {

    let asset = AVURLAsset(url: inputURL as URL, options: nil)

    let exportSession = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetHighestQuality)!
    exportSession.outputURL = outputURL
    exportSession.outputFileType = .mp4
    exportSession.exportAsynchronously(completionHandler: {
        handler(exportSession)
    })
}


file:///private/var/mobile/Containers/Data/Application/60C494F1-2C08-476A-81C2-052A51987682/tmp/517523BC-B84B-460D-81C9-2D8FDB4051BA.mov

Optional(file:///private/var/mobile/Containers/Data/Application/60C494F1-2C08-476A-81C2-052A51987682/tmp/517523BC-B84B-460D-81C9-2D8FDB4051BA.mov)

进一步检查 fileOutput(...) 方法的实现。它的内部 cleanup() 例程在控制流离开删除临时视频文件的方法时被调用。这意味着在您的 buttonSendPostTapped 方法中,视频文件可能不再存在。

您需要确保 fileOutput(...) 将文件存储在一个保存位置,并在您完成后自行删除。