使用AVPlayer播放多个声音的问题(NOT AVAudioPlayer)

时间:2012-06-04 04:26:25

标签: objective-c xcode4 avfoundation

我正在尝试使用AVFoundation框架和AVPlayerItem在我的iPhone游戏中播放背景歌曲,并且还有声音效果。我已经在互联网上寻求AVPlayerItem和AVPlayer的帮助,但我只是找到了关于AVAudioPlayer的东西。

背景歌曲很好,但是当角色跳跃时,我有两个问题:

1)在初始跳跃(跳跃方法中的[播放器播放])中,跳跃音效会中断背景音乐。

2)如果我再次尝试跳转,游戏会因错误“AVPlayerItem无法与多个AVPlayer实例关联”而崩溃

我的教授告诉我为每个想要播放的声音创建一个新的AVPlayer实例,所以我很困惑。

我正在进行数据驱动设计,因此我的声音文件列在.txt中,然后加载到NSDictionary中。

这是我的代码:

- (void) storeSoundNamed:(NSString *) soundName 
        withFileName:(NSString *) soundFileName
{
    NSURL *assetURL = [[NSURL alloc] initFileURLWithPath:[[NSBundle mainBundle] pathForResource:soundName ofType:soundFileName]];

    AVURLAsset *mAsset = [[AVURLAsset alloc] initWithURL:assetURL options:nil];

    AVPlayerItem *mPlayerItem = [AVPlayerItem playerItemWithAsset:mAsset];

    [soundDictionary setObject:mPlayerItem forKey:soundName];

    NSLog(@"Sound added.");
}

- (void) playSound:(NSString *) soundName
{
    // from .h: @property AVPlayer *mPlayer;
    // from .m: @synthesize mPlayer = _mPlayer;       

    _mPlayer = [[AVPlayer alloc] initWithPlayerItem:[soundDictionary valueForKey:soundName]];

    [_mPlayer play];
    NSLog(@"Playing sound.");
}

如果我将这一行从第二种方法移到第一种方法:

_mPlayer = [[AVPlayer alloc] initWithPlayerItem:[soundDictionary valueForKey:soundName]];

游戏不会崩溃,并且背景歌曲将完美播放,但即使控制台显示“播放声音”,跳跃音效也无法播放。每次跳跃。

谢谢

1 个答案:

答案 0 :(得分:0)

我明白了。

错误消息告诉我我需要知道的一切:每个AVPlayerItem不能有多个AVPlayer,这与我的教学方式相反。

无论如何,我没有将我的AVPlayerItem存储在soundDictionary中,而是将AVURLAssets存储在soundDictionary中,并将soundName作为每个Asset的键。然后我每次想播放声音时都会创建一个新的AVPlayerItem AVPlayer。

另一个问题是ARC。我无法跟踪每个不同项目的AVPlayerItem,因此我必须创建一个NSMutableArray来存储AVPlayerItem和AVPlayer。

这是固定代码:

- (void) storeSoundNamed:(NSString *) soundName 
        withFileName:(NSString *) soundFileName
{
    NSURL *assetURL = [[NSURL alloc] initFileURLWithPath:[[NSBundle mainBundle] pathForResource:soundName ofType:soundFileName]];

    AVURLAsset *mAsset = [[AVURLAsset alloc] initWithURL:assetURL options:nil];

    [_soundDictionary setObject:mAsset forKey:soundName];

    NSLog(@"Sound added.");
}

- (void) playSound:(NSString *) soundName
{
    // beforehand: @synthesize soundArray;
    // in init: self.soundArray = [[NSMutableArray alloc] init];

    AVPlayerItem *mPlayerItem = [AVPlayerItem playerItemWithAsset:[_soundDictionary valueForKey:soundName]];

    [self.soundArray addObject:mPlayerItem];

    AVPlayer *tempPlayer = [[AVPlayer alloc] initWithPlayerItem:mPlayerItem];

    [self.soundArray addObject:tempPlayer];

    [tempPlayer play];

    NSLog(@"Playing Sound.");
}