I am building an iOS app in swift and client returned a problem with audio recording, Basically it doesn't record anything. He tested on an iPhone 5/5s with ios 9.x. Checked for permissions and if he has enough space on the phone, these weren't the issue.
Personally, tested with a iphone 6s device with ios 10.x and iphone 5 on the simulator and the record is working. Anybody encountered this before or maybe I did something wrong that eludes me.
Added comments to the different functions that says what the app does.
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()
}
}
my guess is that the catch
in startRecording()
is working as expected and preventing a crash, but you're not logging it.
i recommend changing the two catch statements print the supplied error object like this:
catch {
// or use an alert controller to display the error
print("caught error: \(error)")
}
Here is some code for audio recording in objective 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];
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With