Execution breakpoint when trying to play a music library file with AVAudioEngine

Hi all,

I'm working on an audio visualizer app that plays files from the user's music library utilizing MediaPlayer and AVAudioEngine. I'm working on getting the music library functionality working before the visualizer aspect.

After setting up the engine for file playback, my app inexplicably crashes with an EXC_BREAKPOINT with code = 1. Usually this means I'm unwrapping a nil value, but I think I'm handling the optionals correctly with guard statements. I'm not able to pinpoint where it's crashing. I think it's either in the play function or the setupAudioEngine function. I removed the processAudioBuffer function and my code still crashes the same way, so it's not that. The device that I'm testing this on is running iOS 26 beta 3, although my app is designed for iOS 18 and above.

After commenting out code, it seems that the app crashes at the scheduleFile call in the play function, but I'm not fully sure.

Here is the setupAudioEngine function:

 private func setupAudioEngine() {
    do {
      try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default)
      try AVAudioSession.sharedInstance().setActive(true)
    } catch {
      print("Audio session error: \(error)")
    }
    
    engine.attach(playerNode)
    engine.attach(analyzer)
    
    engine.connect(playerNode, to: analyzer, format: nil)
    engine.connect(analyzer, to: engine.mainMixerNode, format: nil)
    
    analyzer.installTap(onBus: 0, bufferSize: 1024, format: nil) { [weak self] buffer, _ in
      self?.processAudioBuffer(buffer)
    }
  }

Here is the play function:

  func play(_ mediaItem: MPMediaItem) {
    guard let assetURL = mediaItem.assetURL else {
      print("No asset URL for media item")
      return
    }
    
    stop()
    
    do {
      audioFile = try AVAudioFile(forReading: assetURL)
      guard let audioFile else {
        print("Failed to create audio file")
        return
      }
      
      duration = Double(audioFile.length) / audioFile.fileFormat.sampleRate
      
      if !engine.isRunning {
        try engine.start()
      }
      

      playerNode.scheduleFile(audioFile, at: nil)
      
      playerNode.play()

      DispatchQueue.main.async { [weak self] in
        self?.isPlaying = true
        self?.startDisplayLink()
      }
    } catch {
      print("Error playing audio: \(error)")
      DispatchQueue.main.async { [weak self] in
        self?.isPlaying = false
        self?.stopDisplayLink()
      }
    }
  }

Here is a link to my test project if you want to try it out for yourself: https://github.com/aabagdi/VisualMan-example

Thanks!

Answered by Vendetagainst in 849603022

I accidentally selected this reply as an accepted answer, is it possible to undo this action?

I've made a small breakthrough, the code crashes because of the installTap call, but the bad news is that I'm unable to figure out why. Any ideas?

Accepted Answer

I accidentally selected this reply as an accepted answer, is it possible to undo this action?

Execution breakpoint when trying to play a music library file with AVAudioEngine
 
 
Q