I am making a soundboard with Swift. It works great but I am trying to impement a check whether AVAudioPlayer instance is playing, and if yes to stop it. The sounds are listed on a tableview which gets the data from an array in which I store my Sound class (which has 2 variables, title and url of sound).
I have my AVAudioPlayer and AVAudioSession as well as my sounds array on my ViewController Class:
var session = AVAudioSession.sharedInstance()
var audioPlayer = AVAudioPlayer()
var sounds: [Sound] = []
and I implement the audio playing when the app user selects a row like that:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
if audioPlayer.playing {
audioPlayer.stop()
} else {
var sound = self.sounds[indexPath.row]
var baseString : String = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)[0] as String
var pathComponents = [baseString, sound.url]
var audioNSURL = NSURL.fileURLWithPathComponents(pathComponents)
self.audioPlayer = AVAudioPlayer(contentsOfURL: audioNSURL, error: nil)
self.audioPlayer.play()
}
tableView.deselectRowAtIndexPath(indexPath, animated: true)
}
But when I tap the row the app is crashing and all I am getting is "(lldb)"
Do you have any idea what is happening? Or am I doing this completely wrong?
Thank you in advance
I figured it out, so I share with the community:
I also had to declare the sound NSURL property on my ViewController Class:
var session = AVAudioSession.sharedInstance()
var audioPlayer = AVAudioPlayer()
var audioNSURL = NSURL()
and also to prepare my audioPlayer on the ViewDidLoad function: (I had to use a sample sound in order to initialize the AVAudioPlayer)
let samplePath = NSBundle.mainBundle().pathForResource("sample", ofType: "mp4")
audioNSURL = NSURL.fileURLWithPath(samplePath!)!
audioPlayer = AVAudioPlayer(contentsOfURL: audioNSURL, error: nil)
audioPlayer.prepareToPlay()
then, on the didSelectRowAtIndexPath method, I check whether the AVAudioPlayer instance is playing and also if it's playing the sound reflected by the cell that was tapped. If yes, stop the audioPlayer, if not then play the other sound (the audioPlayer stops and plays the other sound)
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
var sound = self.sounds[indexPath.row]
var baseString : String = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)[0] as String
var pathComponents = [baseString, sound.url]
var rowSoundURL = NSURL.fileURLWithPathComponents(pathComponents)!
if audioPlayer.playing && rowSoundURL == audioNSURL {
audioPlayer.stop()
} else {
audioNSURL = rowSoundURL
self.audioPlayer = AVAudioPlayer(contentsOfURL: audioNSURL, error: nil)
self.audioPlayer.play()
}
tableView.deselectRowAtIndexPath(indexPath, animated: true)
}
Be aware, that, if you also record sounds on your app, you have to set the session category as AVAUdioSessionCategoryPlayback or the sound will be heard through the small speaker of the device. So, in viewWillAppear function:
session.setCategory(AVAudioSessionCategoryPlayback, error: nil)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With