Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AVAudioPlayer not playing audio in Swift

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.

like image 330
Kenneth Avatar asked Jul 16 '14 23:07

Kenneth


4 Answers

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)
       }
}

}

like image 97
fullmoon Avatar answered Oct 13 '22 00:10

fullmoon


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).

like image 39
matt Avatar answered Nov 17 '22 17:11

matt


Important that AvPlayer is class member and not in the given function, else it goes out of scope... :)

like image 13
iHolm Avatar answered Nov 17 '22 18:11

iHolm


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

like image 6
bpolat Avatar answered Nov 17 '22 18:11

bpolat