I have an app that successfully records and uploads a file to my PHP server, but unfortunately the file either uploads as 0 bytes or won't play. I received guidance that I needed to use
AVAssetExportSession
to convert the file to mp4
to get it to work but am having trouble incorporating this into my code correctly. Any help is greatly appreciated.//Image Picker Code
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
print("Got a video")
if let pickedVideo:URL = (info[UIImagePickerControllerMediaURL] as? URL) {
/
let selectorToCall = #selector(CameraVideoViewController.videoWasSavedSuccessfully(_:didFinishSavingWithError:context:))
UISaveVideoAtPathToSavedPhotosAlbum(pickedVideo.relativePath, self, selectorToCall, nil)
imageSelected = true
uuid = UUID().uuidString
if imageSelected == true {
saveFileName = "video-\(uuid).mp4"
}
/
let videoData = try? Data(contentsOf: pickedVideo)
let paths = NSSearchPathForDirectoriesInDomains(
FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true)
let documentsDirectory: URL = URL(fileURLWithPath: paths[0])
let dataPath = documentsDirectory.appendingPathComponent(saveFileName)
try! videoData?.write(to: dataPath, options: [])
print("Saved to " + dataPath.absoluteString)
imagePicker.dismiss(animated: true, completion: {
/
self.encodeVideo(dataPath as AnyObject)
/
})
} }
// Convert to mp4 code
func encodeVideo(_ videoData: AnyObject) {
let avAsset = AVURLAsset(url: videoData as! URL, options: nil)
let startDate = Foundation.Date()
/
let exportSession = AVAssetExportSession(asset: avAsset, presetName: AVAssetExportPresetPassthrough)
/
/
let documentsDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
let myDocumentPath = URL(fileURLWithPath: documentsDirectory).appendingPathComponent("temp.mp4").absoluteString
let url = URL(fileURLWithPath: myDocumentPath)
let documentsDirectory2 = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] as URL
let filePath = documentsDirectory2.appendingPathComponent("rendered-Video.mp4")
deleteFile(filePath)
/
if FileManager.default.fileExists(atPath: myDocumentPath) {
do {
try FileManager.default.removeItem(atPath: myDocumentPath)
}
catch let error {
print(error)
}
}
exportSession!.outputURL = filePath
exportSession!.outputFileType = AVFileType.mp4
exportSession!.shouldOptimizeForNetworkUse = true
let start = CMTimeMakeWithSeconds(0.0, 0)
let range = CMTimeRangeMake(start, avAsset.duration)
exportSession?.timeRange = range
exportSession!.exportAsynchronously(completionHandler: {() -> Void in
switch exportSession!.status {
case .failed:
print("%@",exportSession?.error! as Any)
case .cancelled:
print("Export canceled")
case .completed:
/
let endDate = Foundation.Date()
let time = endDate.timeIntervalSince(startDate)
print(time)
print("Successful!")
print(exportSession?.outputURL as Any)
let mediaPath = exportSession?.outputURL?.path as String!
print(mediaPath)
self.uploadVideo(mediaPath! as String)
/
/
/
/
default:
break
}
})
}
// Upload video
func createBodyWithParamsVideo(_ parameters: [String: String]?, filePathKey: String?, mediaPath: Data, boundary: String) -> Data {
var body = ""
if let params = parameters {
for (key, value) in params {
body += "--\(boundary)\r\n"
body += "Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n"
body += "\(value)\r\n"
}
}
var filename = ""
if imageSelected {
filename = "video-\(uuid).mp4"
}
let mimetype = "video/mp4"
body += "--\(boundary)\r\n"
body += "Content-Disposition: form-data; name=\"\(filePathKey!)\"; filename=\"\(filename)\"\r\n"
body += "Content-Type: \(mimetype)\r\n\r\n"
body += String(data: mediaPath, encoding: .utf8)!
body += "\r\n"
body += "--\(boundary)--\r\n"
return Data(body.utf8)
}
/
func uploadVideo(_ mediaPath: String) {
let id = user!["id"] as! String
uuid = UUID().uuidString
let url = URL(string: "http:/
var request = URLRequest(url: url)
request.httpMethod = "POST"
let param = [
"id" : id,
"uuid" : uuid
]
print("just passed videopost page")
/
let boundary = "Boundary-\(UUID().uuidString)"
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
/
/
/
let imageData = Data()
/
request.httpBody = createBodyWithParamsVideo(param, filePathKey: "file", mediaPath: imageData, boundary: boundary)
/
URLSession.shared.dataTask(with: request) { data, response, error in
/
DispatchQueue.main.async(execute: {
if error == nil {
do {
/
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
/
guard let parseJSON = json else {
print("Error while parsing")
return
}
/
let message = parseJSON["message"]
/
if message != nil {
/
self.postBtn.alpha = 0.4
self.imageSelected = false
/
self.tabBarController?.selectedIndex = 4
}
} catch {
/
DispatchQueue.main.async(execute: {
let message = "\(error)"
appDelegate.infoView(message: message, color: colorSmoothRed)
})
return
}
} else {
/
DispatchQueue.main.async(execute: {
let message = error!.localizedDescription
appDelegate.infoView(message: message, color: colorSmoothRed)
})
return
}
})
}.resume()
}