peridotite
peridotite

Reputation: 125

SwiftUI: In a function, I'd like to instantiate AVAudioPlayer and play it

If a button is tapped, I'd like it to play sound.

In "playSound" function below I'd like to instantiate AVAudioPlayer and play the sound but Xcode outputted Exception caught in AudioQueueInternalNotifyRunning - error -66671 error and cannot play the sound. A hoge.mp3 is already imported.

If I instantiate AVAudioPlayer out of the function, it successes but I would like to instantiate it in the function.

Do you have any solution?

Thank you.

func playSound(title:String){
        let tmpSound = try! AVAudioPlayer(data:NSDataAsset(name:title)!.data)
        tmpSound.play()
    }

Button(action: {
 playSound(soundName: "hoge")
 }){
 Text("Play".font(.title)
 }

Upvotes: 0

Views: 737

Answers (1)

you could try something like this, works for me:

import Foundation
import AVFoundation
import SwiftUI

struct ContentView: View {
    @State var audioPlayer: AVAudioPlayer?
    
    var body: some View {
        Button(action: {
            playSound(title: "hoge")
        }) {
            Text("Play").font(.title)
        }
    }
    
    func playSound(title: String) {
        if let url = Bundle.main.url(forResource: title, withExtension: "mp3") {
            do {
                audioPlayer = try AVAudioPlayer(contentsOf: url)
                audioPlayer?.play()
            } catch {
                print("Error")
            }
        }
    }
      
}

EDIT-1: you can also do this if your mp3 files are in the Assets directory:

func playSound(title: String) {
    if let audio = NSDataAsset(name: title) {
        do {
            audioPlayer = try AVAudioPlayer(data: audio.data)
            audioPlayer?.play()
        } catch {
            print("--> error: \(error)")
        }
    }
}

Upvotes: 3

Related Questions