0

I'm looking to execute some code after a sound has finished playing but don't know what the best way to do it is. I've looked at performSelectorOnMainThread.... but don't fully understand it - even then, i'm not sure if that's the best way to approach the problem. I want to change the text color of a label after my sound has finished playing. I'd appreciate some help. My code is below:

-(void) playWordSound:(UILabel *)label
{
    NSString *path;
    SystemSoundID soundId;
    switch (label.tag)
    {
        case 1:
            path = [[NSBundle mainBundle] pathForResource:@"humpty" ofType:@"wav"];
            break;
        case 2:
            path = [[NSBundle mainBundle] pathForResource:@"dumpty" ofType:@"wav"];
            break;
        case 3:
            path = [[NSBundle mainBundle] pathForResource:@"saty" ofType:@"wav"];
            break;
        case 4:
            path = [[NSBundle mainBundle] pathForResource:@"on 2" ofType:@"wav"];
            break;
        case 5:
            path = [[NSBundle mainBundle] pathForResource:@"a 3" ofType:@"wav"];
            break;
        case 6:
            path = [[NSBundle mainBundle] pathForResource:@"wall" ofType:@"wav"];
            break;
    }
        NSURL *url = [NSURL fileURLWithPath:path];
        AudioServicesCreateSystemSoundID( (CFURLRef)objc_unretainedPointer(url), &soundId);
    AudioServicesPlaySystemSound(soundId); 
    //this is where i want to change the color of the label
}
garethdn
  • 12,022
  • 11
  • 49
  • 83

2 Answers2

2

Use an AVPlayerItem and add an observer for the event AVPlayerItemDidPlayToEndTimeNotification.

e.g.

...

AVPlayerItem* playerItem = [AVPlayerItem playerItemWithAsset:asset];
[playerItem addObserver:self forKeyPath:@"status" options:0 context:&ItemStatusContext];
[[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(playerItemDidReachEnd:)
                                             name:AVPlayerItemDidPlayToEndTimeNotification
                                             object:playerItem];
player = [AVQueuePlayer playerWithPlayerItem:playerItem];
[player play];

...

- (void)playerItemDidReachEnd:(NSNotification *)notification {
    // Do stuff here
}

....

codeghost
  • 1,014
  • 7
  • 14
  • Thanks for your answer. I have `#import #import ` in my .h file but am getting some errors - `itemStatusContext` and `player` both throw undeclared identifier errors – garethdn May 15 '12 at 18:10
  • You only need AVFoundation, but you have to declare all your variables, the code above is just a snippet, you would still need to declare an "AVQueuePlayer *player" and a "static const NSString *ItemStatusContext". Check out the Playback system guide in Xcode docs. – codeghost May 15 '12 at 21:31
0

This method may help you:

OSStatus AudioServicesAddSystemSoundCompletion (
   SystemSoundID                           inSystemSoundID,
   CFRunLoopRef                            inRunLoop,
   CFStringRef                             inRunLoopMode,
   AudioServicesSystemSoundCompletionProc  inCompletionRoutine,
   void                                    *inClientData
);
Martol1ni
  • 4,684
  • 2
  • 29
  • 39