1

我一直在将图像从我的无人机直接下载到我的应用程序时遇到一些问题。我在尝试下载图像时不断收到“系统忙,请稍后重试。(代码:-1004) ”错误消息,我已在 stackoverflow 上查看了 DJI 论坛和其他问题,但未能找到任何解决方案到这个问题。

我已经看过这个问题,但我已经在使用该答案中建议的技术。

这是我为下载图像而编写的函数:

func downloadFilesFromDrone(){

    // get current product
    guard let drone = DJISDKManager.product() else {
        Logger.logError("Product is connected but DJISDKManager.product is nil when attempting to download media")
        return
    }


    // Get camera on drone
    guard  let camera: DJICamera = drone.camera else {
        Logger.logError("Unable to detect Camera in downloadFilesFromDrone()")
        // make recursive call until we are able to detect the camera
        DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
            Logger.logH1("Trying to detect Camera again")
            self.downloadFilesFromDrone()
        }
        return
    }

    Logger.logH1("Successfully detected the camera")

    // check if we can download images with the product
     if !camera.isMediaDownloadModeSupported() {
        Logger.logError("Product does not support media download mode")
        return
    }


    // switch camera mode to allow for media downloads
    camera.setMode( .mediaDownload, withCompletion: {(error) in
        if error != nil {
            print("\(error!.localizedDescription)")
        }
        else {

            // get the media manager from the drone to gain access to the files
            let manager = camera.mediaManager!
            manager.refreshFileList(completion: { (error) in

                if error != nil {
                    print("State: \(manager.fileListState.rawValue)")
                    print("Error refreshing list: \(error!.localizedDescription)")
                }
                else {
                    Logger.logH1("Refreshed file list")
                    print("State: \(manager.fileListState.rawValue)")


                    guard let files = manager.fileListSnapshot() else {
                        Logger.logError("No files to download")
                        return
                    }

                    Logger.logH1("There are files to download")

                    var images: [UIImage] = []

                    for file in files {

                        if file.mediaType == .JPEG {

                            print("Time created: \(file.timeCreated)")

                            DispatchQueue.main.asyncAfter(deadline: .now() + 1) {

                                file.fetchData(withOffset: 0, update: DispatchQueue.main, update: {(_ data: Data?, _ isComplete: Bool, _ error: Error?) -> Void in

                                    if error != nil {
                                        print("State: \(manager.fileListState.rawValue)")
                                        print("Error downloading photo: \(error!)")
                                    }
                                    else {
                                        // unwrap downloaded data and create image
                                        if let data = data, let downloadedImage = UIImage(data: data) {
                                            print("Image was downloaded!")
                                            images.append( downloadedImage )
                                        }
                                    }

                                }) // end of filedata fetch

                            }

                        }

                    } // end of loop


                }
            }) // end of file-refresh block

        }

    })// end of camera setMode block

}

这是用我的无人机测试时这个函数的输出:

*** Product Connected ***
*** Unable to detect Camera in downloadFilesFromDrone() ***
*** Firmware package version is: Unknown ***
--> Trying to detect Camera again
--> Successfully detected the camera
--> Refreshed file list
State: 0
--> There are files to download
Time created: 2017-09-01 15:17:04
Time created: 2017-09-01 15:17:16
Time created: 2017-09-01 15:17:26
Time created: 2017-09-01 15:17:36
Time created: 2017-09-01 15:19:06
State: 0
Error downloading photo: System is busy, please retry later.(code:-1004)
State: 0
Error downloading photo: System is busy, please retry later.(code:-1004)
State: 0
Error downloading photo: System is busy, please retry later.(code:-1004)
State: 0
Error downloading photo: System is busy, please retry later.(code:-1004)

编辑:

下面是我用来从无人机下载图像的代码。

/**
 * This function downloads the N latest images from the drone and passes them to the completionhandler once all images have completed downloading
 */
func downloadImages( files: [DJIMediaFile], howMany: Int, maxErrors: Int, completion: @escaping ([UIImage]) -> Void){

    Logger.logH1("Queueing \(howMany) image(s) to be downloaded")

    func downloadNextImage( files: [DJIMediaFile], fileCount: Int, index: Int = 0, downloadedFiles: [UIImage] = [], errorCount: Int = 0) {

        // stop when we reach the end of the list
        if index == fileCount {
            completion(downloadedFiles)
            return
        }
        else {
            var imageData: Data?
            let file = files[index]

            file.fetchData(withOffset: 0, update: DispatchQueue.main, update: {(_ data: Data?, _ isComplete: Bool, _ error: Error?) -> Void in

                if let error = error {
                    Logger.logError("\(error)")

                    if errorCount < maxErrors {
                        DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
                            Logger.logH1("Attempting to download: \(file.fileName) again")
                            downloadNextImage(files: files, fileCount: fileCount, index: index, downloadedFiles: downloadedFiles, errorCount: errorCount + 1)
                        }

                    }
                    else {
                        Logger.logError("Too many errors downloading the images, try downloading again")
                    }


                }
                else {
                    // if image is done downloading
                    if isComplete {

                        // get full image data
                        if let imageData = imageData, let image = UIImage(data: imageData) {
                            Logger.logH1("Downloaded: \(file.fileName)")

                            // now that the image is done downloading, move onto the next image
                            downloadNextImage(files: files, fileCount: fileCount, index: (index + 1), downloadedFiles: downloadedFiles + [image], errorCount: 0)
                        }
                    }
                        // else, download the file
                    else {

                        // If image exists, append the data
                        if let _ = imageData, let data = data {
                            imageData?.append(data)
                        }
                            // initialize the image data
                        else {
                            imageData = data
                        }

                    }
                }


            }) // end of filedata fetch


        }   // end of else statement
    }

    // bounds checking
    let available = files.count
    let n = howMany > available ? available : howMany

    // grab the N latest images taken by the drone
    let filesToDownload : [DJIMediaFile] = Array ( files.suffix(n) )


    // start the recursive function
    downloadNextImage(files: filesToDownload, fileCount: filesToDownload.count)
}

这是如何称呼它的:

  // get current product
    guard let drone = DJISDKManager.product() else {
        Logger.logError("Product is connected but DJISDKManager.product is nil when attempting to download media")
        return
    }


    // Get camera on drone
    guard  let camera: DJICamera = drone.camera else {
        Logger.logError("Unable to detect Camera in initDownload()")
        return
    }

    Logger.logH1("Successfully detected the camera")

    // check if we can download images with the product
    if !camera.isMediaDownloadModeSupported() {
        Logger.logError("Product does not support media download mode")
        return
    }

    // switch camera mode to allow for media downloads
    camera.setMode( .mediaDownload, withCompletion: {(error) in
        if error != nil {
            print("\(error!.localizedDescription)")
        }
        else {

            // get the media manager from the drone to gain access to the files
            let manager = camera.mediaManager!
            manager.refreshFileList(completion: { (error) in

                if error != nil {
                    print("State: \(manager.fileListState.rawValue)")
                    print("Error refreshing list: \(error!.localizedDescription)")
                }
                else {
                    Logger.logH1("Refreshed file list")
                    print("State: \(manager.fileListState.rawValue)")

                    // get list of files
                    guard let files = manager.fileListSnapshot() else {
                        Logger.logError("No files to download")
                        return
                    }

                    Logger.logH1("There are files to download.. Beginning Download")
                    self.downloadImages(files: files, howMany: waypoints, maxErrors: 4, completion: { images in
                        Logger.logH1("Finished downloading: \(images.count) image(s)")
                        // do something with the images here
                    })



                }
            }) // end of file-refresh block

        }

    })// end of camera setMode block
4

1 回答 1

1

你这里有两个问题。首先,您的 updateBlock 是不够的,因为它假设所有数据都将在一次调用中出现。更仔细地查看fetchData () 的文档

注意updateBlock的定义:“块接收文件数据。它会被多次调用,每次都会返回上次调用后接收到的数据。”

所以你的 updateBlock 需要做这样的事情:

imageData.append(data)
if isComplete {
    image = UIImage(data: imageData)
    // handle image as desired
}

第二个问题是您同时请求异步下载所有文件。您一次只需要下载一个文件,并且只有在上一个文件完成后才能开始下一个文件。例如:

imageData.append(data)
if isComplete {
    image = UIImage(data: imageData)
    // handle image as desired

    // then, initiate next download
    downloadFilesFromDrone()
}
于 2017-09-07T20:03:52.373 回答