無人機から自分のアプリケーションに直接画像をダウンロードする際に問題が発生しました。 「システムがビジー状態です。後で再試行してください。(コード:-1004)」画像をダウンロードしようとすると、DJIフォーラムやその他の質問がstackoverflowでチェックされていますが見つかりませんでしたこの問題に対する任意の解決策。IOS DJI-SDKを使用して無人機から画像をプログラムでダウンロードする方法
私は既にthis questionを見てきましたが、私はすでにその答えから提案されているテクニックを使用しています。ここで
は、私が画像をダウンロードするために書いた関数である:私のドローンをテストするとき
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
完全版の機能版をアップロードできますか? – IanTimmis
@IanTimmis私が使用したソリューションで質問を更新しました。ちなみに、ファンクションが最初のコールでカメラを検出しない場合、カメラが検出される前に複数のコールを試す必要があります。 –