user1120133
user1120133

Reputation: 3234

check avaudioplayer's current playback time

Is this the right way to check AVAudioPlayer's current playback time.

[audioPlayer play];

float seconds = audioPlayer.currentTime;

float seconds = CMTimeGetSeconds(duration); 

How I can code after

  [audioPlayer play]; 

that when currentTime is equal to 11 seconds then

[self performSelector:@selector(firstview) withObject:nil]; 

and after firstview when currentTime is equal to 23 seconds

[self performSelector:@selector(secondview) withObject:nil];

Upvotes: 6

Views: 6163

Answers (2)

Sreekuttan
Sreekuttan

Reputation: 1954

Use the AVPlayer's addPeriodicTimeObserver method to observe time changes.

Code:

private(set) var duration: CMTime?
private(set) var currentTime: CMTime?

private let player = AVPlayer()
private var timeObserver: Any?

/// Adds an observer of the player timing.
private func addPeriodicTimeObserver() {
    // Create a 0.5 second interval time.
    let interval = CMTime(value: 1, timescale: 2)
    timeObserver = player.addPeriodicTimeObserver(forInterval: interval,
                                                  queue: .main) { [weak self] time in
        guard let self else { return }
        // Update the currentTime and duration values.
        currentTime = time
        duration = player.currentItem?.duration
        
        // Update your UI
        // playerTimeLabel.text = currentTime?.positionalTime
        // totalTimeLabel.text = duration?.positionalTime
        
    }
}


/// Removes the time observer from the player.
private func removePeriodicTimeObserver() {
    guard let timeObserver else { return }
    player.removeTimeObserver(timeObserver)
    self.timeObserver = nil
}

Use this CMTime extension to format your value to String properly.

extension CMTime {
    var roundedSeconds: TimeInterval {
        return seconds.rounded()
    }
    var hours:  Int { return Int(roundedSeconds / 3600) }
    var minute: Int { return Int(roundedSeconds.truncatingRemainder(dividingBy: 3600) / 60) }
    var second: Int { return Int(roundedSeconds.truncatingRemainder(dividingBy: 60)) }
    var positionalTime: String {
        return hours > 0 ?
            String(format: "%d:%02d:%02d",
                   hours, minute, second) :
            String(format: "%02d:%02d",
                   minute, second)
    }
}

Upvotes: 0

gregheo
gregheo

Reputation: 4270

You could set up a NSTimer to check the time periodically. You would need a method like:

- (void) checkPlaybackTime:(NSTimer *)theTimer
{
  float seconds = audioPlayer.currentTime;
  if (seconds => 10.5 && seconds < 11.5) {
    // do something
  } else if (seconds >= 22.5 && seconds < 23.5) {
    // do something else
  }
}

Then set up the NSTimer object to call this method every second (or whatever interval you like):

NSTimer *myTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 
  target:self
  selector:@selector(checkPlaybackTime:)
  userInfo:nil
  repeats:YES];

Check the NSTimer documentation for more details. You do need to stop (invalidate) the timer at the right time when you're through with it:

https://developer.apple.com/documentation/foundation/nstimer

EDIT: seconds will probably not be exactly 11 or 23; you'll have to fiddle with the granularity.

Upvotes: 8

Related Questions