【发布时间】:2013-03-21 17:14:52
【问题描述】:
我正在使用 AVAssetReaderOutput 从 AVAsset 读取样本,对它们进行一些处理,然后使用 RemoteIO AU 播放结果。
问题是在调用AudioOutputUnitStop暂停播放后,再到后台再回到前台后,调用AudioOutputUnitStart后音频就不会再开始播放了。这是由于 AVAssetReaderOutput 的 copyNextSampleBuffer 方法返回的错误,该方法作为渲染管道的一部分调用。
调用copyNextSampleBuffer后AVAssetReader的status属性为AVAssetReaderStatusFailed,其error属性为Error Domain=AVFoundationErrorDomain Code=-11847 "Operation Interrupted" UserInfo=0x1d8b6100 {NSLocalizedRecoverySuggestion=停止其他操作并重试。, NSLocalizedDescription=Operation Interrupted}
我正在寻找一种解决方案,它不会迫使我在回到前台后重新初始化整个管道 - 希望有这样的解决方案,AVAssetReaders 可以在应用程序进入后台并返回时存活下来。 ..
注意事项
- 应用有权在后台播放音频。
- 我正在处理音频中断 - 在
AVAudioSessionDelegatesendInterruptionWithFlags:事件和应用程序激活时将我的AVAudioSession设置为活动的。无论我是否这样做都没有区别,都会出现同样的错误。
一些代码:
音频播放器
@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;
}
...
}
【问题讨论】:
-
这是压缩音频类型吗?据报道,某些设备型号上的某些硬件音频解压单元必须重新启动才能中断。
-
有趣。它用于从用户的 iTunes 库中读取从
MPMediaItem检索到的AVAsset,一首歌曲。所以mp3/m4a,我相信两者都是压缩的。关于“设备型号” - 这是 iPhone 5 上的一个问题。您所描述的内容是否有任何可用参考?
标签: ios core-audio audiounit avassetreader