[英]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.