Я использую AVAssetReaderOutput
для чтения образцов из AVAsset
, выполняю некоторую обработку на них и воспроизвожу результат с помощью RemoteIO AU.Невозможно продолжить чтение с AVAssetReaderOutput после перехода на задний план и обратно на передний план
Проблема заключается в том, что после вызова AudioOutputUnitStop
, чтобы приостановить воспроизведение, затем, перейдя на задний план и обратно на передний план, звук не возобновится после вызова AudioOutputUnitStart
. Это связано с ошибкой, возвращаемой с помощью метода copyNextSampleBuffer
AVAssetReaderOutput
, который называется частью конвейера рендеринга.
status
свойство AVAssetReader
после вызова copyNextSampleBuffer
является AVAssetReaderStatusFailed
, а его свойство error
является Error Domain = AVFoundationErrorDomain Code = -11847 "Операция Прерванный" UserInfo = 0x1d8b6100 {NSLocalizedRecoverySuggestion = Прекратить другие операции и повторите попытку., NSLocalizedDescription = Операция Прерванный}
Я ищу решение, которое не заставит меня переинициализировать весь трубопровод после возвращения на первый план - Надеясь, есть такое решение, которое AVAssetReader
s может выжить приложение будет фон и назад ...
Примечание
- Приложение имеет право воспроизводить аудио в фоновом режиме.
- Я обрабатываю прерывания звука. Установка моего
AVAudioSession
как активного как наAVAudioSessionDelegate
sendInterruptionWithFlags:
событие и всякий раз, когда приложение становится активным. Не имеет значения, выполняю ли я это или нет, получая ту же ошибку.
Некоторый код:
AudioPlayer
@implementation AudioPlayer
...
// Audio Unit Setup
AudioComponentDescription desc;
desc.componentType = kAudioUnitType_Output;
desc.componentSubType = kAudioUnitSubType_RemoteIO;
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
desc.componentFlags = 0;
desc.componentFlagsMask = 0;
AudioComponent defaultOutput = AudioComponentFindNext(NULL, &desc);
AudioComponentInstanceNew(defaultOutput, &_audioUnit);
AudioStreamBasicDescription audioFormat;
FillOutASBDForLPCM(audioFormat, 44100, 2, 16, 16, false, false);
AudioUnitSetProperty(self.audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, kOutputBus, &audioFormat, sizeof(audioFormat));
AURenderCallbackStruct callbackStruct;
callbackStruct.inputProc = RenderCallback;
callbackStruct.inputProcRefCon = (__bridge void*)self;
AudioUnitSetProperty(self.audioUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, kOutputBus, &callbackStruct, sizeof(callbackStruct));
AudioUnitInitialize(self.audioUnit);
Настройка AudioReader
@implementation AudioReader
...
NSError* error = nil;
self.reader = [AVAssetReader assetReaderWithAsset:self.asset error:&error];
NSDictionary *outputSettings = ...
self.readerOutput = [AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:[self.asset.tracks objectAtIndex:0] outputSettings:outputSettings];
[self.reader addOutput:self.readerOutput];
[self.reader startReading];
AudioReader Рендер метод, называемый в конечном итоге с помощью функции RenderCallback
-(BOOL)readChunkIntoBuffer
{
CMSampleBufferRef sampleBuffer = [self.readerOutput copyNextSampleBuffer];
if (sampleBuffer == NULL)
{
NSLog(@"Couldn't copy next sample buffer, reader status=%d error=%@, self.reader.status, self.reader.error);
return NO;
}
...
}
Это для сжатого типа аудио? Сообщается, что некоторые из аппаратных блоков декомпрессии звука на некоторых моделях устройств не могут быть прерваны без перезапуска. – hotpaw2
Интересно. Он предназначен для чтения «AVAsset», извлеченного из песни «MPMediaItem», из пользовательской библиотеки iTunes. Поэтому mp3/m4a, я считаю, что оба сжаты. Что касается «моделей устройств» - это проблема на iPhone 5. Есть ли доступная ссылка для того, что вы описываете? – Danra