繁体   English   中英

AVQueuePlayer和音频会话问题

[英]AVQueuePlayer and audio session issue

我将尝试详细说明我的问题。

我在商店中有一个应用在应用声音中使用。 目前,我正在使用AVQueuePlayer,因为某些声音会重叠并且可以按顺序播放。 当我使用AVPlayer播放嵌入式视频时,正在播放很多这种声音,这可能根本没有关系。 问题是我有整个应用程序停止播放声音的报告。 我无法自己复制此图像,但是我们有很多活跃用户,并且有人报告。 只要报告了此错误,我们就可以确定不只是静音开关或降低音量重新启动应用程序总能解决问题。 有时候,我们听说过神奇的声音没有改变。 我也有一些报告说使用airplay和蓝牙时会发生这种情况,但这可能只是问题或巧合的复杂性。

以下是我正在使用的代码,也许我只是使用了错误的设置或未使用应有的设置,但是此代码在99.9%的时间内有效。

我对所有播放的声音都使用闪屏,以降低用户iPod音乐的音量。

这是我在appDidFinishLaunchingWithOptions中的初始化(也许一开始根本不需要它,对不起混用约定):

AudioSessionInitialize (NULL, NULL, NULL, NULL);

    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];

    UInt32 sessionCategory = kAudioSessionCategory_AmbientSound;
    AudioSessionSetProperty (kAudioSessionProperty_AudioCategory, sizeof (sessionCategory), &sessionCategory);

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

当我播放声音时:

-(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音乐时,这可能会出现一些轻微的性能问题,但是我宁愿坚持这种播放音频的方法。

感谢您提供任何帮助。

-瑞安

我过去有一个类似的问题,发现并发线程访问是原因。

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

因此,我建议再次检查您的代码,并确保所有对playSound调用都是从主线程进行的。 另外,最好使用performSelectorOnMainThread而不是performSelectorAfterDelay文档所述

不能保证在任何特定线程或队列上进行块,键值观察器或通知处理程序的调用。 而是,AV Foundation在其执行内部任务的线程或队列上调用这些处理程序。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM