2015-12-21 3 views
2

Я использую следующий код для записи с помощью AVAudioRecorder. Я также получаю доступ к записанному аудио в реальном времени (через 4 секунды). Тем не менее, данные равны NULL до 6 секунд.AVAudioRecorder не записывается в файл достаточно быстро

Есть ли способ принудительно попросить диктофон написать в файл?

NSDictionary * recordSetting; 
recordSetting = [[NSMutableDictionary alloc] init]; 
[recordSetting setValue :[NSNumber numberWithInt:kAudioFormatMPEG4AAC] forKey:AVFormatIDKey]; 
[recordSetting setValue:[NSNumber numberWithFloat:11025] forKey:AVSampleRateKey]; 
[recordSetting setValue:[NSNumber numberWithInt:1] forKey:AVNumberOfChannelsKey]; 

self.fileURL = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/recorded.aac", [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]]]; 
self.recorder = [[AVAudioRecorder alloc] initWithURL:self.fileURL settings:recordSetting error:nil]; 
self.recorder.meteringEnabled = YES; 
self.recorder.delegate = self; 
[self.recorder record]; 

И затем через 4 секунды я попытался прочитать файл, используя NSDate.

NSData *songData = [NSData dataWithContentsOfURL:self.recorder.url]; 

Но песня Data равна нулю до 6 секунд.

Я знаю, что это возможно сделать с помощью AudioQueue, однако я не хочу попасть в AudioQueue, потому что, я думаю, это будет излишество.

Спасибо.

ответ

1

Отказ от ответственности: правильный способ сделать это было бы для записи аудиовхода (через AudioUnit/AVAudioEngine/AudioQueue) и кодировать его с помощью AudioConverter, хотя запись на прошивке является толчком и AudioConverter это тянуть, который не делает для очень хорошее чтение SO. Как вы видели, полагаясь на API высокого уровня, например, AVAudioRecorder, чтобы своевременно записывать свой результат в свой файл, пока вы рыскаете вокруг, он не очень надежный. Следующий пример кода (AVAudioEngine + ExtendedAudioFile) должен получить аудиоданные через ~ 1 секунду.

#import <AVFoundation/AVFoundation.h> 
#import <AudioToolbox/ExtendedAudioFile.h> 
// ... 
@property (nonatomic) AVAudioEngine *engine; 
// ... 

NSURL *fileURL = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/recorded.aac", [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]]]; 


const Float64 sampleRate = 11025; 

AudioStreamBasicDescription aacDesc = { 0 }; 
aacDesc.mSampleRate = sampleRate; 
aacDesc.mFormatID = kAudioFormatMPEG4AAC; 
aacDesc.mFramesPerPacket = 1024; 
aacDesc.mChannelsPerFrame = 1; 

ExtAudioFileRef eaf; 
OSStatus err = ExtAudioFileCreateWithURL((__bridge CFURLRef)fileURL, kAudioFileAAC_ADTSType, &aacDesc, NULL, kAudioFileFlags_EraseFile, &eaf); 
assert(noErr == err); 


self.engine = [[AVAudioEngine alloc] init]; 

AVAudioInputNode *input = self.engine.inputNode; 
const AVAudioNodeBus bus = 0; 

AVAudioFormat *micFormat = [input inputFormatForBus:bus]; 

err = ExtAudioFileSetProperty(eaf, kExtAudioFileProperty_ClientDataFormat, sizeof(AudioStreamBasicDescription), micFormat.streamDescription); 
assert(noErr == err); 

[input installTapOnBus:bus bufferSize:512 format:micFormat block:^(AVAudioPCMBuffer *buffer, AVAudioTime *when) { 
    const AudioBufferList *abl = buffer.audioBufferList; 
    OSStatus err = ExtAudioFileWrite(eaf, buffer.frameLength, abl); 
    assert(noErr == err); 
}]; 

NSError *error; 
if (![self.engine startAndReturnError:&error]) { 
    NSLog(@"Engine start: %@", error); 
} 
+0

Привет, возможно ли здесь захватить аудиосреднюю мощность, например AVAudioRecorder? – moeseth

+0

Нет, вам придется делать это вручную с помощью входящих буферов, но это не сложно. –

+0

Как я могу преобразовать этот буфер в формат wav, который может читать FFMPEG? – moeseth

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