尝试修复 AVAudioPlayer 初次使用时的滞后问题

发布于 2024-11-01 07:57:13 字数 1604 浏览 2 评论 0原文

这个问题已经出现在其他几个问题中:

第一次播放声音时 AVAudioPlayer 启动缓慢

使用 AVAudioPlayer 播放声音时出现延迟

我已尝试实施建议的修复,但没有一个正在解决我的问题。我的应用程序向用户呈现一系列可供触摸的对象,当触摸对象时会播放声音。除了初始触摸时有约 2 秒的延迟之外,此功能非常有效。

为了解决这个问题,我用一个虚拟 aiff 文件初始化我的音频播放器:

- (void)viewDidLoad{
    NSString *soundFile = [Card loadCardSoundPath:@"dummy"];

    AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:
                             [NSURL fileURLWithPath:soundFile] error:nil];
    self.audioPlayer = player;
    [audioPlayer setDelegate:self];
    [audioPlayer prepareToPlay];
//    [audioPlayer play];
    [player release];
...
[super viewDidLoad]; 
}

然后,当触摸一个对象时,我调用:

NSString *soundFile = [Card loadCardSoundPath:name];

if (soundFile != nil){

            AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:
                                     [NSURL fileURLWithPath:soundFile] error:nil];
            self.audioPlayer = player;
            [self.audioPlayer setDelegate:self];
            [self.audioPlayer prepareToPlay];
            [self.audioPlayer play];
            [player release]; 
}

我观察到的行为是这样的: 如果我创建一个虚拟音频,当我单击第一个对象时,我会观察到音频延迟播放器并调用prepareToPlay但不播放。但是,如果我在虚拟音频播放器上调用 play,那么我不会得到初始对象的延迟,但视图加载会延迟 2 秒。

有办法解决这个问题吗?我是否应该简单地在加载时创建一个 AVAudioPlayers 的 NSArray 并告诉它们准备播放,然后在单击对象时调用播放?

This issue has shown up in several other question here on SO:

Slow start for AVAudioPlayer the first time a sound is played

Delay in playing sounds using AVAudioPlayer

I've tried implementing the fixes suggested but none of them are solving my problem. My application presents the user with a grid of objects to touch, when an object is touched a sound is played. This works great except on the initial touch there is a delay of ~2 seconds.

To get around this I initialize my audio player with a dummy aiff file:

- (void)viewDidLoad{
    NSString *soundFile = [Card loadCardSoundPath:@"dummy"];

    AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:
                             [NSURL fileURLWithPath:soundFile] error:nil];
    self.audioPlayer = player;
    [audioPlayer setDelegate:self];
    [audioPlayer prepareToPlay];
//    [audioPlayer play];
    [player release];
...
[super viewDidLoad]; 
}

Then when an object is touched I call:

NSString *soundFile = [Card loadCardSoundPath:name];

if (soundFile != nil){

            AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:
                                     [NSURL fileURLWithPath:soundFile] error:nil];
            self.audioPlayer = player;
            [self.audioPlayer setDelegate:self];
            [self.audioPlayer prepareToPlay];
            [self.audioPlayer play];
            [player release]; 
}

The behavior i'm observing is this: I observe the audio delay when I click the first object if I create a dummy audio player and call prepareToPlay but not play. However if I call play on the dummy audio player then I don't get the delay on the initial object but the view load gets delayed by 2 seconds.

Is there a way to get around this? Should I simply create an NSArray of AVAudioPlayers on load and tell them all to prepare to play, and then just call play when the object is clicked?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

不知在何时 2024-11-08 07:57:13

有时,通过使用 peformSelector:withObject:afterDelay: 来假脱机初始化,可以帮助让 viewDidLoad 返回。例如:

- (void)viewDidLoad{
    // initialization ...
    [super viewDidLoad]; 
    [self performSelector:@selector(primeAudioPlayer) withObject:nil afterDelay:0.1];
}

-(void)primeAudioPlayer {
    NSString *soundFile = [Card loadCardSoundPath:@"dummy"];

    AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:
                             [NSURL fileURLWithPath:soundFile] error:nil];
    [audioPlayer prepareToPlay];
    [player release];
}

Sometimes it can help to let viewDidLoad return by spooling off initialization like that using peformSelector:withObject:afterDelay:. For example:

- (void)viewDidLoad{
    // initialization ...
    [super viewDidLoad]; 
    [self performSelector:@selector(primeAudioPlayer) withObject:nil afterDelay:0.1];
}

-(void)primeAudioPlayer {
    NSString *soundFile = [Card loadCardSoundPath:@"dummy"];

    AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:
                             [NSURL fileURLWithPath:soundFile] error:nil];
    [audioPlayer prepareToPlay];
    [player release];
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文