簡體   English   中英

迅捷和錄音

[英]Swift and audio recording

我正在迅速構建一個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()
    }
}

我的猜測是startRecording()中的catch可以按預期運行,並且可以防止崩潰,但是您沒有在記錄日志。

我建議更改兩個catch語句來打印提供的錯誤對象,如下所示:

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

這是在目標c中進行音頻錄制的一些代碼。

 NSMutableDictionary *recordSetting;

 NSString *recorderFilePath;

 AVAudioRecorder *recorder;

- (void) startRecording{


    AVAudioSession *audioSession = [AVAudioSession sharedInstance];

    NSError *err = nil;

    [audioSession setCategory :AVAudioSessionCategoryPlayAndRecord error:&err];

    if (err) {

        NSLog(@"audioSession: %@ %ld %@", [err domain], (long)[err code], [[err userInfo] description]);

        return;
    }

    [audioSession setActive:YES error:&err];

    err = nil;

    if (err) {

        NSLog(@"audioSession: %@ %ld %@", [err domain], (long)[err code], [[err userInfo] description]);

        return;
    }

    recordSetting = [[NSMutableDictionary alloc] init];

    [recordSetting setValue :[NSNumber numberWithInt:kAudioFormatLinearPCM] forKey:AVFormatIDKey];

    [recordSetting setValue:[NSNumber numberWithFloat:44100.0] forKey:AVSampleRateKey];

    [recordSetting setValue:[NSNumber numberWithInt: 2] forKey:AVNumberOfChannelsKey];

    [recordSetting setValue :[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];

    [recordSetting setValue :[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsBigEndianKey];

    [recordSetting setValue :[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsFloatKey];

    // Create a new dated file
    NSDate *now = [NSDate dateWithTimeIntervalSinceNow:0];

    NSString *caldate = [now description];

    recorderFilePath = [NSString stringWithFormat:@"%@/%@.caf", DOCUMENTS_FOLDER, caldate];

    NSURL *url = [NSURL fileURLWithPath:recorderFilePath];

    err = nil;

    recorder = [[ AVAudioRecorder alloc] initWithURL:url settings:recordSetting error:&err];

    if (!recorder) {

        NSLog(@"recorder: %@ %ld %@", [err domain], (long)[err code], [[err userInfo] description]);

        return;
    }

    //prepare to record
    [recorder setDelegate:self];

    [recorder prepareToRecord];

    recorder.meteringEnabled = YES;

    BOOL audioHWAvailable = audioSession.inputAvailable;

    if (!audioHWAvailable) {

        UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"title_warning", nil) message:NSLocalizedString(@"recorder_warning_message", nil) preferredStyle:UIAlertControllerStyleAlert];

        UIAlertAction* ok = [UIAlertAction actionWithTitle:NSLocalizedString(@"ok_action", nil) style:UIAlertActionStyleDefault handler:nil];

        [alertController addAction:ok];

        [self presentViewController:alertController animated:YES completion:nil];

        return;

    } else {

        [recorder record];
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM