iOS AVAudioPlayer - how to set file path to the pathForResource - ios

i want to play small mp3 file when button is clicked. but not sure how to set the mp3 file in setPathForResources
Here My Code
import UIKit
import AVFoundation
class PlaySoundsViewController: UIViewController {
var coinSound = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("/sounds/superman", ofType: "mp3")!)
var audioPlayer = AVAudioPlayer()
#IBOutlet weak var PlaySlow: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func PlaySlowAction(sender: UIButton) {
audioPlayer.play()
}
I have added the sounds folder to the project using just drag and drop. but when i click button im getting this error.
audioPlayer.play() Thread 1: EXC_BAD_ACCESS(Code=1,address=0x1c)

You don't need the sounds/ in your path. Just the filename. e.g.
var coinSound = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("superman", ofType: "mp3")!)
Also fileURLWithPath takes a URL, not a string. You need to convert your NSBundle.mainBundle().pathForResource("superman", ofType: "mp3") to a string first using NSURL(string:).
This is the full setup:
let path = NSBundle.mainBundle().pathForResource("superman", ofType:"mp3")
let fileURL = NSURL(fileURLWithPath: path)
player = AVAudioPlayer(contentsOfURL: fileURL, error: nil)
player.prepareToPlay()
player.delegate = self
player.play()

You missed a couple necessary steps in your "PlaySlowAction" method:
#IBAction func PlaySlowAction(sender: UIButton) {
// if the audioPlayer hasn't been set to any sound file yet,
// load it up...
if(audioPlayer.data == nil)
{
var error:NSError?
audioPlayer = AVAudioPlayer(contentsOfURL: coinSound, error: &error)
if let actualError = error {
println("An Error Occurred: \(actualError)")
}
}
audioPlayer.prepareToPlay()
audioPlayer.play()
}

Related

fatal error: unexpectedly found nil while unwrapping an Optional value on adding audio Swift

I'm trying to add some audio when a button is pressed and the code I use doesnt have any error until I run then I get the 'fatal error: unexpectedly found nil while unwrapping an Optional value' in the out put this line of code:
let url = Bundle.main.url(forResource:sound, withExtension: "mp3")!
This is my entire code just for reference:
import UIKit
import AVFoundation
class ViewController: UIViewController {
let soundFilenames = ["60gs", "check", "dada", "danceforme", "eat", "gods", "irelandbaby", "ko'd", "lefthand", "littlewerp", "nocalls", "precision", "sundaymorning", "surprise", "whothefuckisthatguy", "youlldonothing"]
var audioPlayers = [AVAudioPlayer]()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
for sound in soundFilenames {
do {
let url = Bundle.main.url(forResource:sound, withExtension: "mp3")!
let audioPlayer = try AVAudioPlayer(contentsOf: url)
audioPlayers.append(audioPlayer)
}
catch {
audioPlayers.append(AVAudioPlayer())
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func buttonTapped(_ sender: UIButton) {
let audioPlayer = audioPlayers[sender.tag]
audioPlayer.play()
}
}
Error is self-describing: url(forResource: withExtension:) returned nil and force-unwrapping it with ! causes your crash.
To fix this crash re-check that:
all files were added to the project
file names are written right in the code
If the file names are not needed later there is a more reliable way to get all mp3 files in the resources folder
let audioURLs = Bundle.main.urls(forResourcesWithExtension: "mp3", subdirectory: nil)!
for url in audioURLs {
do {
let audioPlayer = try AVAudioPlayer(contentsOf: url)
audioPlayers.append(audioPlayer)
}
catch {
audioPlayers.append(AVAudioPlayer())
}
}
or - inspired by Alexander's comment – shortly
let audioURLs = Bundle.main.urls(forResourcesWithExtension: "mp3", subdirectory: nil)!
audioPlayers = audioURLs.flatMap{ try? AVAudioPlayer(contentsOf: $0) }

Play multiple songs in iOS

I wrote this code for iOS to play a song, however I'm not sure how to write the code to play multiple songs.
This is the line of code for a song:
import UIKit
import AVFoundation
class ViewController: UIViewController {
var player:AVAudioPlayer = AVAudioPlayer()
#IBAction func play(_ sender: AnyObject)
{
player.play()
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
do
{
let audioPath = Bundle.main.path(forResource: "Ken", ofType: "mp3")
try player = AVAudioPlayer(contentsOf: NSURL(fileURLWithPath: audioPath!) as URL)
}
catch
{
//ERROR
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
You actually can play it with just two instances of the AVAudioPlayer resp. every sound file needs it's own AVAudioPlayer if you want to play them simultaneously.
I already wrote an answer, so I will post even there is already a correct answer. What palme said is correct. You could use multiple AVAudioPlayer instances to play multiple sounds simultaneously:
import UIKit
import AVFoundation
class ViewController: UIViewController {
let paths = ["a","b"]
var sounds = [AVAudioPlayer]()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
for path in paths {
do
{
let audioPath = Bundle.main.path(forResource: path, ofType: "mp3")
let player = try AVAudioPlayer(contentsOf: NSURL(fileURLWithPath: audioPath!) as URL)
sounds.append(player)
}
catch
{
//ERROR
}
}
for sound in sounds {
sound.play()
}
}
}

Swift 3 - AVAudioPlayer is not playing sound

I have a simple program which has one button and its only function is to trigger an sound output.
The app works perfectly when tested on an iOS simulator, but when I test it on an iPhone, the app is not playing any sound. I have tested this on two iPhones.
This was working once upon a time. I don't know if updating to iOS 10 has caused the issue.
Here is my code:
//Code
import UIKit
import AVFoundation
var audioPlayer = AVAudioPlayer()
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let music = Bundle.main.path(forResource: "sound", ofType: "wav")
do {
audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: music! ))
}
catch{
print(error)
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func playSound(_ sender: UIButton) {
audioPlayer.play()
}
}
Would be grateful for any answers.
Thanks.
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let music = Bundle.main.path(forResource: "sound", ofType: "wav")
do {
audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: music! ))
audioPlayer.delegate = self
audioPlayer.preparedToPlay()
}
catch{
print(error)
}
}
import UIKit
import AVFoundation
class ViewController: UIViewController {
var btnSound: AVAudioPlayer!
override func viewDidLoad() {
super.viewDidLoad()
//locate resource
let path = Bundle.main.path(forResource: "sound", ofType: "wav")
let music = URL(fileURLWithPath: path!)
do{
try btnSound = AVAudioPlayer(contentsOf: music)
btnSound.prepareToPlay()
} catch let err as NSError{
print(err.debugDescription)
}
}
}
func playSound(){
if btnSound.isPlaying{
//stop playing sound file if already playing
btnSound.stop()
}
//play sound
btnSound.play()
}
#IBAction func playSound(sender: UIButton){
//call playSound function on pressing the button you attach this function to
playSound()
}

iOS programming noob, need help fixing error message

I've recently gotten into iOS development on my own and am building my first app: a Donald Trump soundboard. However, I got an error saying:
Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
This is the viewcontroller text:
import UIKit
import iAd
import AVFoundation
class SecondViewController: UIViewController {
// Array of every sound file
let soundFilenames = ["china", "drugs_killers_rapists", "america_great_again", "are_you_gay", "Mexico", "i_just_want_them_to_suffer", "are_you_homosexual", "are_you_surprised", "hes_a_loser", "isis_trump", "fantastic", "the_american_dream_is_dead", "wait_dummies", "special_guy", "I'm_really_rich", "speak_english", "so_probably_i'll_sue_her", "ladies", "ill_build_a_wall", "political_bullshit", "ima_bomb_em", "back_to_univision", "hes_a_pussy", "piece_of_garbage", "i_love_mexicans", "i_love_china", "i_love_saudis", "sit_down", "small_loan", "youre_fired", "lets_see_what_happens", "enough", "congratulations", "why", "are_you_anti_semite", "youre_the_boss", "1mm", "tell_it_like_it_is", "100b", "is_that_right", "hes_insecure", "beaten_up", "I_beat_China_all_the_time", "nonono", "ive_been_watching_you", "motivate_you", "okay_okay", "meatloaf"]
// Array of AudioPlayers for each file
var audioPlayers = [AVAudioPlayer]()
// Outlet for the ScrollView
#IBOutlet weak var ScrollView: UIScrollView!
var bannerView: ADBannerView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
// Set up scroll view to hold 48 buttons
ScrollView.contentSize.height = 1900
//Set up audio players
for sound in soundFilenames {
do {
// Try to do something
//THIS NEXT LINE IS WHERE THE BREAKPOINT
let url = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource(sound, ofType: "mp3")!)
let audioPlayer = try AVAudioPlayer(contentsOfURL: url)
audioPlayers.append(audioPlayer)
}
catch {
// Catch the error that is thrown
audioPlayers.append(AVAudioPlayer())
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func buttonTapped(sender: UIButton) {
// Get the audioPlayer that corresponds to the tapped button
let audioPlayer = audioPlayers[sender.tag]
audioPlayer.play()
}
}
Any help will be extremely appreciated.
Edit: fatal error shown at the bottom states:
unexpectedly found nil while unwrapping an Optional value
//Set up audio players
for sound in soundFilenames {
do {
// Try to do something
if let pathOfResource = NSBundle.mainBundle().pathForResource(sound, ofType: "mp3") {
let url = NSURL(fileURLWithPath: pathOfResource)
let audioPlayer = try AVAudioPlayer(contentsOfURL: url)
audioPlayers.append(audioPlayer)
}
}
catch {
// Catch the error that is thrown
audioPlayers.append(AVAudioPlayer())
}
}
Try this updated code.

Playing a sound with AVAudioPlayer

I'm trying to play a sound with AVAudioPlayer but it won't work.
Edit 1: Still doesn't work.
Edit 2: This code works. My device was in silent mode.
import UIKit
import AVFoundation
class ViewController: UIViewController {
var audioPlayer = AVAudioPlayer()
override func viewDidLoad() {
super.viewDidLoad()
var alertSound = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("button-09", ofType: "wav"))
println(alertSound)
var error:NSError?
audioPlayer = AVAudioPlayer(contentsOfURL: alertSound, error: &error)
audioPlayer.prepareToPlay()
audioPlayer.play()
}
}
Made modification to your code:
import UIKit
import AVFoundation
class ViewController: UIViewController {
var audioPlayer = AVAudioPlayer()
override func viewDidLoad() {
super.viewDidLoad()
var alertSound = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("button-09", ofType: "wav"))
println(alertSound)
// Removed deprecated use of AVAudioSessionDelegate protocol
AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, error: nil)
AVAudioSession.sharedInstance().setActive(true, error: nil)
var error:NSError?
audioPlayer = AVAudioPlayer(contentsOfURL: alertSound, error: &error)
audioPlayer.prepareToPlay()
audioPlayer.play()
}
}
Swift 3 and Swift 4.1:
import UIKit
import AVFoundation
class ViewController: UIViewController {
private var audioPlayer: AVAudioPlayer?
override func viewDidLoad() {
super.viewDidLoad()
let alertSound = URL(fileURLWithPath: Bundle.main.path(forResource: "button-09", ofType: "wav")!)
print(alertSound)
try! AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
try! AVAudioSession.sharedInstance().setActive(true)
try! audioPlayer = AVAudioPlayer(contentsOf: alertSound)
audioPlayer!.prepareToPlay()
audioPlayer!.play()
}
}
As per Swift 2 the code should be
var audioPlayer : AVAudioPlayer!
func playSound(soundName: String)
{
let coinSound = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource(soundName, ofType: "m4a")!)
do{
audioPlayer = try AVAudioPlayer(contentsOfURL:coinSound)
audioPlayer.prepareToPlay()//there is also an async version
audioPlayer.play()
}catch {
print("Error getting the audio file")
}
}
Your audio play will be deallocated right after viewDidLoad finishes since you assign it to a local variable. You need to create a property for it to keep it around.
The solution is for AudioPlayer which has play/pause/stop button in the navigation bar as bar button items
In Swift 2.1 you can use the below code
import UIKit
import AVFoundation
class ViewController: UIViewController {
var player:AVAudioPlayer = AVAudioPlayer()
override func viewDidLoad() {
super.viewDidLoad()
let audioPath = NSBundle.mainBundle().pathForResource("ARRehman", ofType: "mp3")
var error:NSError? = nil
do {
player = try AVAudioPlayer(contentsOfURL: NSURL(fileURLWithPath: audioPath!))
}
catch {
print("Something bad happened. Try catching specific errors to narrow things down")
}
}
#IBAction func play(sender: UIBarButtonItem) {
player.play()
}
#IBAction func stop(sender: UIBarButtonItem) {
player.stop()
print(player.currentTime)
player.currentTime = 0
}
#IBAction func pause(sender: UIBarButtonItem) {
player.pause()
}
#IBOutlet weak var sliderval: UISlider!
#IBAction func slidermov(sender: UISlider) {
player.volume = sliderval.value
print(player.volume)
}
}
This will work.....
import UIKit
import AVFoundation
class ViewController: UIViewController {
var ding:AVAudioPlayer = AVAudioPlayer()
override func viewDidLoad() {
super.viewDidLoad()
prepareAudios()
ding.play()
}
func prepareAudios() {
var path = NSBundle.mainBundle().pathForResource("ding", ofType: "mp3")
ding = AVAudioPlayer(contentsOfURL: NSURL(fileURLWithPath: path!), error: nil)
ding.prepareToPlay()
}
}
Use This Function to make sound in Swift (You can use this function where you want to make sound.)
First Add SpriteKit and AVFoundation Framework.
import SpriteKit
import AVFoundation
func playEffectSound(filename: String){
runAction(SKAction.playSoundFileNamed("\(filename)", waitForCompletion: false))
}// use this function to play sound
playEffectSound("Sound File Name With Extension")
// Example :- playEffectSound("BS_SpiderWeb_CollectEgg_SFX.mp3")
This is a pretty old question, but I did not see an answer that worked with Swift 3.0 so I modernized the code and added some safety checks to prevent crashes.
I also took the approach of pulling the playing part out into its own function to help with re-use for anyone coming across this answer.
import UIKit
import AVFoundation
class ViewController: UIViewController {
var audioPlayer: AVAudioPlayer?
override func viewDidLoad() {
super.viewDidLoad()
play(for: "button-09", type: "wav")
}
func play(for resource: String, type: String) {
// Prevent a crash in the event that the resource or type is invalid
guard let path = Bundle.main.path(forResource: resource, ofType: type) else { return }
// Convert path to URL for audio player
let sound = URL(fileURLWithPath: path)
do {
audioPlayer = try AVAudioPlayer(contentsOf: sound)
audioPlayer?.prepareToPlay()
audioPlayer?.play()
} catch {
// Create an assertion crash in the event that the app fails to play the sound
assert(false, error.localizedDescription)
}
}
}
Swift 4.2 onwards, AudioSession category setup options have been changed. (Try following code for Swift 4.2 onwards)
import UIKit
import AVFoundation
class ViewController: UIViewController {
var audioPlayer: AVAudioPlayer?
override func viewDidLoad() {
super.viewDidLoad()
prepareAudioSession()
}
func prepareAudioSession() -> Void {
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback, mode: AVAudioSession.Mode.default, options: AVAudioSession.CategoryOptions.defaultToSpeaker)
try AVAudioSession.sharedInstance().setActive(true)
prepareAudioPlayer()
} catch {
print("Issue with Audio Session")
}
}
func prepareAudioPlayer() -> Void {
let audioFileName = "test"
let audioFileExtension = "mp3"
guard let filePath = Bundle.main.path(forResource: audioFileName, ofType: audioFileExtension) else {
print("Audio file not found at specified path")
return
}
let alertSound = URL(fileURLWithPath: filePath)
try? audioPlayer = AVAudioPlayer(contentsOf: alertSound)
audioPlayer?.prepareToPlay()
}
func playAudioPlayer() -> Void {
audioPlayer?.play()
}
func pauseAudioPlayer() -> Void {
if audioPlayer?.isPlaying ?? false {
audioPlayer?.pause()
}
}
func stopAudioPlayer() -> Void {
if audioPlayer?.isPlaying ?? false {
audioPlayer?.stop()
}
}
func resetAudioPlayer() -> Void {
stopAudioPlayer()
audioPlayer?.currentTime = 0
playAudioPlayer()
}
}

Resources