[英]Can't upload audio file through server using Alamofire
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")
}
我在上面共享了我的代碼。 這里的重點是將音頻錄制為.wav,在應用程序中以及在continueRegist部分中播放,我想使用alamofire調用put方法並將音頻上傳到我們的amazons3server。 錄制和播放音頻部分完全可以正常工作。 問題出在方法continueRegist中。 調用該方法后,我得到正確的響應,它看起來成功。 然后,我從s3服務器的url檢查它。 音頻似乎已上傳,但是當我下載並播放時,它無法正常工作。 我不知道問題出在哪里。
另外,當我嘗試從Postman上傳並選擇文件並提供正確的表單數據信息時,我可以收聽上傳到s3服務器的聲音。 這里可能出什么問題了?
您可以在下面通過郵遞員找到我的請求:
截屏時忘了選擇文件,但它只是一個.wav文件。
請不要問我那些令您不滿意的問題。
希望您能夠幫助我。
謝謝!
問題出在您的Alamofire請求中:您正在使用JSON中的音頻數據構建JSON。 但是,您可以在郵遞員中檢查HTTP代碼(右上方/發送下方),該請求是“多部分表單數據”。
如何實現多部分Alamofire:它應該類似於我不確定appendBodyPart
語句的內容。 他們取決於你的情況
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:
}
})
以下是上傳音頻文件的代碼:
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)
}
}
希望它會有所幫助。
使用上述代碼段的一些注意事項:
withName
設置為您的上傳API參數名稱。 我使用voice
,您可能具有不同的參數名稱。 upload.uploadProgress()
是可選的。 如果不需要,可以將其刪除。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.