Чтение аудио сэмплов через AVAssetReader

Как вы читаете аудио-образцы через AVAssetReader? Я нашел примеры дублирования или микширования с использованием AVAssetReader, но эти петли всегда управляются контуром AVAssetWriter. Можно ли просто создать AVAssetReader и прочитать его, получить каждый образец и выбросить int32 каждого аудио-образца в массив?

Благодарю.

Чтобы расширить ответ на @ amrox, вы можете получить AudioBufferList из CMBlockBufferRef, например

CMItemCount numSamplesInBuffer = CMSampleBufferGetNumSamples(buffer); AudioBufferList audioBufferList; CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer( buffer, NULL, &audioBufferList, sizeof(audioBufferList), NULL, NULL, kCMSampleBufferFlag_AudioBufferList_Assure16ByteAlignment, &buffer ); for (int bufferCount=0; bufferCount < audioBufferList.mNumberBuffers; bufferCount++) { SInt16* samples = (SInt16 *)audioBufferList.mBuffers[bufferCount].mData; for (int i=0; i < numSamplesInBuffer; i++) { // amplitude for the sample is samples[i], assuming you have linear pcm to start with } } //Release the buffer when done with the samples //(retained by CMSampleBufferGetAudioBufferListWithRetainedblockBuffer) CFRelease(buffer); 
 AVAssetReader *reader = [[AVAssetReader alloc] initWithAsset:asset error:&error]; AVAssetTrack *track = [[asset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]; NSDictionary *settings = @{ AVFormatIDKey : [NSNumber numberWithInt:kAudioFormatLinearPCM] }; AVAssetReaderTrackOutput *readerOutput = [AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:track outputSettings:settings]; [reader addOutput:readerOutput]; [reader startReading]; CMSampleBufferRef sample = [readerOutput copyNextSampleBuffer]; while ( sample ) { sample = [readerOutput copyNextSampleBuffer]; if ( ! sample ) { continue; } CMBlockBufferRef buffer = CMSampleBufferGetDataBuffer(sample); size_t lengthAtOffset; size_t totalLength; char *data; if ( CMBlockBufferGetDataPointer( buffer, 0, &lengthAtOffset, &totalLength, &data ) != noErr ) { NSLog(@"error!"); break; } // do something with data... CFRelease(sample); } 

Ответы здесь не общие. Вызов CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer может завершиться неудачно, если AudioBufferList должен быть разным. При использовании в качестве примера неперечисленных образцов.

Правильный способ – дважды вызвать CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer . Первый вызов запрашивает размер, необходимый для AudioBufferList а второй фактически заполняет AudioBufferList .

 size_t bufferSize = 0; CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer( sampleBuffer, &bufferSize, NULL, 0, NULL, NULL, 0, NULL ); AudioBufferList *bufferList = malloc(bufferSize); CMBlockBufferRef blockBuffer = NULL; CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer( sampleBuffer, NULL, bufferList, bufferSize, NULL, NULL, kCMSampleBufferFlag_AudioBufferList_Assure16ByteAlignment, &blockBuffer ); // handle audio here free(bufferList); CFRelease(blockBuffer); 

В реальном мире вы должны выполнить обработку ошибок, а также не должны malloc каждый кадр, а затем кэшировать AudioBufferList .

  • Изменение позиции UIBarButtonItem в UINavigationBar
  • Использование хеша MD5 в строке в cocoa?
  • Сериализация и десериализация объектов Objective-C в JSON
  • Msgstr "wait_fences: не удалось получить ответ: 10004003"?
  • Воспроизведение музыки в фоновом режиме с помощью AVAudioplayer
  • Как масштабировать UIImageView пропорционально?
  • NSDictionary с упорядоченными ключами
  • UIImage от CALayer - iPhone SDK
  • Программно включить Bluetooth в iphone sdk?
  • Как -performSelector: withObject: afterDelay: работать?
  • Создайте случайную буквенно-цифровую строку в Cocoa
  • Давайте будем гением компьютера.