私はあなたのためにうまくいくと思うテクニックを試しました。サウンドを連結してオーディオファイルを作成します。次に、次のようなサウンドに関するメタデータを作成します。
@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"];
}
最初の数字はファイル内のサウンドのオフセットで、2番目の数字は持続時間です。次に、プレーヤーをこのようにプレイする準備をします...
- (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"); }];