Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone AVQueuePlayer和音频会话问题_Iphone_Ios_Audio_Avaudioplayer - Fatal编程技术网

Iphone AVQueuePlayer和音频会话问题

Iphone AVQueuePlayer和音频会话问题,iphone,ios,audio,avaudioplayer,Iphone,Ios,Audio,Avaudioplayer,我将尽力详细说明我的问题 我在商店里有一个应用程序,它使用应用程序内声音。目前我使用的是AVQueuePlayer,因为一些声音会重叠,并允许它按顺序播放。当我使用AVPlayer播放嵌入式视频时,会播放很多这样的声音,这可能根本不重要。问题是,我有报告说声音在整个应用程序中停止。我自己无法复制这一点,但我们有很多活跃用户,据一些人报道。无论何时报告,并且我们确定这不仅仅是静音开关或音量下降,重新启动应用程序总能解决问题。偶尔我们会听到声音神奇地返回而没有变化。我也有一些报告说,当使用airpl

我将尽力详细说明我的问题

我在商店里有一个应用程序,它使用应用程序内声音。目前我使用的是AVQueuePlayer,因为一些声音会重叠,并允许它按顺序播放。当我使用AVPlayer播放嵌入式视频时,会播放很多这样的声音,这可能根本不重要。问题是,我有报告说声音在整个应用程序中停止。我自己无法复制这一点,但我们有很多活跃用户,据一些人报道。无论何时报告,并且我们确定这不仅仅是静音开关或音量下降,重新启动应用程序总能解决问题。偶尔我们会听到声音神奇地返回而没有变化。我也有一些报告说,当使用airplay和蓝牙时会发生这种情况,但这可能只是问题或巧合的一个复杂因素

下面是我正在使用的代码,可能我只是使用了一个错误的设置,或者没有使用我应该使用的设置,但是这段代码99.9%的时间都有效

我在播放的所有声音中都使用了回避来降低用户iPod音乐的音量

以下是我在appDidFinishLaunchingWithOptions中的初始化(可能在开始时根本不需要它,很抱歉混合了约定):

当我播放声音时:

-(void)playSound: (NSString *)soundString
{
    OSStatus propertySetError = 0;
    UInt32 allowMixing = true;
    propertySetError |= AudioSessionSetProperty(kAudioSessionProperty_OtherMixableAudioShouldDuck, sizeof(allowMixing), &allowMixing);

    [[AVAudioSession sharedInstance] setActive:YES withFlags:AVAudioSessionSetActiveFlags_NotifyOthersOnDeactivation error:nil];

    NSURL *thisUrl = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/%@.caf", [[NSBundle mainBundle] resourcePath], soundString]];

    AVPlayerItem *item = [[AVPlayerItem alloc] initWithURL:thisUrl];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(reachedEndOfItem:)
                                                 name:AVPlayerItemDidPlayToEndTimeNotification
                                               object:item];

    if(_audioPlayerQueue == nil)
    {
        _audioPlayerQueue = [[AVQueuePlayer alloc] initWithItems:[NSArray arrayWithObject:item]];
    }
    else
    {
        if([_audioPlayerQueue canInsertItem:item afterItem:nil])
        {
            [_audioPlayerQueue insertItem:item afterItem:nil];
        }
    }

    if(_audioPlayerQueue == nil)
    {
        NSLog(@"error");
    }
    else
    {
        [_audioPlayerQueue play];
    }

    return;
}
声音播放完毕后:

- (void)reachedEndOfItem: (AVPlayerItem*)item
{
    [self performSelector:@selector(turnOffDucking) withObject:nil afterDelay:0.5f];
}

- (void)turnOffDucking
{
    NSLog(@"reached end");

    [[AVAudioSession sharedInstance] setActive:NO withFlags:AVAudioSessionSetActiveFlags_NotifyOthersOnDeactivation error:nil];

    OSStatus propertySetError = 0;
    UInt32 allowMixing = false;
    propertySetError |= AudioSessionSetProperty(kAudioSessionProperty_OtherMixableAudioShouldDuck, sizeof(allowMixing), &allowMixing);
}
任何关于我做错了什么、音频会话应该使用什么设置或已知错误/问题的见解都会非常有用。我愿意研究使用不同的音频引擎,因为在播放视频和同时播放iPod音乐时,这可能会有一些轻微的性能问题,但我宁愿坚持使用这种播放音频的方法

谢谢你能提供的任何帮助


-Ryan

我过去也遇到过类似的问题,并发现并发线程访问是原因

具体来说,我认为如果另一个线程试图在延迟结束的同时修改音频会话,那么调用performSelectorAfterDelay可能是原因,因为这样我们将有两个不同的线程尝试访问音频会话


因此,我建议再次检查代码,并确保所有对
playSound
的调用都是从主线程发出的。此外,最好使用
performselectornmainthread
而不是
performSelectorAfterDelay
,例如:

不能保证在任何特定线程或队列上调用块、键值观察器或通知处理程序。相反,AV基金会在执行内部任务的线程或队列上调用这些处理程序。


有没有可能两个不同的线程可以在你的应用程序中同时修改音频会话?我过去也有过类似的问题,发现并发线程访问是原因。写了这篇文章后,我觉得这就是问题所在。你是说我的“performSelectorAfterDelay”才是问题所在?出现这种情况的原因是,通知发生在会话仍处于活动状态时,因此ducking不会关闭。是的,如果另一个线程在延迟结束的同时尝试修改音频会话,这可能是原因之一。因此,我建议再次检查您的代码,并确保对
playSound
的所有调用都是从主线程进行的。此外,最好使用
performSelectorOnMainThread
来代替文档中所说的“块调用、键值观察者、,或者不保证在任何特定的线程或队列“()”上生成通知处理程序。是的,这是一个很好的观点。我会再次检查我所有的播放声音调用是否来自主线程,但它们有50/50的可能性不是,我可以确保我正在调用关闭主线程上的ducking。我接受这个作为答案。在接下来的3天里,我无法验证它,但文档听起来很有说服力,而且频率与我在不同线程上同时随机访问音频会话的频率差不多。
- (void)reachedEndOfItem: (AVPlayerItem*)item
{
    [self performSelector:@selector(turnOffDucking) withObject:nil afterDelay:0.5f];
}

- (void)turnOffDucking
{
    NSLog(@"reached end");

    [[AVAudioSession sharedInstance] setActive:NO withFlags:AVAudioSessionSetActiveFlags_NotifyOthersOnDeactivation error:nil];

    OSStatus propertySetError = 0;
    UInt32 allowMixing = false;
    propertySetError |= AudioSessionSetProperty(kAudioSessionProperty_OtherMixableAudioShouldDuck, sizeof(allowMixing), &allowMixing);
}