web-dev-qa-db-fra.com

Comment jouer un son avec Swift?

Je voudrais jouer un son en utilisant Swift.

Mon code fonctionnait dans Swift 1.0 mais maintenant, il ne fonctionne plus dans Swift 2 ou plus récent.

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
    }
}
83
Michel

De préférence, vous pouvez utiliser AVFoundation . Il fournit tous les éléments essentiels au travail avec les médias audiovisuels.

Mise à jour: Compatible avec Swift 2, Swift 3 et Swift 4 comme suggéré par certains d'entre vous dans les commentaires.


Swift 2.3

import AVFoundation

var player: AVAudioPlayer?

func playSound() {
    let url = NSBundle.mainBundle().URLForResource("soundName", withExtension: "mp3")!

    do {
        player = try AVAudioPlayer(contentsOfURL: url)
        guard let player = player else { return }

        player.prepareToPlay()
        player.play()

    } catch let error as NSError {
        print(error.description)
    }
}

Swift 3

import AVFoundation

var player: AVAudioPlayer?

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

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

        let player = try AVAudioPlayer(contentsOf: url)

        player.play()

    } catch let error {
        print(error.localizedDescription)
    }
}

Swift 4 (compatible iOS 12)

import AVFoundation

var player: AVAudioPlayer?

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

    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) */

        guard let player = player else { return }

        player.play()

    } catch let error {
        print(error.localizedDescription)
    }
}

Assurez-vous de changer le nom de votre morceau ainsi que le extension .Le fichier doit être correctement importé (Project Build Phases> Copy Bundle Resources). Vous voudrez peut-être le placer dans assets.xcassets pour plus de commodité.

Pour les fichiers sonores courts, vous pouvez choisir des formats audio non compressés tels que .wav, car ils offrent la meilleure qualité et un faible impact sur le processeur. L'augmentation de la consommation d'espace disque ne devrait pas être un gros problème pour les fichiers sonores courts. Plus les fichiers sont longs, vous pouvez choisir un format compressé tel que .mp3, etc. pp. Vérifiez les formats audio compatibles de CoreAudio.


Fun-fact: Il existe de petites bibliothèques bien conçues qui facilitent la lecture des sons. :) 
Par exemple: SwiftySound

175
Devapploper

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

La meilleure pratique pour les actifs locaux est de le placer dans assets.xcassets et vous chargez le fichier comme suit:

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)")
    }
}
37
Adi Nugroho

iOS 12 - Xcode 10 beta 6 - Swift 4.2

Utilisez seulement 1 IBAction et pointez tous les boutons sur cette 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!")

        }

}
11
Tony Ward

Si le code ne génère aucune erreur, mais que vous n'entendez pas de son, créez le lecteur comme instance:

   static var player: AVAudioPlayer!

Pour moi la première solution a fonctionné quand j'ai fait ce changement :)

4
EranKT

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
}
3
Mr.Shin

Swift 4 (compatible iOS 12)

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

très simple Code to Swift

ajoutez votre fichier audio à votre Xcode et donnez le code tel que donné

import AVFoundation

class ViewController: UIViewController{

   var audioPlayer = AVAudioPlayer() //declare as Globally

   override func viewDidLoad() {
        super.viewDidLoad()

        guard let sound = Bundle.main.path(forResource: "audiofilename", ofType: "mp3") else {
            print("error to get the mp3 file")
            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()
}
1
M VIJAY

Testé avec Swift 4 et 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)
    }
}
1
Ershin Bot

Swift 4, 4.2 et 5

Lecture audio de l'URL et de votre projet (fichier local)

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

}
0
Akbar Khan

Importez d'abord ces bibliothèques

import AVFoundation

import AudioToolbox    

définir délégué comme ça 

   AVAudioPlayerDelegate

écrivez ce joli code sur l'action du bouton ou quelque chose:

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% travaillant dans mon projet et testé

0
Mr.Javed Multani
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!")
    }
}

fonctionne dans Swift 4 dernière version. ButtonTag serait une balise sur un bouton de votre interface. Les notes se trouvent dans un dossier situé dans un dossier parallèle à Main.storyboard. Chaque note est nommée note1, note2, etc. ButtonTag donne le nombre 1, 2, etc.

0
Egi Messito
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)
        }

    }

}
0
Hunter Akers