我试图弄清楚几周内实际发生了什么,我不知道为什么我不能在中断后继续播放,所以你们可能知道答案。 AudioSessionSetActive(TRUE)总是返回'!cat',这是kAudioSessionIncompatibleCategory,重新激活,如果我的应用程序在后台播放,我在不同的应用程序。虽然它工作正常并且如果我在我的应用程序中发现中断时继续播放。
原始代码实际上包含所有包含在宏中的AudioSession和AudioQueue调用,如果它意味着错误,则打印OSStatus,但我删除了它以获得更好的可读性。另外,[self pause]只是暂停,所以基本上它会在upause时调用AudioQueueStart(audioQueue,NULL)但是如果AudioSession失败则它不起作用。
音频会话初始化代码:
AudioSessionInitialize(NULL, NULL, _audioSessionInterruptionListener, self);
UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;
AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(sessionCategory), &sessionCategory);
AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, _audioSessionPropertyListener, self);
AudioSessionSetActive(TRUE);
中断处理程序代码:
- (void)handleInterruptionChangeToState:(AudioQueuePropertyID)inInterruptionState
{
if(inInterruptionState == kAudioSessionBeginInterruption)
{
NSLog(@"+Interruption");
if(self.state == NX_STATE_PLAY)
{
[self pause];
AudioSessionSetActive(FALSE);
isPausedByInterruption = YES;
}
}
else if(inInterruptionState == kAudioSessionEndInterruption)
{
if(isPausedByInterruption)
{
AudioSessionSetActive(TRUE);
[self pause];
isPausedByInterruption = FALSE;
}
NSLog(@"-Interruption");
}
}
这个流媒体源代码可以在https://bitbucket.org/and/amaudiostreamer/src/122de41fe6c0/AMAudioStreamer/AMAudioStreamer/Classes/NxAudioStreamer.m找到,如果它能以某种方式帮助解决问题..
答案 0 :(得分:3)
如果您使用的是AudioQueue API,则需要执行一些取决于某些因素的额外步骤。我从来没有这样做过,所以我会把解释留给专家:
Apple开发人员网站上有关于该主题的视频,其中涵盖了该问题。 WWDC 2010会议412 iPhone OS第1部分的音频开发大约在第45分钟你就此问题得到了很好的解释。
答案 1 :(得分:2)
我遇到了问题,当应用程序运行期间出现警报时,用户只需按下设备电源按钮即可进入睡眠状态。然后,从睡眠状态恢复后,我的AudioSessionSetActive
失败并显示“this audiosession type can't be used
”之类的内容。我尝试在Interruptionlistener中set audiosession
之前添加AudioSessionSetActive(true)
属性,但没有运气。
最后我添加了
retry(~1000 times :)
ftw)
AudioSessionSetActive(true),
它解决了我的问题。
答案 2 :(得分:0)
尝试在 else if 条件下激活AudioSession,如下所示:
AVAudioSession *session = [AVAudioSession sharedInstance];
NSError *error = nil;
[session setCategory: AVAudioSessionCategoryPlayback error: &error];
if (error != nil)
NSLog(@"Failed to set category on AVAudioSession");
// AudioSession and AVAudioSession calls can be used interchangeably
OSStatus result = AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, RouteChangeListener, self);
if (result) NSLog(@"Could not add property listener! %d\n", result);
BOOL active = [session setActive: YES error: nil];
if (!active)
NSLog(@"Failed to set category on AVAudioSession");
但是我相信这可能行不通,因为在我的情况下发生的事情是当我在后台时它没有得到任何会话。但是,请尝试分析Apple的aurioTouch example并仅浏览AppDelegate
文件并尝试分析解释同一问题的(void)rioInterruptionListener
方法。
您使用的是直播音频吗?那么我建议你浏览我的question's answer,通过处理我的答案中给出的错误来解决队列启动问题。
希望这对你有帮助。
答案 3 :(得分:0)
kAudioSessionEndInterruption可能会或可能不会打到您的代码,它不是控制播放状态的可靠方法,只是不要在代码中关闭音频会话,一旦它再次获得控制权,它将恢复会话,你的情况,只需注释掉AudioSessionSetActive(FALSE)就可以帮到你。
答案 4 :(得分:0)
如果您查看Audio Session Programming Guide cookbook section中的Listing 7-16 An interruption listener callback function
,代码示例(似乎与您的情况兼容,使用kAudioSessionCategory_MediaPlayback)实际上并不执行
AudioSessionSetActive(FALSE);
在kAudioSessionBeginInterruption
和
AudioSessionSetActive(TRUE);
在kAudioSessionEndInterruption
的情况下打电话。我真的不认为你应该这样做。 This post似乎也解释了这个问题(得到一个kAudioSessionIncompatibleCategory)。如果你注释掉这两个电话怎么办?
当你的应用程序在后台,而不是前景是一个谜时,问题发生的原因。你应该跟踪状态(你似乎正在使用NX_STATE_PLAY),然后有两种不同的方法([self pause]和[self play]),因为[self pause](切换播放状态)可能被称为意外的次数。
答案 5 :(得分:0)
我知道了如何为我工作,你可以尝试冒风险。
在功能
中void _audioSessionInterruptionListener(void *inClientData, UInt32 inInterruptionState)
删除
[(NxAudioStreamer*)inClientData handleInterruptionChangeToState:inInterruptionState];
handleInterruptionChangeToState
,因为audioSessionInterruptionListener
有audioSessionInterruptionListener
作为参数,因此无法在inInterruptionState
中直接处理audioSessionInterruptionListener
。因此请将您修改为void _audioSessionInterruptionListener(void *inClientData, UInt32 inInterruptionState)
{
if(inInterruptionState == kAudioSessionBeginInterruption)
{
NSLog(@"+Interruption");
if(self.state == NX_STATE_PLAY)
{
[self pause];
AudioSessionSetActive(FALSE);
isPausedByInterruption = YES;
}
}
else if(inInterruptionState == kAudioSessionEndInterruption)
{
if(isPausedByInterruption)
{
AudioSessionSetActive(TRUE);
[self pause];
isPausedByInterruption = FALSE;
}
NSLog(@"-Interruption");
}
}
{{1}}