Reputation: 650
class VoiceRecogViewController: UIViewController, AVAudioPlayerDelegate, AVAudioRecorderDelegate {
var audioPlayer: AVAudioPlayer?
var audioRecorder: AVAudioRecorder?
var error: NSError?
var soundFileURL: URL?
var soundFilePath: String = ""
var data : NSData?
@IBOutlet weak var startRocordButton: UIButton!
@IBOutlet weak var stopRecordButton: UIButton!
@IBOutlet weak var playRecordButton: UIButton!
@IBOutlet weak var continueButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
playRecordButton.isEnabled = false
stopRecordButton.isEnabled = false
let dirPaths =
NSSearchPathForDirectoriesInDomains(.documentDirectory,
.userDomainMask, true)
let docsDir = dirPaths[0]
soundFilePath = (docsDir as NSString).appendingPathComponent("sound.wav")
soundFileURL = URL(fileURLWithPath: soundFilePath)
let recordSettings = [AVEncoderAudioQualityKey: AVAudioQuality.min.rawValue,
AVEncoderBitRateKey: 16,
AVNumberOfChannelsKey: 2,
AVSampleRateKey: 44100.0] as [String : Any]
let audioSession = AVAudioSession.sharedInstance()
try! audioSession.setCategory(AVAudioSessionCategoryPlayAndRecord, with: [])
try! audioSession.setActive(true)
if let err = error {
print("audioSession error: \(err.localizedDescription)")
}
do {
audioRecorder = try AVAudioRecorder(url: soundFileURL!,
settings: recordSettings as [String : AnyObject])
} catch {
audioRecorder = nil
}
audioRecorder?.prepareToRecord()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBAction func startRecord(_ sender: AnyObject) {
if audioRecorder?.isRecording == false {
playRecordButton.isEnabled = false
startRocordButton.isEnabled = false
stopRecordButton.isEnabled = true
audioRecorder?.record()
}
}
@IBAction func stopRecord(_ sender: AnyObject) {
stopRecordButton.isEnabled = false
playRecordButton.isEnabled = true
startRocordButton.isEnabled = true
if audioRecorder?.isRecording == true {
audioRecorder?.stop()
} else {
audioPlayer?.stop()
}
}
@IBAction func playRecord(_ sender: AnyObject) {
if audioRecorder?.isRecording == false {
stopRecordButton.isEnabled = true
startRocordButton.isEnabled = false
}
do {
try audioPlayer = AVAudioPlayer(contentsOf: soundFileURL!)
audioPlayer?.delegate = self
audioPlayer?.prepareToPlay()
audioPlayer?.play()
} catch {
print("audioPlayer error")
}
}
@IBAction func continueRegist(_ sender: AnyObject) {
let headers: HTTPHeaders = ["Authorization": "Token ___(**token**)_____",
"Accept": "application/json"]
data = NSData (contentsOf: soundFileURL!)
let parameters: Parameters = ["from_account_id": "3",
"to_account_id": "4",
"file": data!,
]
let URL = "http://leaofımjpüsmfweüdıpckfw"
Alamofire.request(URL, method: .put, parameters: parameters, headers: headers).responseJSON { response in
if let data = response.result.value {
print(data)
}
}
}
func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
startRocordButton.isEnabled = true
stopRecordButton.isEnabled = false
}
func audioPlayerDecodeErrorDidOccur(_ player: AVAudioPlayer, error: Error?) {
print("Audio Play Decode Error")
}
func audioRecorderDidFinishRecording(_ recorder: AVAudioRecorder, successfully flag: Bool) {
}
func audioRecorderEncodeErrorDidOccur(_ recorder: AVAudioRecorder, error: Error?) {
print("Audio Record Encode Error")
}
I shared my code above. Here the point is recording audio as .wav, playing it in app and in continueRegist part I want to call put method with alamofire and upload the audio to our amazons3server. Recording and playing audio part is totally working. The problem is in the method continueRegist. After calling the method, I am getting the correct response, it looks successful. Then, I am checking it from the url of our s3 server. The audio seems like uploaded but when I download and play it, it is not working. I could not figure out the where problem is.
Also, when I try to upload from Postman with selecting file and giving the right form data information, I can listen the sound I uploaded to the s3 server. What might be wrong here?
Below you can find my request through Postman:
I forgot to choose the file when I am taking the screenshot but it is simply a .wav file.
Please do not hesitate to ask me questions those does not satisfy you.
Hope you can help me.
Thanks!
Upvotes: 0
Views: 4691
Reputation: 561
Following is the code to upload audio file:
let uploadAudioURL = "http://<your post API url>"
let header : [String:String] = [
"Authorization" : "<your authorisation token>"
]
let voiceData = try? Data(contentsOf: <url of audio file to upload>)
let params : [String:String] = [
"length" : "39000",
"title" : "Trying to upload",
]
Alamofire.upload(
multipartFormData: { (multipartFormData) in
multipartFormData.append(voiceData!, withName: "voice", fileName: "TempRecordedAudioFile", mimeType: "audio/m4a")
for (key, value) in params {
multipartFormData.append(value.data(using: String.Encoding.utf8)!, withName: key)
}
},
usingThreshold : SessionManager.multipartFormDataEncodingMemoryThreshold,
to : uploadAudioURL,
method: .post,
headers: header){ (result) in
switch result {
case .success(let upload, _, _):
upload.uploadProgress(closure: { (Progress) in
print("Upload Progress: \(Progress.fractionCompleted)")
})
upload.responseJSON { response in
if let JSON = response.result.value {
print("Response : ",JSON)
}
}
case .failure(let encodingError):
print(encodingError)
}
}
Hopefully it will help.
Some points to note for using the above code snippet:
withName
is set to your upload API parameter name. I used voice
, you might have different parameter name.upload.uploadProgress()
is optional. You can delete it if you don't need it.Upvotes: 1
Reputation: 735
The problem is in your Alamofire Request: You are building a JSON with the audio data in the JSON. However, you can check in Postman the HTTP code(top right/under send) that the request is Multi Part Form Data.
How to implement a multipart Alamofire:
It should be something similar to that I am not sure about appendBodyPart
statements. They depend on your case
let audioData: NSData = ...//should be loaded from the file
Alamofire.Manager.upload(.PUT,
URL,
headers: headers,
multipartFormData: { multipartFormData in
multipartFormData.appendBodyPart(data: "3".dataUsingEncoding(NSUTF8StringEncoding), name: "from_account_id")
multipartFormData.appendBodyPart(data: "4".dataUsingEncoding(NSUTF8StringEncoding), name: "to_account_id")
multipartFormData.appendBodyPart(data: audioData, name: "file", fileName: "file", mimeType: "application/octet-stream")
},
encodingCompletion: { encodingResult in
switch encodingResult {
case .Success(let upload, _, _):
upload.responseJSON { response in
}
case .Failure(let encodingError):
// Error while encoding request:
}
})
Upvotes: 3