Swift AVAudioPlayer doesn't play sound - ios

I want to play two sound files in my Swift app. "C1_bip.aif" and "false.aif".
They're both in the same folder in the project.
But when I start the app, the C1_bip sound is played and the false sound not and it prints Error to the Console.
The sound files are the same file type and I can play them both in the project explorer in Xcode.
if let path = NSBundle.mainBundle().pathForResource("C1_bip", ofType: "aif") {
audioPlayer = AVAudioPlayer(contentsOfURL: NSURL(fileURLWithPath: path),
fileTypeHint: "aif", error: nil)
if let sound = audioPlayer {
sound.prepareToPlay()
sound.play()
}
}
else {
println("Error")
}
if let path = NSBundle.mainBundle().pathForResource("false", ofType: "aif") {
audioPlayer = AVAudioPlayer(contentsOfURL: NSURL(fileURLWithPath: path),
fileTypeHint: "aif", error: nil)
if let sound = audioPlayer {
sound.prepareToPlay()
sound.play()
}
}
else {
println("Error")
}

Here is what I did in my test project:
let musicPath = NSBundle.mainBundle().pathForResource("bgmusic", ofType: "mp3")
let url = NSURL(fileURLWithPath: musicPath!)
do{
audioPlayer = try AVAudioPlayer(contentsOfURL: url)
}catch _ {
audioPlayer = nil
}
audioPlayer.numberOfLoops = -1
audioPlayer.prepareToPlay()
audioPlayer.play()
And it did work well:)

Related

How to add a delay to a sound being played with swift

I am a total swift beginner and am working on a tutorial project (magic 8 ball) and have been successful at doing the following:
- play a specific sound when the "Ask" button is pressed.
- play a specific sound when for each of the randomly picked images
However now the sound that should play whenever the button is pressed only plays once and from there on i only hear the sounds that are being displayed with each image. Is this because I am "stuck" in the "if - else" loop ? Or do I have to delay the sounds that are being played for each image in the array ?
Thanks so much for your help !
Here is my code:
import UIKit
import AVFoundation
class ViewController: UIViewController {
#IBOutlet weak var magicBall: UIImageView!
var magicBallDisplay = 1
var audioPlayer = AVAudioPlayer()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
magicBall.image = #imageLiteral(resourceName: "theanswerisyes")
}
#IBAction func askButtonPressed(_ sender: UIButton) {
let magicBallArray = [ #imageLiteral(resourceName: "askagainlater"),#imageLiteral(resourceName: "no"),#imageLiteral(resourceName: "theanswerisyes"),#imageLiteral(resourceName: "yes"),#imageLiteral(resourceName: "noidea")]
magicBall.image = magicBallArray.randomElement()
let soundURL = NSURL(fileURLWithPath: Bundle.main.path(forResource: "Ask", ofType: "wav")!)
do{
audioPlayer = try AVAudioPlayer(contentsOf: soundURL as URL)
}catch {
print("there was some error. The error was \(error)")
}
audioPlayer.play()
if (magicBall.image?.isEqual(UIImage(named: "yes")))! {
let soundURL = NSURL(fileURLWithPath: Bundle.main.path(forResource: "yes", ofType: "mp3")!)
do{
audioPlayer = try AVAudioPlayer(contentsOf: soundURL as URL)
} catch {
print("there was some error. The error was \(error)")
}
audioPlayer.play()
}
else if (magicBall.image?.isEqual(UIImage(named: "no")))! {
let soundURL = NSURL(fileURLWithPath: Bundle.main.path(forResource: "no", ofType: "mp3")!)
do{
audioPlayer = try AVAudioPlayer(contentsOf: soundURL as URL)
} catch {
print("there was some error. The error was \(error)")
}
audioPlayer.play()
}
else if (magicBall.image?.isEqual(UIImage(named: "theanswerisyes")))! {
let soundURL = NSURL(fileURLWithPath: Bundle.main.path(forResource: "theanswerisyes", ofType: "mp3")!)
do{
audioPlayer = try AVAudioPlayer(contentsOf: soundURL as URL)
} catch {
print("there was some error. The error was \(error)")
}
audioPlayer.play()
}
else if (magicBall.image?.isEqual(UIImage(named: "noidea")))! {
let soundURL = NSURL(fileURLWithPath: Bundle.main.path(forResource: "noidea", ofType: "mp3")!)
do{
audioPlayer = try AVAudioPlayer(contentsOf: soundURL as URL)
} catch {
print("there was some error. The error was \(error)")
}
audioPlayer.play()
}
else if (magicBall.image?.isEqual(UIImage(named: "askagainlater")))! {
let soundURL = NSURL(fileURLWithPath: Bundle.main.path(forResource: "askagainlater", ofType: "mp3")!)
do{
audioPlayer = try AVAudioPlayer(contentsOf: soundURL as URL)
} catch {
print("there was some error. The error was \(error)")
}
audioPlayer.play()
}
}
}
I make a new project and change your code to this:
import UIKit
import AVFoundation
class ViewController: UIViewController {
#IBOutlet weak var magicBall: UIImageView!
// you never used this
//var magicBallDisplay = 1
var audioPlayer = AVAudioPlayer()
override func viewDidLoad() {
super.viewDidLoad()
magicBall.image = #imageLiteral(resourceName: "theanswerisyes")
}
#IBAction func askButtonPressed(_ sender: UIButton) {
// because you have audio file and image with equal name i made array of string
let magicBallArray = [ "yes","no","theanswerisyes","noidea","askagainlater"]
// check if i get not null item
guard let choosedImageName = magicBallArray.randomElement() else {return}
print(choosedImageName)
// set image with random picked name
magicBall.image = UIImage(named: choosedImageName)
// play ask sound
playSound(fileName: "Ask", fileType: "wav")
// play picked image sound after 10 second from now()
// change number to your needed time
DispatchQueue.main.asyncAfter(deadline: .now() + 10.0, execute: {
self.playSound(fileName: choosedImageName, fileType: "mp3")
})
}
private func playSound(fileName: String, fileType: String)
{
// check if you find the audio file
guard let url = Bundle.main.path(forResource: fileName, ofType: fileType) else {
print("path not found")
return
}
// make NSURL from path
let soundURL = NSURL(fileURLWithPath: url)
do{
audioPlayer = try AVAudioPlayer(contentsOf: soundURL as URL)
} catch {
print("there was some error. The error was \(error)")
}
audioPlayer.play()
}
}
I explain code for you.
I didn't enable the button. you can improve this code when you came stronger in swift
your code is really messy.
at first, I advise you to make a function for playing sound like that:
func playSound(fileName: String, fileType: String) {
let soundURL = NSURL(fileURLWithPath: Bundle.main.path(forResource: fileName, ofType: fileType)!)
do{
audioPlayer = try AVAudioPlayer(contentsOf: soundURL as URL)
}catch {
print("there was some error. The error was \(error)")
}
audioPlayer.play()
}
you must have a callback for first play sound. after finishing the first sound you can check your if-else or you can try switch-case.
also, you can use delay for playing second sound

AVAudioPlayer can't play sound until using debug script

I'm using Xcode 7.3.1 with iOS 9 and having issue with playing sound by AVAudioPlayer. I've tried all possible solution out there and nothing works Here is my code
let mp3Url = NSBundle.mainBundle().URLForResource("BCA", withExtension:"mp3")!
var player = AVAudioPlayer()
do {
player = try AVAudioPlayer(contentsOfURL: mp3Url)
player.prepareToPlay()
player.play()
} catch let error as NSError {
print(error.description)
}
The sound won't play until I put a breakpoint at player.play() and using po player. Then the sound will be played.
Any idea will be helpful for me.
Try this :
var player: AVAudioPlayer?
func playSound(){
guard let url = Bundle.main.url(forResource: "alert_song", withExtension: "mp3") else {
print("MP3 resource not found.")
return
}
print("Music to play : \(String(describing: url))")
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
try AVAudioSession.sharedInstance().setActive(true)
player = try AVAudioPlayer(contentsOf: url)
guard let player = player else { return }
player.play()
} catch let error {
print(error.localizedDescription)
}
}
Try this :
var player = AVAudioPlayer() //global variables will otherwise be deadlock
let mp3Url = NSBundle.mainBundle().URLForResource("BCA", withExtension:"mp3")!
do {
player = try AVAudioPlayer(contentsOfURL: mp3Url)
player.play()
} catch let error as NSError {
print(error.description)
}

Play different audioplayers in sequence Swift

So basically I have two audio players while using the AVFoundation. I want the second one to be played right after the first one finishes.
myFilePathString = NSBundle.mainBundle().pathForResource("\(workout[currentExercise])", ofType: "mp3")
#IBAction func startWorkout(sender: AnyObject) {
if let myFilePathString = myFilePathString {
let myFilePathURL = NSURL(fileURLWithPath: myFilePathString)
do {
try audioPlayer = AVAudioPlayer(contentsOfURL: myFilePathURL)
audioPlayer.play()
}catch {
print("Error")
}
}
This above one is to be the first
let path = NSBundle.mainBundle().pathForResource("Rest", ofType: "mp3")
let url = NSURL(fileURLWithPath: path!)
do {
let sound = try AVAudioPlayer(contentsOfURL: url)
secondAudioPlayer = sound
sound.play()
} catch {
print("error")
}
...while this one is to be played after. At the moment they play at the same time. Got any ideas for me?
Thank you in advance.

AVAudioPlayer can't hear any sound using swift 2.1

i try to make iOS app to play some funny sound put when i click play no sound are out from speaker here is the code :
#IBAction func slow(sender: UIButton) {
if let filePath = NSBundle.mainBundle().URLForResource("io", withExtension: "mp3") {
let _a = try! AVAudioPlayer(contentsOfURL: filePath)
// Play
_a.play()
}else
{
print("error")
}
}
there is no error but i can't hear any sound at all
for how that face this problem
#IBAction func slow(sender: UIButton) {
if let path = NSBundle.mainBundle().pathForResource("io", ofType:"mp3") {
let fileURL = NSURL(fileURLWithPath: path)
player = try! AVAudioPlayer(contentsOfURL: fileURL)
player.prepareToPlay()
player.play()
}
else
{
print("error")
}
}
}

How do you add background music to SpriteKit?

I tried doing this:
let soundFilePath = NSBundle.mainBundle().pathForResource("GL006_SNES_Victory_loop.aif", ofType: "GL006_SNES_Victory_loop.aif")
let soundFileURL = NSURL(fileURLWithPath: soundFilePath!)
let player = AVAudioPlayer(contentsOfURL: soundFileURL, fileTypeHint: nil)
player.numberOfLoops = -1 //infinite
player.play()
I put this code in the didMoveToView function, and I have import AVFoundation at the top of my code. I get the error:
Call can throw, but it is not marked with 'try' and the error is not handled.
Thank you in advance!
(Xcode 8 and Swift 3)
Using SpriteKit this is pretty simple. You create an SKAudioNote with a sound file and then you attach it to your Scene as a child. It will loop by default:
override func didMove(to view: SKView) {
let backgroundSound = SKAudioNode(fileNamed: "bg.mp3")
self.addChild(backgroundSound)
}
If you want to stop the background music at some point you can use the build in methods:
backgroundSound.run(SKAction.stop())
Or maybe you want to play the sound again after stopping it:
backgroundSound.run(SKAction.play())
SpriteKit makes this really simple. I hope this helps you.
In Swift 2, the parameter of type NSErrorPointer is left out and can be caught within catch block as follows:
do
{
let player = try AVAudioPlayer(contentsOfURL: soundFileURL, fileTypeHint: nil)
}
catch let error as NSError
{
print(error.description)
}
Addendum:
It is better to declare your AVAudioPlayer as an ivar; otherwise, it could be released and thus the music won't play:
class yourViewController: UIViewController
{
var player : AVAudioPlayer!
....
So, given that, we make a minor change to the aforementioned try-catch:
do
{
player = try AVAudioPlayer(contentsOfURL: soundFileURL, fileTypeHint: nil)
}
catch let error as NSError
{
print(error.description)
}
Edit:
What you originally have:
let soundFilePath = NSBundle.mainBundle().pathForResource("GL006_SNES_Victory_loop.aif", ofType: "GL006_SNES_Victory_loop.aif")
let soundFileURL = NSURL(fileURLWithPath: soundFilePath!)
let player = AVAudioPlayer(contentsOfURL: soundFileURL, fileTypeHint: nil)
player.numberOfLoops = -1 //infinite
player.play()
Hereby adding the catch clause in Swift 2:
let soundFilePath = NSBundle.mainBundle().pathForResource("GL006_SNES_Victory_loop.aif", ofType: "GL006_SNES_Victory_loop.aif")
let soundFileURL = NSURL(fileURLWithPath: soundFilePath!)
do
{
player = try AVAudioPlayer(contentsOfURL: soundFileURL, fileTypeHint: nil)
}
catch let error as NSError
{
print(error.description)
}
player.numberOfLoops = -1 //infinite
player.play()
Assuming your class is a subclass of SKScene:
class yourGameScene: SKScene
{
//declare your AVAudioPlayer ivar
var player : AVAudioPlayer!
//Here is your didMoveToView function
override func didMoveToView(view: SKView)
{
let soundFilePath = NSBundle.mainBundle().pathForResource("GL006_SNES_Victory_loop.aif", ofType: "GL006_SNES_Victory_loop.aif")
let soundFileURL = NSURL(fileURLWithPath: soundFilePath!)
do
{
player = try AVAudioPlayer(contentsOfURL: soundFileURL, fileTypeHint: nil)
}
catch let error as NSError
{
print(error.description)
}
player.numberOfLoops = -1 //infinite
player.play()
//The rest of your other codes
}
}

Resources