2
我有一個應用程序,從麥克風錄製聲音,然後通過NSUrlRequest發送到我的網站。爲了測試它,我補充說音頻是從網站播放的,所以我可以聽到它是否工作。
當我在模擬器上測試它時,一切工作正常:錄音和上傳音頻,我可以聽到它,但是當我將它安裝在我的iPhone上時,我聽不到任何聲音,並且在我的網站上有一個損壞的音頻文件。NSUrlRequest工作在模擬器,但不是在iPhone上
我TestNahravani.swift代碼:
import UIKit
import AVFoundation
class TestNahravani: UIViewController, AVAudioRecorderDelegate, AVAudioPlayerDelegate {
@IBOutlet weak var recordButton: UIButton!
@IBOutlet weak var playButton: UIButton!
var soundRecorder: AVAudioRecorder!
var soundPlayer:AVAudioPlayer?
let fileName = "demo.m4a"
override func viewDidLoad() {
super.viewDidLoad()
setupRecorder()
}
@IBAction func recordSound(sender: UIButton) {
if (sender.titleLabel?.text == "Record"){
soundRecorder.record()
sender.setTitle("Stop", for: .normal)
playButton.isEnabled = false
} else {
soundRecorder.stop()
sender.setTitle("Record", for: .normal)
}
}
@IBAction func playSound(sender: UIButton) {
if (sender.titleLabel?.text == "Play"){
recordButton.isEnabled = false
sender.setTitle("Stop", for: .normal)
preparePlayer()
} else {
soundPlayer?.stop()
sender.setTitle("Play", for: .normal)
}
}
// MARK:- AVRecorder Setup
func setupRecorder() {
//set the settings for recorder
let recordSettings = [AVSampleRateKey : NSNumber(value: Float(44100.0)),
AVNumberOfChannelsKey : NSNumber(value: 2),
AVEncoderAudioQualityKey : NSNumber(value: Int32(AVAudioQuality.max.rawValue)),
AVFormatIDKey : NSNumber(value: kAudioFormatMPEG4AAC)]
var error: NSError?
do {
soundRecorder = try AVAudioRecorder(url: getFileURL() as URL, settings: recordSettings)
} catch let error1 as NSError {
error = error1
soundRecorder = nil
}
if let err = error {
print("AVAudioRecorder error: \(err.localizedDescription)")
} else {
soundRecorder.delegate = self
soundRecorder.prepareToRecord()
}
}
// MARK:- Prepare AVPlayer
func preparePlayer() {
var errorX: NSError?
let dirPaths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
let docsDir: AnyObject=dirPaths[0] as AnyObject
var recordedFilePath : String = docsDir.appendingPathComponent(fileName)
let recordedFileURL = getFileURL()
// "currentFilename", "recordedFilePath" and "recordedFileURL" are all global variables
// This recording stored at "recordedFileURL" can be played back fine.
let sendToPath = "http://www.kvetinac97.cz/jt.php"
let sendToURL = NSURL(string: sendToPath)
let recording: NSData! = NSData(contentsOf: recordedFileURL as URL)
if recording == nil {
recordedFilePath = "FailedUpload"
}
let boundary = "--------14737809831466499882746641449----"
let contentType = "multipart/form-data;boundary=\(boundary)"
let beginningBoundary = "--\(boundary)"
let endingBoundary = "--\(boundary)--"
let header = "Content-Disposition: form-data; name=\"\(fileName)\"; filename=\"\(recordedFilePath)\"\r\n"
let body = NSMutableData()
body.append(("\(beginningBoundary)\r\n" as NSString).data(using: String.Encoding.utf8.rawValue)!)
body.append((header as NSString).data(using: String.Encoding.utf8.rawValue)!)
body.append(("Content-Type: application/octet-stream\r\n\r\n" as NSString).data(using: String.Encoding.utf8.rawValue)!)
body.append(recording! as Data) // adding the recording here
body.append(("\r\n\(endingBoundary)\r\n" as NSString).data(using: String.Encoding.utf8.rawValue)!)
let request = NSMutableURLRequest()
request.url = sendToURL! as URL
request.httpMethod = "POST"
request.addValue(contentType, forHTTPHeaderField: "Content-Type")
request.addValue("multipart/form-data", forHTTPHeaderField: "Accept")
request.httpBody = body as Data
let session = URLSession.shared
let task = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
if let data = NSData(contentsOf: NSURL(string: "http://www.kvetinac97.cz/uploads/demo.m4a")! as URL) {
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
try AVAudioSession.sharedInstance().setActive(true)
self.soundPlayer = try AVAudioPlayer(data: data as Data, fileTypeHint: AVFileType.m4a.rawValue)
self.soundPlayer!.delegate = self
self.soundPlayer!.prepareToPlay()
self.soundPlayer!.volume = 1.0
self.soundPlayer!.play()
} catch let error1 as NSError {
errorX = error1
self.soundPlayer = nil
print ("Chyba nejaka \(error1)")
}
}
else {
print ("Smulicka")
}
})
task.resume()
}
func generateBoundaryString() -> String {
return "Boundary-\(NSUUID().uuidString)"
}
// MARK:- File URL
func getCacheDirectory() -> String {
let paths = NSSearchPathForDirectoriesInDomains(.cachesDirectory,.userDomainMask, true)
return paths[0]
}
func getFileURL() -> NSURL {
let path = getCacheDirectory().appending(fileName)
let filePath = NSURL(fileURLWithPath: path)
return filePath
}
// MARK:- AVAudioPlayer delegate methods
func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
recordButton.isEnabled = true
playButton.setTitle("Play", for: .normal)
}
// MARK:- AVAudioRecorder delegate methods
func audioRecorderDidFinishRecording(_ recorder: AVAudioRecorder, successfully flag: Bool) {
playButton.isEnabled = true
recordButton.setTitle("Record", for: .normal)
}
// MARK:- didReceiveMemoryWarning
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
也許問題是由ATS(App Transport Security;例如不使用HTTPS)引起的? –
AllowArbitaryLoads設置爲YES,像iOS文件許可或類似的問題必須有問題 – kvetinac97
您可以通過檢查「recording」變量是否正確初始化來檢查文件權限問題。但我不希望這裏出現問題。也許你應該嘗試發送一個虛擬的數據對象(如文本字符串),並檢查服務器是否接收到正確的數據,如果沒有,可能收到的數據會給你一些提示(如隱藏的「錯誤消息」而不是預期的數據) –