I have had success playing sounds by pressing a button, by using the following code. However, I'd like to press a button and have that sound play in a loop/infinitely. How is this acheived? I'd also like to acheive pause/play functionality as well. Thanks in advance.
#IBAction func keyPressed(_ sender: UIB`utton) {
playSound(soundName: sender.currentTitle!)
}
func playSound(soundName: String) { //
let url = Bundle.main.url(forResource: soundName, withExtension: "wav")
player = try! AVAudioPlayer(contentsOf: url!)
player.play()
} // End of Play Sound
By default AVAudioPlayer plays its audio from start to finish then stops, but we can control how many times to make it loop by setting its numberOfLoops property. For example, to make your audio play three times in total, you’d write this:
player.numberOfLoops = 3
if you want the infinite loop then use
player.numberOfLoops = -1
for e.g
func playSound(soundName: String) { //
let url = Bundle.main.url(forResource: soundName, withExtension: "wav")
player = try! AVAudioPlayer(contentsOf: url!)
player.numberOfLoops = -1 // set your count here
player.play()
} // End of Play Sound
var audioPlayer: AVAudioPlayer?
func startBackgroundMusic() {
if let bundle = Bundle.main.path(forResource: "Guru_Nanak_Sahib_Ji", ofType: "mp3") {
let backgroundMusic = NSURL(fileURLWithPath: bundle)
do {
audioPlayer = try AVAudioPlayer(contentsOf:backgroundMusic as URL)
guard let audioPlayer = audioPlayer else { return }
audioPlayer.numberOfLoops = -1 // for infinite times
audioPlayer.prepareToPlay()
audioPlayer.play()
} catch {
print(error)
}
}
}
You can retain the player. Then in the player's completion delegate callback, start playing again. Or stop the player at any time, since you've retained a reference to it.
I am attempting to play a sound as an alert to the user of my app and I've looked at a few sources in trying to help me do this:
AVAudioPlayer not playing audio in Swift (to help me solve the problem I am running into now, to no avail)
Creating and playing a sound in swift (where I started originally)
And these videos:
https://www.youtube.com/watch?v=Kq7eVJ6RSp8
https://www.youtube.com/watch?v=RKfe7xzHEZk
All of which are not giving me the desired outcome (the sound doesn't play).
Here is my code:
private func playFinishedSound(){
if let pathResource = NSBundle.mainBundle().pathForResource("3000", ofType: "mp3"){
let finishedStepSound = NSURL(fileURLWithPath: pathResource)
var audioPlayer = AVAudioPlayer()
do {
audioPlayer = try AVAudioPlayer(contentsOfURL: finishedStepSound)
if(audioPlayer.prepareToPlay()){
print("preparation success")
audioPlayer.delegate = self
if(audioPlayer.play()){
print("Sound play success")
}else{
print("Sound file could not be played")
}
}else{
print("preparation failure")
}
}catch{
print("Sound file could not be found")
}
}else{
print("path not found")
}
}
Currently I see "preparation success" and "sound play success" but no sound is played. The class I am implementing this in is an AVAudioPlayerDelegate and the file is called "3000.mp3" which is within the project directory. In context the method is called here:
private func finishCell(cell: TimerTableViewCell, currentTimer: TimerObject){
currentTimer.isRunning = false
cell.label.text = "dismiss"
cell.backgroundColor = UIColor.lightMintColor()
if(!currentTimer.launchedNotification){
playFinishedSound()
}
currentTimer.launchedNotification = true
}
Any help would be appreciated.
UPDATE/SOLUTION:
So the problem was that audioPlayer would become deallocated before it would play the sound, to fix this I had to make it a property within the class instead of just creating an instance of it within the function. The updated code looks like this:
Optional reference within the property declarations of the class:
var audioPlayer : AVAudioPlayer?
The function that utilizes the audioPlayer:
private func playFinishedSound(){
if let pathResource = NSBundle.mainBundle().pathForResource("3000", ofType: "mp3"){
let finishedStepSound = NSURL(fileURLWithPath: pathResource)
audioPlayer = AVAudioPlayer()
do {
audioPlayer = try AVAudioPlayer(contentsOfURL: finishedStepSound)
if(audioPlayer!.prepareToPlay()){
print("preparation success")
audioPlayer!.delegate = self
if(audioPlayer!.play()){
print("Sound play success")
}else{
print("Sound file could not be played")
}
}else{
print("preparation failure")
}
}catch{
print("Sound file could not be found")
}
}else{
print("path not found")
}
}
I have a game which consists of 3 view controllers:
viewController
settingViewController
GameViewController
I have set the background music and played it in the viewController class
var backgroundMusic : AVAudioPlayer!
func setUpSounds(){
//button sound
if let buttonSoundPath = NSBundle.mainBundle().pathForResource("buttonClick", ofType: "mp3") {
let buttonSoundURL = NSURL(fileURLWithPath: buttonSoundPath)
do {
try buttonSound = AVAudioPlayer(contentsOfURL: buttonSoundURL)
}catch {
print("could not setup button sound")
}
buttonSound.volume = 0.5
}
//background sound
if let backgroundMusicPath = NSBundle.mainBundle().pathForResource("BackgroundMusic", ofType: "mp3") {
let backgroundMusicURL = NSURL(fileURLWithPath: backgroundMusicPath)
do {
try backgroundMusic = AVAudioPlayer(contentsOfURL: backgroundMusicURL)
}catch {
print("could not setup background music")
}
backgroundMusic.volume = 0.2
/*
set any negative integer value to loop the sound
indefinitely until you call the stop method
*/
backgroundMusic.numberOfLoops = -1
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.setUpSounds()
self.playBackgroundSound()
// Do any additional setup after loading the view, typically from a nib.
}
when I move to the settingViewController then back again to the viewController the sound replay and overlap the old played music.
What is the solution of this problem?
You have to check if the AVAudioPlayer is playing a music before call playBackgroundSound.
You can also put your SoundManager as a singleton, so you can manipulate it, from other parts of the app.
class SoundManager{
static var backgroundMusicSharedInstance = AVAudioPlayer?
}
In the View
func setUpSounds(){
//background sound
if SoundManager.backgroundMusicSharedInstance == nil {
if let backgroundMusicPath = NSBundle.mainBundle().pathForResource("BackgroundMusic", ofType: "mp3") {
let backgroundMusicURL = NSURL(fileURLWithPath: backgroundMusicPath)
do {
try SoundManager.backgroundMusicSharedInstance = AVAudioPlayer(contentsOfURL: backgroundMusicURL)
}catch {
print("could not setup background music")
}
SoundManager.backgroundMusicSharedInstance!.volume = 0.2
/*
set any negative integer value to loop the sound
indefinitely until you call the stop method
*/
SoundManager.backgroundMusicSharedInstance!.numberOfLoops = -1
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.setUpSounds()
if SoundManager.backgroundMusicSharedInstance!.playing == false{
self.playBackgroundSound()
}
}
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")
}
}
}
I have this code in a very simple, single view Swift application in my ViewController:
var audioPlayer = AVAudioPlayer()
#IBAction func playMyFile(sender: AnyObject) {
let fileString = NSBundle.mainBundle().pathForResource("audioFile", ofType: "m4a")
let url = NSURL(fileURLWithPath: fileString)
var error : NSError?
audioPlayer = AVAudioPlayer(contentsOfURL: url, error: &error)
audioPlayer.delegate = self
audioPlayer.prepareToPlay()
if (audioPlayer.isEqual(nil)) {
println("There was an error: (er)")
} else {
audioPlayer.play()
NSLog("working")
}
I have added import AVFoundation and audioPlayer is a global variable. When I execute the code, it does print "working", so it makes it through without errors but no sound is played. The device is not in silent.
There's so much wrong with your code that Socratic method breaks down; it will probably be easiest just to throw it out and show you:
var player : AVAudioPlayer! = nil // will be Optional, must supply initializer
#IBAction func playMyFile(sender: AnyObject?) {
let path = NSBundle.mainBundle().pathForResource("audioFile", ofType:"m4a")
let fileURL = NSURL(fileURLWithPath: path)
player = AVAudioPlayer(contentsOfURL: fileURL, error: nil)
player.prepareToPlay()
player.delegate = self
player.play()
}
I have not bothered to do any error checking, but the upside is you'll crash if there's a problem.
One final point, which may or may not be relevant: not every m4a file is playable. A highly compressed file, for example, can fail silently (pun intended).
Important that AvPlayer is class member and not in the given function, else it goes out of scope... :)
I had to declare a global player variable
var player: AVAudioPlayer!
and set it in viewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
player = AVAudioPlayer()
}
Then I could play the audio file wherever like this:
func playAudioFile(){
do {
if audioFileUrl == nil{
return
}
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: audioFileUrl, fileTypeHint: AVFileType.m4a.rawValue)
/* iOS 10 and earlier require the following line:
player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileTypeMPEGLayer3) */
guard let player = player else { return }
player.play()
print("PLAYING::::: \(audioFileUrl)")
}
catch let error {
print(error.localizedDescription)
}
}
}
Here is a working snippet from my swift project. Replace "audiofile" by your file name.
var audioPlayer = AVAudioPlayer()
let audioPath = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("audiofile", ofType: "mp3"))
audioPlayer = AVAudioPlayer(contentsOfURL: audioPath, error: nil)
audioPlayer.delegate = self
audioPlayer.prepareToPlay()
audioPlayer.play()
You can download fully functional Swift Audio Player application source code from here https://github.com/bpolat/Music-Player
for some reason (probably a bug) Xcode can't play certain music files in the .m4a and the .mp3 format I would recommend changing them all to .wav files to get it to play
//top of your class
var audioPlayer = AVAudioPlayer
//where you want to play your sound
let Sound = NSURL(fileURLWithPath: Bundle.main.path(forResource: "sound", ofType: "wav")!)
do {
audioPlayer = try AVAudioPlayer(contentsOf: Sound as URL)
audioPlayer.prepareToPlay()
} catch {
print("Problem in getting File")
}
audioPlayer.play()
var audioPlayer = AVAudioPlayer()
var alertSound = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("KiepRongBuon", ofType: "mp3")!)
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()
I used the below code in my app and it works. Hope that is helpful.
var audioPlayer: AVAudioPlayer!
if var filePath = NSBundle.mainBundle().pathForResource("audioFile", ofType:"mp3"){
var filePathUrl = NSURL.fileURLWithPath(filePath)
audioPlayer = AVAudioPlayer(contentsOfURL: filePathUrl, error: nil)
audioPlayer.play()
}else {
println("Path for audio file not found")
}
In Swift Coding using Try catch, this issues will solve and play audio for me and my code below,
var playerVal = AVAudioPlayer()
#IBAction func btnPlayAction(sender: AnyObject) {
let fileURL: NSURL = NSURL(string: url)!
let soundData = NSData(contentsOfURL: fileURL)
do {
playerVal = try AVAudioPlayer(data: soundData!)
}
catch {
print("Something bad happened. Try catching specific errors to narrow things down",error)
}
playerVal.delegate = self
playerVal.prepareToPlay()
playerVal.play()
}
Based on #matt answer but little bit detailed 'cause original answer did not completely satisfied me.
import AVFoundation
class YourController: UIViewController {
private var player : AVAudioPlayer?
override func viewDidLoad() {
super.viewDidLoad()
prepareAudioPlayer()
}
#IBAction func playAudio() {
player?.play()
}
}
extension YourController: AVAudioPlayerDelegate {}
private extension YourController {
func prepareAudioPlayer() {
guard let path = Bundle.main.path(forResource: "you-audio", ofType:"mp3") else {
return
}
let fileURL = URL(fileURLWithPath: path)
do {
player = try AVAudioPlayer(contentsOf: fileURL)
} catch let ex {
print(ex.localizedDescription)
}
player?.prepareToPlay()
player?.delegate = self
}
}
swift 3.0:
import UIKit
import AVFoundation
class ViewController: UIViewController
{
var audioplayer = AVAudioPlayer()
#IBAction func Play(_ sender: Any)
{
audioplayer.play()
}
#IBAction func Pause(_ sender: Any)
{
if audioplayer.isPlaying
{
audioplayer.pause()
}
else
{
}
}
#IBAction func Restart(_ sender: Any)
{
if audioplayer.isPlaying
{
audioplayer.currentTime = 0
audioplayer.play()
}
else
{
audioplayer.play()
}
}
override func viewDidLoad()
{
super.viewDidLoad()
do
{
audioplayer = try AVAudioPlayer(contentsOf:URL.init(fileURLWithPath:Bundle.main.path(forResource:"bahubali", ofType: "mp3")!))
audioplayer.prepareToPlay()
var audioSession = AVAudioSession.sharedInstance()
do
{
try audioSession.setCategory(AVAudioSessionCategoryPlayback)
}
catch
{
}
}
catch
{
print (error)
}
}
}