【问题标题】:How to play a sound using Swift?如何使用 Swift 播放声音?
【发布时间】:2015-11-09 05:59:12
【问题描述】:

我想使用 Swift 播放声音。

我的代码在 Swift 1.0 中工作,但现在它在 Swift 2 或更高版本中不再工作。

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

【问题讨论】:

标签: ios swift avfoundation


【解决方案1】:

最好使用AVFoundation。 它提供了使用视听媒体的所有必需品。

更新: 兼容 Swift 2Swift 3Swift 4,正如你们在厘米。


斯威夫特 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)
    }
}

斯威夫特 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(兼容 iOS 13)

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

确保更改您的曲调名称以及extension 需要正确导入文件 (Project Build Phases > Copy Bundle Resources)。你可能想把它放在assets.xcassets 更方便。

对于短声音文件,您可能希望使用非压缩音频格式,例如 .wav,因为它们具有最佳质量和低 CPU 影响。对于较短的声音文件,较高的磁盘空间消耗应该不是什么大问题。文件越长,您可能想要使用压缩格式,例如.mp3 等。pp。检查CoreAudiocompatible audio formats


有趣的事实:有一些简洁的小库可以让播放声音变得更加容易。 :)
例如:SwiftySound

【讨论】:

  • 抱歉,这段代码在 swift 2.0 中不再起作用,它提示错误“调用可以抛出,但它没有标有 'try' 并且错误未处理”
  • do { bgMusic = try AVAudioPlayer(contentsOfURL: bgMusicURL, fileTypeHint: nil) } catch _ { return \\ if it doesn't exist, don't play it}替换bgMusic = AVAudioPlayer(contentsOfURL: bgMusicURL, fileTypeHint: nil)
  • 我必须将 AVAudioPlayer 对象设为实例变量才能使其正常工作。作为局部变量,它不会播放任何东西,没有错误。代表也不会被召唤。
  • 你为什么在这里使用警卫? player = try AVAudioPlayer(contentsOf: url) guard let player = player else { return } 对我来说似乎是额外的工作,为什么不只是 let player = try AVAudioPlayer(contentsOf: url)
  • 使用保护语句可以让你避免因 nil 值而崩溃。
【解决方案2】:

对于 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)")
    }
}

本地资产的最佳做法是将其放在assets.xcassets 中,然后像这样加载文件:

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 10.2.1、xCode 8.2.1 上。对我来说,这两条“尝试 AVAudioSession”行会影响在真实设备上实际听到的声音与否。没有它们,就没有声音。
  • 这对我帮助很大,但我在理解 do 块中发生的事情时遇到了一些麻烦。显然player!.play() 是不言自明的。但是setCategorysetActive 方法的目的是什么?
  • 如果您将AVAudioSessionCategoryPlayback 提供给setCategory,它将确保即使手机处于锁定屏幕或静音模式也始终播放音频。 setActive 就像告诉系统您的应用已准备好播放音频
  • @AdiNugroho 你觉得你能帮我解决我的问题吗:stackoverflow.com/questions/44201592/… ?
  • 我在 iOS 11 上遇到了很多麻烦。它曾经可以工作,但现在突然不行了。有什么想法吗?
【解决方案3】:

iOS 12 - Xcode 10 beta 6 - Swift 4.2

仅使用 1 个 IBAction 并将所有按钮指向该 1 个操作。

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

【讨论】:

  • 有趣的是,您假设每个人都在观看“iOS 11 & Swift 4 - The Complete iOS App Development Bootcamp”??
【解决方案4】:

如果代码没有产生任何错误,但您没有听到声音 - 将播放器创建为实例:

   static var player: AVAudioPlayer!

对我来说,当我进行此更改时,第一个解决方案有效:)

【讨论】:

  • 为我工作。有谁知道你为什么要把它设置为静态?
  • 我不认为它必须是静态的(不再是?),但似乎如果你在它创建后让它超出范围,即使你调用了 play(),它不会玩?我只是把它作为我的类的一个实例变量,它就可以工作了。
  • @kuzdu 这是因为您没有将player 放在外部范围内。否则,player 会离域,因此无法播放任何声音,因为它不再存在。
  • 为我工作 - 没有 static
  • 也为我工作!谢谢!
【解决方案5】:

Swift 4、4.2 和 5

从 URL 和您的项目(本地文件)播放音频

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

}

【讨论】:

    【解决方案6】:

    Swift 版本:5.4 及以上

    import AVFoundation
    var player: AVAudioPlayer?
    
    func playSound() {
        guard let path = Bundle.main.path(forResource: "beep", ofType:"mp3") else {
            return }
        let url = URL(fileURLWithPath: path)
    
        do {
            player = try AVAudioPlayer(contentsOf: url)
            player?.play()
            
        } catch let error {
            print(error.localizedDescription)
        }
    }
    

    【讨论】:

      【解决方案7】:

      斯威夫特 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
      }
      

      【讨论】:

        【解决方案8】:

        对于 Swift 5AVFoundation”\

        从本地路径播放音频的简单代码,没有错误处理

        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 declare local path as url
            let url = Bundle.main.url(forResource: "Alarm", withExtension: "mp3")
            // now use declared path 'url' to initialize the player
            audio = AVPlayer.init(url: url!)
            // after initialization play audio its just like click on play button
            audio.play()
        }
        

        【讨论】:

          【解决方案9】:

          使用 Swift 4 和 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)
              }
          }
          

          【讨论】:

            【解决方案10】:

            游戏风格:

            文件 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 {
                        apCheer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: s))
                    } catch {
                        return  print("Sfx woe")
                    }
                }
                
                func cheer() { apCheer?.play() }
                func plonk() { apPlonk?.play() }
                func crack() { apCrack?.play() } .. etc
            }
            

            代码中的任何地方

            sfx.cheer()
            sfx.crack()
            

            【讨论】:

              【解决方案11】:

              首先导入这些库

              import AVFoundation
              
              import AudioToolbox    
              

              这样设置委托

                 AVAudioPlayerDelegate
              

              在按钮动作或其他动作上编写这段漂亮的代码:

              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% 在我的项目中工作并经过测试

              【讨论】:

              • 这里不需要导入AudioToolbox
              【解决方案12】:
              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)
                      }
              
                  }
              
              }
              

              【讨论】:

                【解决方案13】:

                Swift 4(兼容 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)
                }
                

                【讨论】:

                • 我收到以下错误:The operation couldn’t be completed. (OSStatus error 1954115647.)。我到处寻找,找不到解决方案。可能会发布一个关于它的问题。
                【解决方案14】:

                这是在 Swift 中查找和播放音频文件的基本代码。

                将您的音频文件添加到您的 Xcode 并添加以下代码。

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

                【讨论】:

                  【解决方案15】:
                  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()
                  }
                  

                  【讨论】:

                    【解决方案16】:

                    这很简单,可以完成工作!

                    import AVFoundation
                    var player: AVAudioPlayer!
                                
                        let url = Bundle.main.url(forResource: "sound_name", withExtension: "mp3")
                         
                        player = try! AVAudioPlayer(contentsOf: url!)
                        player.play()
                    

                    【讨论】:

                      【解决方案17】:
                      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!")
                          }
                      }
                      

                      适用于 swift 4 最新版本。 ButtonTag 将是界面上按钮上的标签。笔记位于与 Main.storyboard 平行的文件夹中。每个音符都被命名为 note1、note2 等。ButtonTag 给出了作为参数传递的单击按钮的数字 1、2 等

                      【讨论】:

                        【解决方案18】:
                        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)
                                }
                            }
                        }
                        

                        调用这个函数

                        MP3Player.shared.playLocalFile(name: "JungleBook")
                        

                        【讨论】:

                          猜你喜欢
                          • 2014-12-22
                          • 2017-03-28
                          • 1970-01-01
                          • 1970-01-01
                          • 2015-12-25
                          • 2014-06-05
                          • 1970-01-01
                          • 1970-01-01
                          • 2014-12-26
                          相关资源
                          最近更新 更多