Home > Net >  How to play several sound in a row
How to play several sound in a row

Time:01-25

The goal is to play several sounds one after another (getReady -> nextExercise -> burpees). The problem is that only the first one is being played

How it should work:

  1. I call playGetReady() from WorkoutTabataViewController
  2. I plays the first sound
  3. After the first sound is finished, automatically "audioPlayerDidFinishPlaying()" is being called
  4. It triggers "playNextSound()" func, which playing next sound

But audioPlayerDidFinishPlaying() is not being called. Or am I missing something and it should work differently?

class AudioPlayerManager: AVAudioPlayerDelegate {
    var description: String
    
    static let shared = AudioPlayerManager()
    var audioPlayer: AVAudioPlayer?
    var workoutVC: WorkoutTabataViewController?
    var mainVC: MainTabataViewController?
    
    var currentSound = 0
    let urls: [URL]
    
    init() {
        self.description = ""
        //First sound
        let getReady = Bundle.main.path(forResource: "Get ready", ofType: "mp3")!
        let urlGetReady = URL(fileURLWithPath: getReady)
        
        //Second sound
        let nextExercise = Bundle.main.path(forResource: "Next Exercise", ofType: "mp3")!
        let urlNextExercise = URL(fileURLWithPath: nextExercise)
        
        //Third sound
        let burpees = Bundle.main.path(forResource: "Burpees", ofType: "mp3")!
        let urlBurpees = URL(fileURLWithPath: burpees)
        
        urls = [urlGetReady, urlNextExercise, urlBurpees]
    }
    
    func playGetReady() {

        do {
            audioPlayer = try AVAudioPlayer(contentsOf: urls[currentSound])
            audioPlayer?.delegate = self
            audioPlayer?.play()
        } catch {
            print(error)
        }
    }
    
    func playNextSound() {
        currentSound  = 1

        if currentSound < urls.count {
            do {
                audioPlayer = try AVAudioPlayer(contentsOf: urls[currentSound])
                audioPlayer?.delegate = self
                audioPlayer?.play()
            } catch {
                print(error)
            }
        }
    }
    
    func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
 
        if flag {
            playNextSound()
        }
    }
}

CodePudding user response:

Your audio manager class is not introspectable. Say @objc func audioPlayerDidFinishPlaying or, better, make it an NSObject.

  • Related