0

我想也许最快的方法是使用声音服务。它非常有效,但我需要按顺序播放声音,而不是重叠。因此,我使用回调方法来检查声音何时结束。这个周期产生大约 0.3 秒的延迟。我知道这听起来很严格,但它基本上是程序的主轴。

编辑:我现在尝试使用AVAudioPlayer,但我无法在不使用的情况下按顺序播放声音,audioPlayerDidFinishPlaying因为这会使我处于与 SoundServices 的回调方法相同的情况。

EDIT2:我认为如果我能以某种方式将我想要播放的声音部分加入一个大文件中,我可以让整个音频文件连续发声。

EDIT3:我认为这可行,但音频重叠:

waitTime = player.deviceCurrentTime;

    for (int k = 0; k < [colores count]; k++)
    {    
        player.currentTime = 0;
        [player playAtTime:waitTime];
        waitTime += player.duration;
    }

谢谢

4

2 回答 2

4

我刚刚尝试了一种我认为对你很有效的技术。建立一个连接你的声音的音频文件。然后构建一些关于你的声音的元数据,如下所示:

@property (strong, nonatomic) NSMutableDictionary *soundData;
@synthesize soundData=_soundData;

- (void)viewDidLoad {
    [super viewDidLoad];

    _soundData = [NSMutableDictionary dictionary];
    NSArray *sound = [NSArray arrayWithObjects:[NSNumber numberWithFloat:5.0], [NSNumber numberWithFloat:0.5], nil];
    [self.soundData setValue:sound forKey:@"soundA"];
    sound = [NSArray arrayWithObjects:[NSNumber numberWithFloat:6.0], [NSNumber numberWithFloat:0.5], nil];
    [self.soundData setValue:sound forKey:@"soundB"];
    sound = [NSArray arrayWithObjects:[NSNumber numberWithFloat:7.0], [NSNumber numberWithFloat:0.5], nil];
    [self.soundData setValue:sound forKey:@"soundC"];
}

第一个数字是文件中声音的偏移量,第二个是持续时间。然后让你的播放器准备好像这样玩......

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];

    NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/audiofile.mp3", [[NSBundle mainBundle] resourcePath]]];

    NSError *error;
    audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
    audioPlayer.numberOfLoops = -1;

    if (audioPlayer == nil)
        NSLog(@"%@", [error description]);              
    else {
        [audioPlayer prepareToPlay];
    }
}

然后你可以像这样构建一个低级的声音播放方法......

- (void)playSound:(NSString *)name withCompletion:(void (^)(void))completion {

    NSArray *sound = [self.soundData valueForKey:name];
    if (!sound) return;

    NSTimeInterval offset = [[sound objectAtIndex:0] floatValue];
    NSTimeInterval duration = [[sound objectAtIndex:1] floatValue];

    audioPlayer.currentTime = offset;
    [audioPlayer play];

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, duration * NSEC_PER_SEC), dispatch_get_current_queue(), ^{
        [audioPlayer pause];
        completion();
    });
}

你可以像这样快速组合播放声音......

- (IBAction)playAB:(id)sender {

    [self playSound:@"soundA" withCompletion:^{
        [self playSound:@"soundB" withCompletion:^{}];
    }];
}

您可以构建一个更高级别的方法,而不是嵌套块,该方法采用声音名称列表并一个接一个地播放它们,如下所示:

- (void)playSoundList:(NSArray *)soundNames withCompletion:(void (^)(void))completion {

    if (![soundNames count]) return completion();

    NSString *firstSound = [soundNames objectAtIndex:0];
    NSRange remainingRange = NSMakeRange(1, [soundNames count]-1);
    NSArray *remainingSounds = [soundNames subarrayWithRange:remainingRange];

    [self playSound:firstSound withCompletion:^{
        [self playSoundList:remainingSounds withCompletion:completion];
    }];
}

像这样称呼它...

NSArray *list = [NSArray arrayWithObjects:@"soundB", @"soundC", @"soundA", nil];
[self playSoundList:list withCompletion:^{ NSLog(@"done"); }];
于 2012-06-26T03:12:26.950 回答
0

我假设您有时想更改顺序或省略声音。(否则,您只需连续构建所有三个声音的资产并播放它)。

那里可能有一个更好的主意,但为了让事情变得非常紧凑,您可以考虑生成该串联资产,预加载它 - 将所有延迟移动到该负载,然后在它周围寻找以改变声音。

于 2012-06-19T00:05:28.207 回答