AVAssetExportSession fails due to "The operation could not be completed" when uploading to https url

I am trying to upload a video file after compressing it to our AWS server.

When uploading without compressing, it works fine.

func uploadVideoToUrlWithoutEncoding(videoUrl: URL, uploadUrl: URL) async -> Bool {
  var videoData = Data()
  do {
    videoData = try Data(contentsOf: videoUrl)
  } catch {
    print("Failed to get video data")
    return false
  }
   
  var request = URLRequest(url: uploadUrl)
  request.setValue("blobs/mov", forHTTPHeaderField: "Content-Type") 
  request.httpMethod = "PUT"
   
  do {
    let (data, response) = try await URLSession.shared.upload(for: request, from: videoData)
    return true
  } catch {
    print("URL upload failed")
    return false
  }
}

Now I am trying to do the same but with compression using AVAssetExportSession. It always fails :(

The code I used is the following:

func uploadVideoToUrl(videoUrl: URL, uploadUrl: URL) async {
  let anAsset = AVAsset(url: videoUrl)
  let preset = AVAssetExportPresetLowQuality
  let outFileType = AVFileType.mov
   
  AVAssetExportSession.determineCompatibility(ofExportPreset: preset, with: anAsset, outputFileType: outFileType) { isCompatible in
    guard isCompatible else {
      return
    }
     
    guard let exportSession = AVAssetExportSession(asset: anAsset, presetName: preset) else {
      return
    }
     
    exportSession.outputFileType = outFileType
    // Testing path/output url
    let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] as URL
    let filePath = documentsDirectory.appendingPathComponent("rendered-Video.mov") // try this for testing
    exportSession.outputURL = uploadUrl // if I set to filePath this works

    exportSession.exportAsynchronously {
      switch exportSession.status {
      case .failed:
        let errorString: String = exportSession.error?.localizedDescription ?? "Unknown Error"
        print("Failed to upload video due to..." + errorString)
        print(exportSession.error!)
      case .cancelled:
        print("Upload video cancelled...")
      case .completed:
        print("Upload video complete!")
      default:
        print("Upload video unload error encountered")
        break
      }
    }
  }
}

This always errors out giving the error: Failed to upload video due to...The operation could not be completed Error Domain=AVFoundationErrorDomain Code=-11800 "The operation could not be completed" UserInfo={NSLocalizedFailureReason=An unknown error occurred (-12105), NSLocalizedDescription=The operation could not be completed, NSUnderlyingError=0x6000019dd5f0 {Error Domain=NSOSStatusErrorDomain Code=-12105 "(null)"}}

Does anyone know why this is happening?

I also tried changing the outputUrl to be local file path just to check. Setting to local path works. So it must be something about the http url I set.

The actual url I use is something like: https://ouraddress.amazonaws.com/location/fileName.mov?X-Amz-Security-Token=tokenvalue

My current guess is that it has to do something with the security of the url?

Any help is greatly appreciated!

Answered by Media Engineer in 739300022

AVAssetExportSession only supports writing to local file URLs, so you'll need to do the upload as a separate step. That said, clearly the error could be more helpful in pointing this out. Could you file a report using the feedback assistant about the unhelpful error? Thanks.

Accepted Answer

AVAssetExportSession only supports writing to local file URLs, so you'll need to do the upload as a separate step. That said, clearly the error could be more helpful in pointing this out. Could you file a report using the feedback assistant about the unhelpful error? Thanks.

Thank you for the reply! I ended up exporting it locally and then using it to export it to url. I will report the unhelpful error, thanks!

AVAssetExportSession fails due to "The operation could not be completed" when uploading to https url
 
 
Q