iphone - AVQueuePlayer和 Audio Session 问题

标签 iphone ios audio avaudioplayer

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

我在商店中有一个应用在应用声音中使用。目前,我正在使用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);
}

对我做错了什么,应该在音频 session 中使用哪些设置或已知的错误/问题的任何见解都将非常有帮助。我愿意考虑使用其他音频引擎,因为在播放视频和同时播放iPod音乐时,这可能会有一些轻微的性能问题,但是我宁愿坚持这种播放音频的方法。

感谢您提供任何帮助。

-瑞安

最佳答案

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

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

因此,我建议再次检查您的代码,并确保所有对playSound的调用都是从主线程进行的。同样,使用performSelectorOnMainThread代替performSelectorAfterDelay可能更好,因为the docs表示:

Invocations of blocks, key-value observers, or notification handlers are not guaranteed to be made on any particular thread or queue. Instead, AV Foundation invokes these handlers on threads or queues on which it performs its internal tasks.

关于iphone - AVQueuePlayer和 Audio Session 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17241483/

相关文章:

ios - 在 iOS 下操作现有 PDF 文档的最佳方法是什么?

ios - 我用 CocoaPods 破坏了 GIT 并且无法 merge/提交

iphone - 使用 MPMoviePlayerController 播放视频,同时使用 AudioQueue 进行录制

audio - ffmpeg "Header Missing"重新编码 mp3 文件时出错

iphone - 如何有效地将图像从服务器加载到tableView?

ios - 每个页面上的 UIScrollview 中的单个 UIView

iphone - PBKDF2-HMAC-SHA256 Objective-C 实现

ios - Swift CoreLocation获取经纬度

iphone - 如何使用 ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering() 从 ExchangeGal 来源获取人数

javascript - HTML/JavaScript 中应用于字典的多个动态音频播放器