AVAssetReader и проблема потоковой передачи аудио-очереди - PullRequest
2 голосов
/ 21 января 2011

У меня проблема с AVAssetReader, чтобы получить сэмплы из библиотеки iPod и транслировать их через аудио-очередь.Я не смог найти ни одного такого примера, поэтому я пытаюсь реализовать свой собственный, но кажется, что AssetReader каким-то образом «облажался» в функции обратного вызова аудио-очереди.В частности, происходит сбой, когда он выполняет copyNextSampleBuffer, т.е. он возвращает ноль, когда он еще не завершен.Я убедился, что указатель существует, и поэтому было бы здорово, если бы кто-нибудь мог помочь.

Ниже приведен код функции обратного вызова, который я использовал.Эта функция обратного вызова «работает», когда она не вызывается обратным вызовом AudioQueue.

    static void HandleOutputBuffer (
        void                *playerStateH,
        AudioQueueRef       inAQ,
        AudioQueueBufferRef inBuffer
        ) {

 AQPlayerState *pplayerState = (AQPlayerState *) playerStateH;
 //if (pplayerState->mIsRunning == 0) return;    



 UInt32 bytesToRead = pplayerState->bufferByteSize;
 [[NSNotificationCenter defaultCenter] postNotificationName:NOTIF_callsample object:nil];


 float * inData =(float *) inBuffer->mAudioData;
 int offsetSample = 0;
 //Loop until finish reading from the music data
 while (bytesToRead) {

  /*THIS IS THE PROBLEMATIC LINE*/
  CMSampleBufferRef sampBuffer = [pplayerState->assetWrapper getNextSampleBuffer]; //the assetreader getting nextsample with copyNextSampleBuffer

  if (sampBuffer == nil) {
   NSLog(@"No more data to read from");
 //  NSLog(@"aro status after null %d",[pplayerState->ar status]);
   AudioQueueStop (
       pplayerState->mQueue,
       false
       );
   pplayerState->mIsRunning = NO;

   return;
  }

  AudioBufferList  audioBufferList;
  CMBlockBufferRef blockBuffer;
  CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer(sampBuffer, NULL, &audioBufferList, sizeof(audioBufferList), NULL, NULL, 0, &blockBuffer);
  AudioBuffer audioBuffer = audioBufferList.mBuffers[0];
  memcpy(inData + (2*offsetSample),audioBuffer.mData,audioBuffer.mDataByteSize);
  bytesToRead = bytesToRead - audioBuffer.mDataByteSize;
  offsetSample = offsetSample + audioBuffer.mDataByteSize/8;



 }
 inBuffer->mAudioDataByteSize = offsetSample*8;

 AudioQueueEnqueueBuffer ( 
        pplayerState->mQueue,
        inBuffer,
        0,
        0
        );


}

Ответы [ 3 ]

2 голосов
/ 06 мая 2011

Я получаю ту же загадочную ошибку. Конечно, «настройка» аудио сеанса заставила ошибку исчезнуть. Вот так я настроил свой аудио сеанс.

- (void)setupAudio {
    [[AVAudioSession sharedInstance] setDelegate:self];
    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:nil];
    NSError *activationError = nil;
    [[AVAudioSession sharedInstance] setActive: YES error:&activationError];

    NSLog(@"setupAudio ACTIVATION ERROR IS %@", activationError);
    [[AVAudioSession sharedInstance] setPreferredIOBufferDuration:0.1 error:&activationError];
    NSLog(@"setupAudio BUFFER DURATION ERROR IS %@", activationError);
}
1 голос
/ 06 сентября 2011

Из Руководства по программированию аудиосеанса, под AVAudioSessionCategoryAmbient:

Эта категория позволяет воспроизводить звук с iPod, Safari и других встроенных приложений, пока ваше приложение воспроизводит звук.

При использовании AVAssetReader, вероятно, используется аппаратный декодер iOS, который блокирует использование AudioQueue. Установка AVAudioSessionCategoryAmbient означает, что звук воспроизводится в программном обеспечении, что позволяет одновременно работать обоим, однако это может повлиять на производительность / срок службы батареи. (См. Руководство по программированию аудиосеанса в разделе «Как категории влияют на кодирование и декодирование»).

0 голосов
/ 22 января 2011

Хорошо, я как-то решил эту странную ошибку ... Очевидно, это из-за того, что аудио сессия не установлена ​​должным образом. Поговорим об отсутствии документации по этому вопросу ...

...