I would like to play a sound using Swift.
My code worked in Swift 1.0 but now it doesn't work anymore in Swift 2 or newer.
override func viewDidLoad() {
super.viewDidLoad()
let url:NSURL = NSBundle.mainBundle().URLForResource("soundName", withExtension: "mp3")!
do {
player = try AVAudioPlayer(contentsOfURL: url, fileTypeHint: nil)
} catch _{
return
}
bgMusic.numberOfLoops = 1
bgMusic.prepareToPlay()
if (Data.backgroundMenuPlayed == 0){
player.play()
Data.backgroundMenuPlayed = 1
}
}
This question is related to
ios
swift
avfoundation
Tested with Swift 4 and iOS 12:
import UIKit
import AVFoundation
class ViewController: UIViewController{
var player: AVAudioPlayer!
override func viewDidLoad() {
super.viewDidLoad()
}
func playTone(number: Int) {
let path = Bundle.main.path(forResource: "note\(number)", ofType : "wav")!
let url = URL(fileURLWithPath : path)
do {
player = try AVAudioPlayer(contentsOf: url)
print ("note\(number)")
player.play()
}
catch {
print (error)
}
}
@IBAction func notePressed(_ sender: UIButton) {
playTone(number: sender.tag)
}
}
import AVFoundation
var player:AVAudioPlayer!
func Play(){
guard let path = Bundle.main.path(forResource: "KurdishSong", ofType: "mp3")else{return}
let soundURl = URL(fileURLWithPath: path)
player = try? AVAudioPlayer(contentsOf: soundURl)
player.prepareToPlay()
player.play()
//player.pause()
//player.stop()
}
var player: AVAudioPlayer?
let path = Bundle.main.path(forResource: "note\(sender.tag)", ofType: "wav")
let url = URL(fileURLWithPath: path ?? "")
do {
player = try AVAudioPlayer(contentsOf: url)
player?.play()
} catch let error {
print(error.localizedDescription)
}
for Swift 5 "AVFoundation"
Simple code without error handling to play audio from your local path
import AVFoundation
var audio:AVPlayer!
func stopAlarm() {
// To pause or stop audio in swift 5 audio.stop() isn't working
audio.pause()
}
func playAlarm() {
// need to declear local path as url
let url = Bundle.main.url(forResource: "Alarm", withExtension: "mp3")
// now use decleared path 'url' to initialize the player
audio = AVPlayer.init(url: url!)
// after initialization play audio its just like click on play button
audio.play()
}
import UIKit
import AVFoundation
class ViewController: UIViewController{
var player: AVAudioPlayer?
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func notePressed(_ sender: UIButton) {
guard let url = Bundle.main.url(forResource: "note1", withExtension: "wav") else { return }
do {
try AVAudioSession.sharedInstance().setCategory((AVAudioSession.Category.playback), mode: .default, options: [])
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.wav.rawValue)
/* iOS 10 and earlier require the following line:
player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileTypeMPEGLayer3) *//
guard let player = player else { return }
player.play()
} catch let error {
print(error.localizedDescription)
}
}
}
If code doesn't generate any error, but you don't hear sound - create the player as an instance:
static var player: AVAudioPlayer!
For me the first solution worked when I did this change :)
First import these libraries
import AVFoundation
import AudioToolbox
set delegate like this
AVAudioPlayerDelegate
write this pretty code on button action or something action:
guard let url = Bundle.main.url(forResource: "ring", withExtension: "mp3") else { return }
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
try AVAudioSession.sharedInstance().setActive(true)
player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileType.mp3.rawValue)
guard let player = player else { return }
player.play()
}catch let error{
print(error.localizedDescription)
}
100% working in my project and tested
import AVFoundation
import AudioToolbox
public final class MP3Player : NSObject {
// Singleton class
static let shared:MP3Player = MP3Player()
private var player: AVAudioPlayer? = nil
// Play only mp3 which are stored in the local
public func playLocalFile(name:String) {
guard let url = Bundle.main.url(forResource: name, withExtension: "mp3") else { return }
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback)
try AVAudioSession.sharedInstance().setActive(true)
player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileType.mp3.rawValue)
guard let player = player else { return }
player.play()
}catch let error{
print(error.localizedDescription)
}
}
}
To call this function
MP3Player.shared.playLocalFile(name: "JungleBook")
For Swift 3 :
import AVFoundation
/// **must** define instance variable outside, because .play() will deallocate AVAudioPlayer
/// immediately and you won't hear a thing
var player: AVAudioPlayer?
func playSound() {
guard let url = Bundle.main.url(forResource: "soundName", withExtension: "mp3") else {
print("url not found")
return
}
do {
/// this codes for making this app ready to takeover the device audio
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
try AVAudioSession.sharedInstance().setActive(true)
/// change fileTypeHint according to the type of your audio file (you can omit this)
player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileTypeMPEGLayer3)
// no need for prepareToPlay because prepareToPlay is happen automatically when calling play()
player!.play()
} catch let error as NSError {
print("error: \(error.localizedDescription)")
}
}
The best practice for local assets is to put it inside assets.xcassets
and you load the file like this :
func playSound() {
guard let url = Bundle.main.url(forResource: "soundName", withExtension: "mp3") else {
print("url not found")
return
}
do {
/// this codes for making this app ready to takeover the device audio
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
try AVAudioSession.sharedInstance().setActive(true)
/// change fileTypeHint according to the type of your audio file (you can omit this)
/// for iOS 11 onward, use :
player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileType.mp3.rawValue)
/// else :
/// player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileTypeMPEGLayer3)
// no need for prepareToPlay because prepareToPlay is happen automatically when calling play()
player!.play()
} catch let error as NSError {
print("error: \(error.localizedDescription)")
}
}
iOS 12 - Xcode 10 beta 6 - Swift 4.2
Use just 1 IBAction and point all the buttons to that 1 action.
import AVFoundation
var player = AVAudioPlayer()
@IBAction func notePressed(_ sender: UIButton) {
print(sender.tag) // testing button pressed tag
let path = Bundle.main.path(forResource: "note\(sender.tag)", ofType : "wav")!
let url = URL(fileURLWithPath : path)
do {
player = try AVAudioPlayer(contentsOf: url)
player.play()
} catch {
print ("There is an issue with this code!")
}
}
Swift 3
import AVFoundation
var myAudio: AVAudioPlayer!
let path = Bundle.main.path(forResource: "example", ofType: "mp3")!
let url = URL(fileURLWithPath: path)
do {
let sound = try AVAudioPlayer(contentsOf: url)
myAudio = sound
sound.play()
} catch {
//
}
//If you want to stop the sound, you should use its stop()method.if you try to stop a sound that doesn't exist your app will crash, so it's best to check that it exists.
if myAudio != nil {
myAudio.stop()
myAudio = nil
}
file Sfx.swift
import AVFoundation
public let sfx = Sfx.shared
public final class Sfx: NSObject {
static let shared = Sfx()
var apCheer: AVAudioPlayer? = nil
private override init() {
guard let s = Bundle.main.path(forResource: "cheer", ofType: "mp3") else {
return print("Sfx woe")
}
do {
apComment = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: s))
} catch {
return print("Sfx woe")
}
}
func cheer() { apCheer?.play() }
func plonk() { apPlonk?.play() }
func crack() { apCrack?.play() } .. etc
}
Anywhere at all in code
sfx.explosion()
sfx.cheer()
Swift 4, 4.2 and 5
Play audio from URL and from your project (Local File)
import UIKit
import AVFoundation
class ViewController: UIViewController{
var audioPlayer : AVPlayer!
override func viewDidLoad() {
super.viewDidLoad()
// call what ever function you want.
}
private func playAudioFromURL() {
guard let url = URL(string: "https://geekanddummy.com/wp-content/uploads/2014/01/coin-spin-light.mp3") else {
print("error to get the mp3 file")
return
}
do {
audioPlayer = try AVPlayer(url: url as URL)
} catch {
print("audio file error")
}
audioPlayer?.play()
}
private func playAudioFromProject() {
guard let url = Bundle.main.url(forResource: "azanMakkah2016", withExtension: "mp3") else {
print("error to get the mp3 file")
return
}
do {
audioPlayer = try AVPlayer(url: url)
} catch {
print("audio file error")
}
audioPlayer?.play()
}
}
var soundEffect = AVAudioPlayer()
func playSound(_ buttonTag : Int){
let path = Bundle.main.path(forResource: "note\(buttonTag)", ofType : "wav")!
let url = URL(fileURLWithPath : path)
do{
soundEffect = try AVAudioPlayer(contentsOf: url)
soundEffect?.play()
// to stop the spound .stop()
}catch{
print ("file could not be loaded or other error!")
}
}
works in swift 4 latest version. ButtonTag would be a tag on a button on your interface. Notes are in a folder in a folder parallel to Main.storyboard. Every note is named as note1, note2, etc. ButtonTag is giving the number 1, 2, etc from the button clicked which is passed as param
This is basic code to find and play an audio file in Swift.
Add your audio file to your Xcode and add the code below.
import AVFoundation
class ViewController: UIViewController {
var audioPlayer = AVAudioPlayer() // declare globally
override func viewDidLoad() {
super.viewDidLoad()
guard let sound = Bundle.main.path(forResource: "audiofilename", ofType: "mp3") else {
print("Error getting the mp3 file from the main bundle.")
return
}
do {
audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: sound))
} catch {
print("Audio file error.")
}
audioPlayer.play()
}
@IBAction func notePressed(_ sender: UIButton) { // Button action
audioPlayer.stop()
}
}
Source: Stackoverflow.com