Search code examples
iosavfoundationswiftuiavaudioplayerswift5

How to play audio using AVAudioPlayer in SwiftUI project


Audio is not playing using this approach. The play() function is executing without any error. Please help

var audioPlayer = AVAudioPlayer()
let path = Bundle.main.path(forResource: "a", ofType: "mp3")
@State var isPlaying : Bool = false

var body: some View {
    Button(action: {
         self.isPlaying.toggle()    
         let url = URL(fileURLWithPath: self.path!)
         do {
             self.audioPlayer = try AVAudioPlayer(contentsOf: url)
             self.audioPlayer.prepareToPlay()
             self.audioPlayer.play()
         }catch {
             print("Eror")
         }        
      }, label: {
           if isPlaying {
                    Image(systemName: "pause")
                    .font(Font.system(.largeTitle).bold())
           }else {
                Image(systemName: "play.fill")
                 .font(Font.system(.largeTitle).bold())
           }
    })
}

Solution

  • Is the audiofile there? Please select the project, go to Build Phases tab and under 'Copy Bundle Resources' you must see the audio file. If it is there then the problem is this.

    I tried your code, it played the sound and then crashed. i changed it like this to make it work

     @State var audioPlayer:AVAudioPlayer?
    
     @State var isPlaying : Bool = false
    
     var body: some View {
    
         Button(action: {
    
             if let path = Bundle.main.path(forResource: "a", ofType: ".mp3") {
    
                 self.audioPlayer = AVAudioPlayer()
    
                 self.isPlaying.toggle()
    
                 let url = URL(fileURLWithPath: path)
    
                 do {
                     self.audioPlayer = try AVAudioPlayer(contentsOf: url)
                     self.audioPlayer?.prepareToPlay()
                     self.audioPlayer?.play()
                 }catch {
                     print("Error")
                 }
             }
    
         }, label: {
    

    ----

    Have you considered separating your Audio model from your UI? It would make your code much clearer if you put it into separate Swift file

    import AVFoundation
    
     class Sounds {
    
       static var audioPlayer:AVAudioPlayer?
    
       static func playSounds(soundfile: String) {
    
           if let path = Bundle.main.path(forResource: soundfile, ofType: nil){
    
               do{
    
                   audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: path))
                   audioPlayer?.prepareToPlay()
                   audioPlayer?.play()
    
               }catch {
                   print("Error")
               }
           }
        }
     }
    

    And just one line to use it in UI

    var body: some View {
        Button(action: {
            self.isPlaying.toggle()
            Sounds.playSounds(soundfile: "0.wav")
    
        }, label: {