2016-12-21 3 views
5

Я создаю приложение iOS в swift, и клиент возвратил проблему с записью звука, в основном ничего не записывает. Он тестировал iPhone 5/5 с ios 9.x. Проверено на наличие разрешений, и если у него достаточно места на телефоне, это не проблема.Быстрая и аудиозапись

Лично протестирован с устройством iphone 6s с ios 10.x и iphone 5 на симуляторе, и запись работает. Кто-нибудь сталкивался с этим раньше или, может быть, я сделал что-то неправильно, что ускользало от меня.

Добавлены комментарии к различным функциям, которые говорят, что делает приложение.

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() 
    } 
} 
+0

Аудиозапись Лучший учебник в Swift 3.0: https://iosdevcenters.blogspot.com/2016/05/audio-recording-and-playing-in-swift-30.html –

ответ

5

мое предположение о том, что catch в startRecording() работает, как ожидалось и предотвращение аварии, но вы не его регистрации.

я рекомендую изменения в два заявления об уловах печатать прилагаемый объект ошибки, как это:

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

Вот некоторый код для записи звука в объективном с.

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]; 
    } 
} 
+0

Спасибо, но вопрос был о быстрых, а не obj-c. –

Смежные вопросы