gpt4 book ai didi

ios - 进入后台并返回前台后无法继续从 AVAssetReaderOutput 读取

转载 作者:技术小花猫 更新时间:2023-10-29 10:51:33 25 4
gpt4 key购买 nike

我正在使用 AVAssetReaderOutputAVAsset 中读取样本,对它们进行一些处理,然后使用 RemoteIO AU 播放结果。

问题是在调用 AudioOutputUnitStop 暂停播放后,在转到后台并返回前台后,调用 AudioOutputUnitStart 后音频不会再次启动.这是由于 AVAssetReaderOutputcopyNextSampleBuffer 方法返回的错误,该方法作为渲染管道的一部分被调用。

调用copyNextSampleBufferAVAssetReaderstatus属性为AVAssetReaderStatusFailed,其error 属性是 Error Domain=AVFoundationErrorDomain Code=-11847 "Operation Interrupted"UserInfo=0x1d8b6100 {NSLocalizedRecoverySuggestion=停止其他操作并重试。, NSLocalizedDescription=Operation Interrupted}

我正在寻找一种解决方案,它不会迫使我在回到前台后重新初始化整个管道 - 希望有这样一种解决方案,AVAssetReader 可以在应用程序运行时存活下来背景和背景......

注释

  • 该应用有权在后台播放音频。
  • 我正在处理音频中断 - 在 AVAudioSessionDelegateendInterruptionWithFlags: 事件中以及每当应用程序变为积极的。无论我是否这样做都没有关系,得到同样的错误。

部分代码:

音频播放器

@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);

音频阅读器设置

@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 Render 方法,最终由 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;
}
...
}

最佳答案

图形和 AVReader 基础没有任何连接/链接。混淆可能来自于如果 iOS 看到音频图正在运行(因为那样将无法生成音频数据),它不会“后台”(休眠)进程。这就是为什么当你停止音频图时,2-3 分钟后,iOS 将后台处理你的进程(从 iOS 9 开始)。据推测,iOS 会查看您的进程中正在发生的事情,并决定何时应将您的进程强制置于后台(通过 beginBackgroundTaskWithName:expirationHandler)。

Apple 开发人员出于某种原因决定让 AVReader 在进入后台模式时停止(我最好的猜测是 QA)。好消息是您可以检测到它并在您的进程退出后台模式时恢复,但是您将需要重新启动您的阅读器和阅读器输出。首先,当 AVAssetReaderOutput 的 copyNextSampleBuffer 返回 NULL 时,检查 AVAssetReader.error.code 是否有 AVErrorOperationInterrupted

我们在这里实现无缝恢复的方法是,当我们到达那个点时,我们首先计算我们停止的确切时间(很容易做到——只需维护一个已经输出的样本总数的计数器)。然后,您将需要重新启动您的 AVAssetReaderAVAssetReaderOutput 流程。但这没问题,因为您的良好开发实践会将其封装在一个以寻道时间作为参数的函数中。在该函数中,使用 AVAssetReader.timeRange 查找您需要恢复的时间,然后就可以了!

关于ios - 进入后台并返回前台后无法继续从 AVAssetReaderOutput 读取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15729742/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com