简体   繁体   中英

AVAudioengine play / loop audio , multiple buttons

I have this button to play and loop a wav. But what if I have a second button with another loop? I want this second loop to start playing once pressed, however, the first loop must finish his 'round'. And vice versa (play and loop the second loop, press button first loop and it takes over)

 @IBAction func playButtonTapped(_ sender: Any) {



    guard let filePath: String = Bundle.main.path(forResource: "25loop110", ofType: "wav") else{ return }
          print("\(filePath)")
          let fileURL: URL = URL(fileURLWithPath: filePath)
          guard




              let audioFile = try? AVAudioFile(forReading: fileURL) else{ return }

          let audioFormat = audioFile.processingFormat
          let audioFrameCount = UInt32(audioFile.length)
          guard let audioFileBuffer = AVAudioPCMBuffer(pcmFormat: audioFormat, frameCapacity: audioFrameCount)  else{ return }
          do{
              try audioFile.read(into: audioFileBuffer)

              timeShift.rate = adjustedBpm/bpm
              playerNode.scheduleFile(audioFile, at: nil, completionHandler: nil)


          } catch{
              print("over")
          }

          try? audioEngine.start()
          playerNode.play()
          playerNode.scheduleBuffer(audioFileBuffer, at: nil, options:.loops,completionHandler: nil)

    }

You can handle this behavior by using the completionHandler parameter of .scheduleBuffer .

For example, you could do something like this:

var nextAudioFilePath: String  
var isPlaying: Bool = false

@IBAction func playLoopA() {  
   guard let path = Bundle.main.path(forResource: "audioFileA", ofType: "wav") else { return }  
   nextAudioFilePath = path  
   guard !isPlaying else { return }  
   play()
}  

@IBAction func playLoopB() {  
   guard let path = Bundle.main.path(forResource: "audioFileB", ofType: "wav") else { return }  
   nextAudioFilePath = path  
   guard !isPlaying else { return }  
   play()
}  

private func play() {  
   let fileURL = URL(fileURLWithPath: nextAudioFilePath)  
   ...  
   playerNode.scheduleBuffer(audioFileBuffer, at: nil, options: [], completionHandler: { [weak self] in   
      self?.play()
   })
}  

我也找到了这个解决方案:

playerNode.scheduleBuffer(audioFileBuffer, at: nil, options:[.interruptsAtLoop, .loops],completionHandler: nil)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM