dciso dciso - 3 months ago 41
Objective-C Question

iOS Stop Audio Playback At Certain Time (AVAudioPlayer End Time)

I'm wanting to play just part of an audio file. This audio file contains 232 spoken words, I have a dictionary that contains the start time of each word. So I have the start and stop times I just can't find a way to stop at a given time or play the file for a certain duration. Any advice and/or sample code to help me would be much appreciated, thanks Jason.

So I've found a solution, there's a problem with how I get endTime but I sure I can fix it.

//Prepare to play
[audioPlayer prepareToPlay];

//Get current time from the array using selected word
audioPlayer.currentTime = [[wordsDict objectForKey:selectedWord] floatValue];

//Find end time - this is a little messy for now
int currentIndex = 0;
int count = 0;

for (NSString* item in wordsKeys) {
if ([item isEqualToString: selectedWord]) {
currentIndex = count+1;
}
count++;
}

//Store found end time
endTime = [[wordsDict objectForKey:[wordsKeys objectAtIndex:currentIndex]] floatValue];

//Start Timer
NSTimer * myAudioTimer = [NSTimer scheduledTimerWithTimeInterval:0.1
target:self
selector:@selector(checkCurrentTime)
userInfo:nil
repeats:YES]
//Now play audio
[audioPlayer play];



//Stop at endTime
- (void) checkCurrentTime {
if(audioPlayer.playing && audioPlayer.currentTime >= endTime)
[audioPlayer stop];
}

Answer

The AVAudioPlayer gives you some neat properties to work with:

  • currentTime: during playback you can rely on this property.

  • playAtTime : starts playing from a pre-defined time.


But first of all I would write some helpers for that:

@interface Word {
    double startTime;
    double endTime;
}

@property double startTime;  
@property double endTime;  

@end

This is just a class to simply working with the following method.

- (void)playWord:(Word *)aWord {

    self.avPlayer.playAtTime = aWord.startTime;
    [avPlayer prepareToPlay];
    [avPlayer play];

    while (avPlayer.playing) {
        /*
        This while loop could be dangerous as it could go on for a long time.
        But because we're just evaluating words, it won't be as much power draining
        */

        if(avPlayer.currentTime >= aWord.endTime;
        [avPlayer stop];
    }
}

I would suggest you to use an array or any other mechanism to automatically switch to the next word. Maybe your could also add a Previous and Next button for handling user input.

Please let me know if that worked for you.

HTH