Play Sound Using AVFoundation with Swift 2 - swift

I am trying to play a sound in my iOS app (written in Swift 2) using AVFoundation. I had it working with no issues with the previous version of Swift. I am using Xcode 7.0. I am not sure what the issue is and cannot find any additional info for Swift 2 regarding playing sounds. Here's my code for the sound part:
import AVFoundation
class ViewController: UIViewController {
var mySound = AVAudioPlayer()
override func viewDidLoad() {
super.viewDidLoad()
mySound = self.setupAudioPlayerWithFile("mySound", type:"wav")
mySound.play()
}
func setupAudioPlayerWithFile(file:NSString, type:NSString) -> AVAudioPlayer {
var path = NSBundle.mainBundle().pathForResource(file, ofType:type)
var url = NSURL.fileURLWithPath(path!)
var error: NSError?
var audioPlayer:AVAudioPlayer?
audioPlayer = AVAudioPlayer(contentsOfURL: url, error: &error)
return audioPlayer!
}
}
I am getting this error but have a feeling there maybe some other issue:
'NSString' is not implicitly convertible to 'String'; did you mean to use 'as' to explicitly convert?

Like Leo said
You need to implement do try catch error handling.
Here is another example of some code that will run sound when a button is pressed.
import UIKit
import AVFoundation
class ViewController: UIViewController {
#IBAction func play(sender: AnyObject) {
player.play()
}
#IBAction func pause(sender: AnyObject) {
player.pause()
}
var player: AVAudioPlayer = AVAudioPlayer()
override func viewDidLoad() {
super.viewDidLoad()
let audioPath = NSBundle.mainBundle().pathForResource("sound", ofType: "mp3")!
do {
try player = AVAudioPlayer(contentsOfURL: NSURL(fileURLWithPath: audioPath))
} catch {
// Process error here
}
}
}
I hope this helps!

You need to implement do try catch error handling. Try like this:
func setupAudioPlayerWithFile(file: String, type: String) -> AVAudioPlayer? {
if let url = NSBundle.mainBundle().URLForResource(file, withExtension: type) {
do {
return try AVAudioPlayer(contentsOfURL: url)
} catch let error as NSError {
print(error.localizedDescription)
}
}
return nil
}

Related

How to play a sound in Swift 5

I am new at swift and Xcode, and When I am trying to play a sound, it gives me an error that I have no idea what is wrong.
This is the code:
import UIKit
import AVFoundation
class ViewController: UIViewController {
var player: AVAudioPlayer?
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func buttonC(_sender: UIButton) {
playSound()
}
func playSound() {
guard let path = Bundle.main.path(forResource: "C", ofType:"wav") else {
return }
let url = URL(fileURLWithPath: path)
do {
player = try AVAudioPlayer(contentsOf: url)
player?.play()
} catch let error {
print(error.localizedDescription)
}
}
}
And this is the error:
I will appreciate the help; thanks!
Probably you have renamed your IBAction method name, now it's different and it's connected to the previous name inside your storyboard.
Disconnect your action method and reconnect it appropriately.
Go to your storyboard, select button and then in connectionInspector (cmd + option + 6) delete your previous connection.
Then link your button to the #IBAction function correctly.
I hope it helps you

Run multiple audio in sequence one by one in loop in swift

I want to run multiple audios in a loop. So I want to stop the execution of loop until the completion of running audio.
I have tried semaphores but no luck. Should I have to run it on main thread or what?
#IBAction func btnPlayAudiosClicked(_ sender: Any) {
for each in Constants.audioNames{
semaphore.wait()
txtStatus.text = "Playing audio " + each
AudioManager.shared.playSound(audioName: each)
semaphore.signal()
}
}
import AVFoundation
class YourClass: ..., AVAudioPlayerDelegate {
var player: AVAudioPlayer?
var yourURLStrings:[String] = []
override func viewDidLoad() {
self.playSound(position: 0)
}
func playSound(position: Int) {
let firstURL = yourURLStrings[position]
do {
try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default)
try AVAudioSession.sharedInstance().setActive(true)
/* The following line is required for the player to work on iOS 11. Change the file type accordingly*/
player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileType.mp3.rawValue)
/* iOS 10 and earlier require the following line:
player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileTypeMPEGLayer3) */
//Set delegate to self so we can execute delegate `AVAudioPlayerDelegate` functions
player.delegate = self
guard let player = player else { return }
player.play()
} catch let error {
print(error.localizedDescription)
}
}
func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
self.yourURLStrings.remove(at: 0)
if(yourURLStrings.count > 0) {
self.playSound(position: 0)
}
}
}

Swift AVAudioplayer on Button press

I am trying to have a button that will play a sound when pushed.
The app I have has 6 buttons (with 6 different sounds). I only have one listed because I am trying to get one button to work correctly before doing the rest. I know the button is working (from the print command at the bottom), but it is not playing the sound.
import UIKit
import AVFoundation
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
var player : AVAudioPlayer?
#IBAction func buttonOne(_ sender: Any) {
func playSound() {
let url = Bundle.main.url(forResource: "drinking", withExtension: "mp3")!
do {
player = try AVAudioPlayer(contentsOf: url)
guard let player = player else { return }
player.prepareToPlay()
player.play()
} catch let error as NSError {
print(error.description)
}
}
print("Anakin: IT IS WORKING!")
}
}
Is it printing any error?
Can you try doing this?
let path = Bundle.main.path(forResource: "FILE NAME WITH EXTENSION", ofType:nil)!
let url = URL(fileURLWithPath: path)
do {
let sound = try AVAudioPlayer(contentsOf: url)
sound.play()
} catch {
// couldn't load file :(
}

Trying to play a sound using AVFoundation

I am quite new to Xcode therefore apologies if the below requires a simple fix. Have created a simple button as a test for a different project, imported the mp3 file under the "Supporting Files" directory and the below is my code which is giving a number of errors due to tutorials I followed which were all using different versions of Xcode.
AVFoundation was also added to the project.
Errors:
Argument labels '(_:, error:)' do -- Extra argument 'error' in call
Use of unresolved identifier 'alertSound'
Code:
import UIKit
import AVFoundation
class ViewController: UIViewController {
var AudioPlayer = AVAudioPlayer()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let alertSound = NSURL(fileURLWithPath: Bundle.main.path(forResource: "two", ofType: "mp3")!)
print(alertSound)
AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, error: nil)
AVAudioSession.sharedInstance().setActive(true, error: nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func n2(_ sender: UIButton) {
var error:NSError?
AudioPlayer = AVAudioPlayer(contentsOfUrl: alertSound, error: &error)
AudioPlayer.prepareToPlay()
AudioPlayer.play()
}
}
For the first error:
Argument labels '(_:, error:)' do -- Extra argument 'error' in call
Objective C function which contains an error parameter and returns a boolean will be marked as a function which can potentially throw exceptions in Swift 3. You can handle the error using a do..try..catch construct.
You can check Apple Documentation on error handling here:
https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/ErrorHandling.html
The other error related to the AudioPlayer variable being a local variable which is being accessed outside of the scope.
var AudioPlayer = AVAudioPlayer()
// Declare alertSound at the instance level for use by other functions.
let alertSound = URL(fileURLWithPath: Bundle.main.path(forResource: "two", ofType: "mp3")!)
override func viewDidLoad() {
super.viewDidLoad()
print(alertSound)
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
try AVAudioSession.sharedInstance().setActive(true)
}
catch {
print("ERROR: \(error.localizedDescription)")
}
}
#IBAction func n2(_ sender: UIButton) {
do {
AudioPlayer = try AVAudioPlayer(contentsOf: alertSound)
AudioPlayer.prepareToPlay()
AudioPlayer.play()
}
catch {
print("ERROR: \(error.localizedDescription)")
}
}

Adding sound to an iOS app

I'm trying to add sound to an iOS app that I am writing. I keep getting the error message
"Incorrect argument label in call (have 'contentsOfURL:error:', expected "contentsOfURL:fileTypeHint:')".
I have tried tinkering with it in several ways, and I can't get it to build. Here is my code:
import UIKit import AVFoundation
class ViewController: UIViewController {
var Setup = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("DMSetup", ofType: "mp3")!)
var audioPlayer = AVAudioPlayer()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
audioPlayer = AVAudioPlayer(contentsOfURL: Setup, error: nil)
audioPlayer.prepareToPlay()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func PlayKeySetup(sender: UIButton) {
audioPlayer.play()
}
}
Any suggestions? I'm a newbie at this, so I'm sure I'm missing something obvious.
xCode 7.3.1, OSX 10.11.4
Thanks.
Try this code:
var audioPlayer: AVAudioPlayer!
let path = NSBundle.mainBundle().pathForResource("yourfilename", ofType: "format")
let CREATE_ANY_VARIABLE = NSURL(fileURLWithPath: path!)
do {
try audioPlayer = AVAudioPlayer(contentsOfURL: CREATE_ANY_VARIABLE)
} catch let error as NSError {
print(error.debugDescription)
}
audioPlayer.prepareToPlay()
and then you can play anywhere in the function!
the problem in your code is the name of your var Setup is overlapping with another Setup method form the AVFoundation
Usually using uppercase to the properties name it's considered as a bad attitude, you should use setup
Try this code:
let setupUrl = NSBundle.mainBundle().URLForResource("DMSetup", withExtension: "mp3")
if (setupUrl == nil) {
print("Could not find file: DMSetup.mp3")
return
}
do { audioPlayer = try AVAudioPlayer(contentsOfURL: Setup!, fileTypeHint: nil) }
catch let error as NSError { print(error.description) }
if let player = audioPlayer {
player.prepareToPlay()
}