我正在 swift 构建一个iOS应用,客户端返回了一个录音问题,基本上它什么也没记录。他在装有ios 9.x的iPhone 5/5s上进行了测试。
检查权限,如果他在电话上有足够的空间,这些都不是问题。

就个人而言,已在模拟器上使用装有ios 10.x和iphone 5的iphone 6s设备进行了测试,并且记录正常。任何人以前都遇到过这种情况,或者我做错了一些事情,使我难以捉摸。

添加了对不同功能的注释,以说明应用程序的功能。

protocol RecordAndPlayManagerDelegate : class{
    func recorderDidStopRecording()
}

class RecordAndPlayManager: NSObject, AVAudioRecorderDelegate {
    var soundRecorder: AVAudioRecorder!
    let recordSettings = [
        AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
        AVSampleRateKey: 12000,
        AVNumberOfChannelsKey: 1,
        AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue
    ]
    class func directoryURL() -> URL? {
        let fileManager = FileManager.default
        let urls = fileManager.urls(for: .documentDirectory, in: .userDomainMask)
        let documentDirectory = urls[0] as URL
        let soundURL = documentDirectory.appendingPathComponent("recording.m4a")
        return soundURL
    }

    //calling this from outside to get the audio
    class func getLocalOrRemoteRecording(_ recordingID : String!) -> URL?{

        let fileManager = FileManager.default
        let urls = fileManager.urls(for: .documentDirectory, in: .userDomainMask)
        let documentDirectory = urls[0] as URL
        let soundURL = documentDirectory.appendingPathComponent(recordingID)

        if (fileManager.fileExists(atPath: soundURL.path)){
            return soundURL
        }

        let path = kBaseServerURLNOPORT + "data/" + recordingID
        let url = URL(string: path)

        return url

    }

    //called from outside, recordingID -> name of the file
    class func storeRecording(_ recordingID : String!) -> URL? {
        let fileManager = FileManager.default
        let urls = fileManager.urls(for: .documentDirectory, in: .userDomainMask)
        let documentDirectory = urls[0] as URL
        let soundURL = documentDirectory.appendingPathComponent("recording.m4a")

        let data = try? Data(contentsOf: soundURL)
        //data here has only 28bytes and from this I know it didn't record. In my tests, I always get at least 20000 bytes.

        let newSoundURL = documentDirectory.appendingPathComponent(recordingID)
        try? data?.write(to: newSoundURL, options: [.atomic])

        do {
            try  FileManager.default.removeItem(at: soundURL)
        } catch _ {
            print("failed to delete file")
            return newSoundURL
        }

        return newSoundURL
    }

    //called on viewDidLoad in another screen
    func setupRecorder() {
        let url = DRMessageRecordAndPlayManager.directoryURL()!
        do {
            try self.soundRecorder = AVAudioRecorder(url: url, settings: self.recordSettings)
        } catch _ {
            return
        }
        soundRecorder.delegate = self
        soundRecorder.prepareToRecord()
    }

    //calling this from outside to start recording
    func startRecording() {
        if !self.soundRecorder.isRecording {
            let audioSession = AVAudioSession.sharedInstance()
            do {
                try audioSession.setCategory(AVAudioSessionCategoryPlayAndRecord)
                try audioSession.setActive(true)
                soundRecorder.record(forDuration: 15)
            } catch {
            }
        }
    }

    //called from outside when I hit stop
    func stopRecording() {

        self.soundRecorder.stop()
        let audioSession = AVAudioSession.sharedInstance()

        do {
            try audioSession.setActive(false)
        } catch {
        }
    }

    func audioRecorderDidFinishRecording(_ recorder: AVAudioRecorder, successfully flag: Bool) {
        self.delegate?.recorderDidStopRecording()
    }
}

最佳答案

我的猜测是catch中的startRecording()可以按预期运行,并且可以防止崩溃,但是您没有对其进行记录。

我建议更改两个catch语句来打印提供的错误对象,如下所示:

catch {
    // or use an alert controller to display the error
    print("caught error: \(error)")
}

10-05 20:42
查看更多