4

I saw a lot of tutorials but when i click button (that actvivate The func playsound) The sound doesn’t play. I saw the code reccomended by stackoverflow but nothing. I put The mp3 file info asset.xcasset. It’s right?

jscs
  • 63,694
  • 13
  • 151
  • 195
Angelo Volpe
  • 73
  • 1
  • 1
  • 3
  • You need to add your code of what you have tried so we can help you. Check the https://stackoverflow.com/help/how-to-ask – unniverzal Dec 03 '17 at 15:04
  • Possible duplicate of [Play specific sound when specific button is pressed in iOS](https://stackoverflow.com/questions/43960065/play-specific-sound-when-specific-button-is-pressed-in-ios) – Fattie Jan 15 '18 at 18:01
  • easy, https://stackoverflow.com/a/43963507/294884 – Fattie Jan 15 '18 at 18:01

6 Answers6

13

SWIFT 4 / XCODE 9.1

import AVFoundation

var objPlayer: AVAudioPlayer?

func playAudioFile() {
    guard let url = Bundle.main.url(forResource: "soundName", withExtension: "mp3") else { return }

    do {
        try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
        try AVAudioSession.sharedInstance().setActive(true)

        // For iOS 11 
        objPlayer = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileType.mp3.rawValue)

        // For iOS versions < 11 
        objPlayer = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileTypeMPEGLayer3) 

        guard let aPlayer = objPlayer else { return }
        aPlayer.play()

    } catch let error {
        print(error.localizedDescription)
    }
}
Arpit Jain
  • 1,660
  • 12
  • 23
  • This works great. In case your simulator doesn't play the sound, do the following: On your Mac, go to System Preferences > Sound > Sound Effects and then uncheck and recheck "Play user interface sound effects". Borrowed from: https://stackoverflow.com/questions/302399/sound-not-working-in-iphone-simulator – PanHrabia Jul 05 '18 at 23:17
7

SWIFT 4.2 / XCODE 10.1

Note that you must call AVAudioSession.sharedInstance().setCategory() with the mode parameter in Swift 4.2.

import AVFoundation

var audioPlayer: AVAudioPlayer?

func playSound() {
    if let audioPlayer = audioPlayer, audioPlayer.isPlaying { audioPlayer.stop() }

    guard let soundURL = Bundle.main.url(forResource: "audio_file", withExtension: "wav") else { return }

    do {
        try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback, mode: AVAudioSession.Mode.default)
        try AVAudioSession.sharedInstance().setActive(true)
        audioPlayer = try AVAudioPlayer(contentsOf: soundURL)
        audioPlayer?.play()
    } catch let error {
        Print.detailed(error.localizedDescription)
    }
}
Robert Nelson
  • 91
  • 1
  • 3
3

A very simple solution.

import AVFoundation

var myAudioPlayer = AVAudioPlayer?

func playAudioFile() {

    let audioFileURL = Bundle.main.url(forResource: "<name-of-file>", withExtension: "mp3/wav/m4a etc.")

    do {
        try myAudioPlayer = AVAudioPlayer(contentsOf: audioFileURL!)
    } catch let error {
        print(error.localizedDescription)
    }

    myAudioPlayer?.play()

}

Now, play this audio file anywhere by calling: playAudioFile()

ok_ape
  • 79
  • 6
0

Add your .mp3 file to Bundle

import AVFoundation

let url = Bundle.main.url(forResource: "SampleAudio", withExtension: "mp3")

    let playerItem = AVPlayerItem(url: url!)
    let player=AVPlayer(playerItem: playerItem)
    let playerLayer=AVPlayerLayer(player: player)

    playerLayer.frame = CGRect(x: 0, y: 0, width: 0, height: 0)
    self.view.layer.addSublayer(playerLayer)
    player.play()
Suresh Vutukuru
  • 211
  • 2
  • 8
  • Where is bundle? – Angelo Volpe Dec 03 '17 at 17:22
  • 1
    You have to pass `mp3` as the `type` and `SampleAudio` as `resource`. But why don't you suggest the proper API `let url = Bundle.main.url(forResource: "SampleAudio", withExtension: "mp3")!` and remove the extra line to create the URL? – vadian Dec 03 '17 at 17:31
  • And why create separate optional variables for `player` and `playerItem`? Declare and initialize the variables one line and avoid the need for the explicit data type. And please do proper handling of optionals. The use of `!` for `path` is fine. But the others are bad. – rmaddy Dec 03 '17 at 23:07
  • @AngeloVolpe To add .mp3 file to Bundle. Click on "+" at bottom left corner of your Project Navigator, then select "File" – Suresh Vutukuru Dec 04 '17 at 05:26
  • @vadian Thanks for your suggestions. I have made my changes. Please check – Suresh Vutukuru Dec 04 '17 at 05:27
  • @rmaddy Thanks for your suggestions. I have made my changes. Please check – Suresh Vutukuru Dec 04 '17 at 05:28
0

You can also put a timer to show the progress of the music played

import AVFoundation

class ViewController: UIViewController {
var player : AVAudioPlayer?
var timer : Timer?
@IBOutlet var pauseBtn: UIButton!
@IBOutlet var replayBtn: UIButton!
@IBAction func rewind2(_ sender: Any) {

}
@IBAction func forward(_ sender: Any) {
    var time : TimeInterval = (player?.currentTime)!
    time += 5.0
    if (time > (player?.duration)!)
    {
        // stop, track skip or whatever you want
    }
    else
    {
        player?.currentTime = time
    }
}
@IBOutlet var progress: UIProgressView!
@IBAction func playClicked(_ sender: Any) {
    if player == nil {
        let resource = Bundle.main.url(forResource: "audioFX", withExtension: "mp3")
        do {
            player = try AVAudioPlayer(contentsOf: resource!)
            player?.isMeteringEnabled = true
            player?.prepareToPlay()
        } catch let error {
            print(error)

        }
    }
    if player != nil {
        player?.play()
        enableTimer()
        player!.delegate = self as? AVAudioPlayerDelegate
    }
}
@IBAction func pauseClicked(_ sender: Any) {
    if(player != nil){
        if(player?.isPlaying == true){
            endTimer()
            player!.pause()
            pauseBtn.setTitle("Resume", for: .normal)
        }else{
            player!.play()
            enableTimer()
            pauseBtn.setTitle("Stop", for: .normal)
        }

    }
}
@IBAction func replayClicked(_ sender: Any) {
    if player != nil{
        endTimer()
        player = nil
        pauseBtn.setTitle("Stop", for: .normal)
        playClicked(replayBtn)
    }
}

override func viewDidLoad() {
    super.viewDidLoad()


}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}
func enableTimer(){
    if(player != nil){
        timer = Timer(timeInterval: 0.1, target: self, selector: (#selector(self.updateProgress)), userInfo: nil, repeats: true)
        RunLoop.main.add(timer!, forMode: RunLoopMode(rawValue: "NSDefaultRunLoopMode"))
    }
}
func endTimer(){
    if(timer != nil){
        timer!.invalidate()
    }
}

@objc func updateProgress(){
    if(player != nil){
        player!.updateMeters() //refresh state
        progress.progress = Float(player!.currentTime/player!.duration)
    }
}

}

steffi pravasi
  • 101
  • 1
  • 6
0

Simple way with Swift 4.2:

import AVFoundation

and

   let soundEffect = URL(fileURLWithPath: Bundle.main.path(forResource: "btn_click_sound", ofType: "mp3")!)
   var audioPlayer = AVAudioPlayer()

   @IBAction func buttonClick(sender: AnyObject) {
       do {
            audioPlayer = try AVAudioPlayer(contentsOf: soundEffect)
            audioPlayer.play()
       } catch {
          // couldn't load file :(
       } 
   }
Sunil Targe
  • 7,251
  • 5
  • 49
  • 80