在ios上一点一点地播放声音

时间:2014-03-20 16:17:01

标签: ios iphone audio avaudioplayer

我正在尝试按特定顺序播放声音。我设法做到了,但声音之间有微小的延迟。声音以彼此适合的方式录制,因此用户将无法注意到音乐已经改变。

在底线,我必须避免的声音之间存在延迟..

我不会将所有声音都收集到一个长音中,因为我需要在不同时间开始播放不同的声音。

也许有更好的方法然后使用AVAudioPlayer?

这是我的代码:

-(id)init {
     self = [super init];
     if (self) {
       gameMusicSounds = @[gamePlaySound1,gamePlaySound2,gamePlaySound3,gamePlaySound4,gamePlaySound5,gamePlaySound6,gamePlaySound7,gamePlaySound8,gamePlaySound9,gamePlaySound10];
     }
     return self;
 }

-(void)gameMusicNew {

     NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
     currentMusicToPlay = [[defaults objectForKey:CURRENT_GAME_MUSIC] intValue];

     if (currentMusicToPlay >= [gameMusicSounds count]){
         currentMusicToPlay = 0;
     }

     NSString * music = [[NSBundle mainBundle] pathForResource:[gameMusicSounds objectAtIndex:currentMusicToPlay] ofType:@"mp3"];
     self.backgroundMusic = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:music] error:NULL];
     self.backgroundMusic.numberOfLoops = 1;
     self.backgroundMusic.delegate = self;
     [self.backgroundMusic play];

     currentMusicToPlay ++;
     [defaults setObject:[NSString stringWithFormat:@"%i",currentMusicToPlay] forKey:CURRENT_GAME_MUSIC];
     [defaults synchronize];

}

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{
    [self gameMusicNew];
}

---- -----更新

我想与大家分享我写的最终代码,因为我实际上并未在网上找到很多这方面的内容。

基本上我有一组声音我需要一个接一个地播放,当它们结束时,我需要重新开始。我不使用一个长mp3文件的原因是,有时候,如果用户回到应用程序并且他处于游戏中间,我希望他不要听他最后听的音乐。

所以这是代码:

 - (id)init {
    self = [super init];
    if (self) {
       gameMusicSounds = @[gamePlaySound1,gamePlaySound2,gamePlaySound3,gamePlaySound4,gamePlaySound5,gamePlaySound6,gamePlaySound7,gamePlaySound8,gamePlaySound9,gamePlaySound10];
    }
    return self;
 }

-(void)gameMusicNew{

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSString * isGameOver =[defaults objectForKey:IS_GAME_OVER];
    currentMusic = [[defaults objectForKey:CURRENT_GAME_MUSIC] intValue];

    if([isGameOver isEqualToString:@"YES"] || currentMusic >= [gameMusicSounds count]){
         currentMusic = 0;
         [defaults setObject:[NSString stringWithFormat:@"%i",currentMusic] forKey:CURRENT_GAME_MUSIC];
         [defaults synchronize];
    }

    NSMutableArray* songs = [NSMutableArray arrayWithCapacity:[gameMusicSounds count]];

    NSURL* url = [[NSBundle mainBundle] URLForResource:[gameMusicSounds objectAtIndex:currentMusic] withExtension:@"mp3"];
    AVPlayerItem* item = [[AVPlayerItem alloc] initWithURL:url];
    [songs addObject:item];

    self.queue = [AVQueuePlayer queuePlayerWithItems:songs];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(playerItemDidReachEnd:)
                                             name:AVPlayerItemDidPlayToEndTimeNotification
                                           object:[self.queue currentItem]];

     [self.queue play];

     [self addNextMusic];
}

-(void)addNextMusic{

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    currentMusic = [[defaults objectForKey:CURRENT_GAME_MUSIC] intValue];

    int nextMusic = currentMusic + 1;
    if(nextMusic >= [gameMusicSounds count]){
        nextMusic = 0;
    }

    NSURL* url = [[NSBundle mainBundle] URLForResource:[gameMusicSounds objectAtIndex:nextMusic] withExtension:@"mp3"];
    AVPlayerItem* item = [[AVPlayerItem alloc] initWithURL:url];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(playerItemDidReachEnd:)
                                             name:AVPlayerItemDidPlayToEndTimeNotification
                                           object:item];
    [self.queue insertItem:item afterItem:nil]; 
}

- (void)playerItemDidReachEnd:(NSNotification *)notification {

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    currentMusic = [[defaults objectForKey:CURRENT_GAME_MUSIC] intValue];

    currentMusic++;
    if(currentMusic >= [gameMusicSounds count]){
       currentMusic = 0;
    }

    [defaults setObject:[NSString stringWithFormat:@"%i",currentMusic] forKey:CURRENT_GAME_MUSIC];
    [defaults synchronize];

    [self addNextMusic];
}

-(void)stopGameMusic{
    [self.queue removeAllItems];
}

希望它对某人有用。

1 个答案:

答案 0 :(得分:1)

您可以使用AVQueuePlayer执行此操作。它接受多个声音并按顺序播放它们。

要使用它,请创建一个AVPlayerItem对象数组(使用initWithURL:创建指向您声音的每个AVPlayerItem),然后只需添加数组并播放。

以下是我的某个应用中的实际代码。它完全符合您的描述,就像所有的歌曲一样#34;是一首长歌":

NSMutableArray* songs = [NSMutableArray arrayWithCapacity:self.tiles.count];
for (NSString* fnam in self.songsSorted) {
    NSURL* url = [[NSBundle mainBundle] URLForResource:fnam withExtension:@"m4a" subdirectory:@"Songs"];
    AVPlayerItem* item = [[AVPlayerItem alloc] initWithURL:url];
    [songs addObject:item];
}
self.queue = [AVQueuePlayer queuePlayerWithItems:songs];
[self.queue play];