【问题标题】:Creating and playing a sound in swift快速创建和播放声音
【发布时间】:2014-07-25 11:38:38
【问题描述】:

所以我想做的是在 swift 中创建并播放一个声音,当我按下一个按钮时就会播放,我知道如何在 Objective-C 中做到这一点,但是有人知道如何在 Swift 中做到这一点吗?

Objective-C 应该是这样的:

NSURL *soundURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"mysoundname" ofType:@"wav"]];
AudioServicesCreateSystemSoundID((__bridge CFURLRef)soundURL, &mySound);

然后我会玩它:

AudioServicesPlaySystemSound(Explosion);

有人知道我该怎么做吗?

【问题讨论】:

  • 这个问题的根源是如何从swift调用C函数。我也很好奇这个。
  • 这一行可以创建声音的url:var url :NSURL = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("mysoundname", ofType: "wav"))
  • @connor 谢谢它的工作,但 AudioServicesCreateSystemSoundID 呢
  • 我不确定。我只能从swift调用objective-c api。

标签: ios objective-c audio swift


【解决方案1】:

这与其他一些答案类似,但可能更“Swifty”:

// Load "mysoundname.wav"
if let soundURL = Bundle.main.url(forResource: "mysoundname", withExtension: "wav") {
    var mySound: SystemSoundID = 0
    AudioServicesCreateSystemSoundID(soundURL as CFURL, &mySound)
    // Play
    AudioServicesPlaySystemSound(mySound);
}

请注意,这是一个重现问题中代码效果的简单示例。你需要确保import AudioToolbox,加上这种代码的一般模式是在你的应用程序启动时加载你的声音,将它们保存在某处的SystemSoundID实例变量中,在你的应用程序中使用它们,然后完成后致电AudioServicesDisposeSystemSoundID

【讨论】:

  • 还需要导入AudioToolbox
  • 以后需要调用AudioServicesDisposeSystemSoundID(mySound)释放内存吗?如果您立即执行此操作,则声音基本上不会播放(立即清理)所以我做了dispatch_after 并在 10 秒后清理了它。
  • @owenfi 我的答案中的代码片段只是问题中代码片段的 Swift 等价物。 AudioServices 的一般模式是在您的应用程序启动时加载您的声音,在整个应用程序中使用它们,并在应用程序关闭时处理它们,但每个应用程序都会有所不同。
  • @ozgur 你为什么使用过时的 Xcode 版本?我们需要知道“不工作”是什么意思,如果您有具体问题,最好提出一个新问题。
  • 其实这是播放wav文件的唯一方式。 AVPlayer 似乎不起作用。
【解决方案2】:

这是我添加到 FlappySwift 中的一些有效代码:

import SpriteKit
import AVFoundation

class GameScene: SKScene {

    // Grab the path, make sure to add it to your project!
    var coinSound = NSURL(fileURLWithPath: Bundle.main.path(forResource: "coin", ofType: "wav")!)
    var audioPlayer = AVAudioPlayer()

    // Initial setup
    override func didMoveToView(view: SKView) {
        audioPlayer = AVAudioPlayer(contentsOfURL: coinSound, error: nil)
        audioPlayer.prepareToPlay()
    }

    // Trigger the sound effect when the player grabs the coin
    func didBeginContact(contact: SKPhysicsContact!) {
        audioPlayer.play()
    }

}

【讨论】:

  • 看起来你可以在使用它之前声明audioPlayer,但这对我在模拟器中不起作用。我必须像你一样在顶部声明它。
  • @Adam Loving 您可以在使用它之前立即声明 audioPlayer,但请确保您在声明它的同一函数中调用 play() (而不是好的答案)此外,我会声明 @987654322 @ 和 audioPlayer 使用 let 而不是 var,因为您不想在以后更改这些对象。
  • 在 Swift 2 中记得以这种方式运行它do { (player object) } catch _ { } 否则你会得到一个错误! :)
  • 但是注意!它将暂停播放器的背景音乐。要播放短声音,我们必须使用下面的答案
  • 投反对票——这不是系统声音,它使用的是不同的 api
【解决方案3】:

方便的 Swift 扩展:

import AudioToolbox

extension SystemSoundID {
    static func playFileNamed(fileName: String, withExtenstion fileExtension: String) {
        var sound: SystemSoundID = 0
        if let soundURL = NSBundle.mainBundle().URLForResource(fileName, withExtension: fileExtension) {
            AudioServicesCreateSystemSoundID(soundURL, &sound)
            AudioServicesPlaySystemSound(sound)
        }
    }
}

然后,您可以从您应用中的任何位置(记得import AudioToolbox)拨打电话

SystemSoundID.playFileNamed("sound", withExtenstion: "mp3")

播放“sound.mp3”

【讨论】:

  • 当我在 SpriteKit 游戏中执行此操作时,在播放声音之前总是有延迟。即使我把它放在DispatchQueue.global(qos: .userInitiated).async {}里面。
  • NSBundle 已替换为Bundle,请改用Bundle.main.url(forResource: fileName, withExtension: fileExtension)
【解决方案4】:

这会从名为 Cha-Ching.aiff 的文件中创建一个 SystemSoundID

import AudioToolbox

let chaChingSound: SystemSoundID = createChaChingSound()

class CashRegisterViewController: UIViewController {
    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
        AudioServicesPlaySystemSound(chaChingSound)
    }
}

func createChaChingSound() -> SystemSoundID {
    var soundID: SystemSoundID = 0
    let soundURL = CFBundleCopyResourceURL(CFBundleGetMainBundle(), "Cha-Ching", "aiff", nil)
    AudioServicesCreateSystemSoundID(soundURL, &soundID)
    CFRelease(soundURL)
    return soundID
}

【讨论】:

  • 您是否尝试编译代码?我收到错误“无法转换 extression 的类型 'Unmanaged !'从这一行输入'CFString'" "let soundURL = CFBundleCopyResourceURL(CFBundleGetMainBundle(), "Cha-Ching", "aiff", nil)"
  • 这应该是公认的答案,因为提供的 Obj-C 示例基于 AudioToolBox 框架
  • @JochenBedersdorfer,由于 Core Foundation 对象被自动管理内存,您可能会遇到错误。
【解决方案5】:

有一个类和AudioToolbox:

import AudioToolbox

class Sound {

    var soundEffect: SystemSoundID = 0
    init(name: String, type: String) {
        let path  = NSBundle.mainBundle().pathForResource(name, ofType: type)!
        let pathURL = NSURL(fileURLWithPath: path)
        AudioServicesCreateSystemSoundID(pathURL as CFURLRef, &soundEffect)
    }

    func play() {
        AudioServicesPlaySystemSound(soundEffect)
    }
}

用法:

testSound = Sound(name: "test", type: "caf")
testSound.play()

【讨论】:

  • 我喜欢这个答案。同样因为它是系统声音,所以我没有收到 AVAudioPlayer 在 xcode 8 的控制台中抛出的系统消息。
  • 请帮我做同样的事情,声音播放但音量太低。听不见
【解决方案6】:
import AVFoundation

var audioPlayer = AVAudioPlayer()

class GameScene: SKScene {

    override func didMoveToView(view: SKView) {

        let soundURL = NSBundle.mainBundle().URLForResource("04", withExtension: "mp3")
        audioPlayer = AVAudioPlayer(contentsOfURL: soundURL, error: nil)
        audioPlayer.play()
    }
}

【讨论】:

  • 现代 Swift 中的 AVAudioPlayer(contentsOf: soundURL)
【解决方案7】:

此代码对我有用。为 AVAudioPlayer 使用 Try and Catch

import UIKit
import AVFoundation
class ViewController: UIViewController {

    //Make sure that sound file is present in your Project.
    var CatSound = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("Meow-sounds.mp3", ofType: "mp3")!)
    var audioPlayer = AVAudioPlayer()

    override func viewDidLoad() {
        super.viewDidLoad()

        do {

            audioPlayer = try AVAudioPlayer(contentsOfURL: CatSound)
            audioPlayer.prepareToPlay()

        } catch {

            print("Problem in getting File")

        }      
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    @IBAction func button1Action(sender: AnyObject) {

        audioPlayer.play()
    }
}

【讨论】:

    【解决方案8】:
    var mySound = NSSound(named:"Morse.aiff")
    mySound.play()
    

    "Morse.aiff" 是 OSX 的系统声音,但如果您在 XCode 中单击“命名”,您将能够查看(在 QuickHelp 窗格中)此功能正在搜索声音的位置。它可以在您的“支持文件”文件夹中

    【讨论】:

    • 问题是关于iOS的。
    • 确实...无法在模拟器中实现。迄今为止没有可用的文档
    【解决方案9】:

    根据新的 Swift 2.0,我们应该使用 do try catch。代码如下所示:

    var badumSound = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("BadumTss", ofType: "mp3"))
    var audioPlayer = AVAudioPlayer()
     do {
         player = try AVAudioPlayer(contentsOfURL: badumSound)
     } catch {
         print("No sound found by URL:\(badumSound)")
     }
     player.prepareToPlay()
    

    【讨论】:

      【解决方案10】:

      这适用于 Swift 4:

      if let soundURL = Bundle.main.url(forResource: "note3", withExtension: "wav") {
                      var mySound: SystemSoundID = 0
                      AudioServicesCreateSystemSoundID(soundURL as CFURL, &mySound)
                      // Play
                      AudioServicesPlaySystemSound(mySound);
                  }
      

      【讨论】:

      • 请解释一下您的代码。仅代码的答案不如解释有价值。
      • @Vincent +1,实际上我想知道 & 运算符。这可能在声音和记忆之间被引用。
      • 你必须添加 import AudioToolbox 然后添加上面的代码
      【解决方案11】:
      //Swift 4
      import UIKit
      import AVFoundation
      
      class ViewController: UIViewController {
      
          var player : AVAudioPlayer?
      
          override func viewDidLoad() {
              super.viewDidLoad()
          }
      
          @IBAction func notePressed(_ sender: UIButton) {
              let path = Bundle.main.path(forResource: "note1", ofType: "wav")!
              let url = URL(fileURLWithPath: path)
              do {
                  player = try AVAudioPlayer(contentsOf: url)
                  player?.play()
              } catch {
                  // error message
              }
          }
      }
      

      【讨论】:

        【解决方案12】:

        让我们看看这个问题的更新方法:

        Import AudioToolbox
        
        func noteSelector(noteNumber: String) {
        
            if let soundURL = Bundle.main.url(forResource: noteNumber, withExtension: "wav") {
                var mySound: SystemSoundID = 0
                AudioServicesCreateSystemSoundID(soundURL as CFURL, &mySound)
                AudioServicesPlaySystemSound(mySound)
        }
        

        【讨论】:

        • 代码在 Swift 4 上运行良好,但显然发出的声音不跟随媒体音量
        【解决方案13】:

        你可以在 Swift 5.2 中试试这个:

        func playSound() {
                let soundURL = Bundle.main.url(forResource: selectedSoundFileName, withExtension: "wav")
                do {
                    audioPlayer = try AVAudioPlayer(contentsOf: soundURL!)
                }
                catch {
                    print(error)
                }
                audioPlayer.play()
            }
        

        【讨论】:

          【解决方案14】:
          import UIKit
          import AudioToolbox
          
          class ViewController: UIViewController {
          
              let toneSound : Array =  ["note1","note2","note3","note4","note5","note6"]
          
              override func viewDidLoad() {
                  super.viewDidLoad()
                  // Do any additional setup after loading the view.
          
              }
          
              func playSound(theTone : String) {
                  if let soundURL = Bundle.main.url(forResource: theTone, withExtension: "wav") {
                      var mySound: SystemSoundID = 0
                      do {
                          AudioServicesCreateSystemSoundID(soundURL as CFURL, &mySound)
                          // Play
                          AudioServicesPlaySystemSound(mySound);
                      }
                      catch {
                         print(error)
                      }
                  }
              }
          
              @IBAction func anypressed(_ sender: UIButton) {
                  playSound(theTone: toneSound[sender.tag-1] )
              }    
          
          }
          

          【讨论】:

            【解决方案15】:

            Matt Gibson 的解决方案对我有用,这里是 swift 3 版本。

            if let soundURL = Bundle.main.url(forResource: "ringSound", withExtension: "aiff") {
              var mySound: SystemSoundID = 0
              AudioServicesCreateSystemSoundID(soundURL as CFURL, &mySound)
              AudioServicesPlaySystemSound(mySound);
            }
            

            【讨论】:

              【解决方案16】:

              斯威夫特 4

              import UIKit
              import AudioToolbox
              
              class ViewController: UIViewController{
              
              var sounds : [SystemSoundID] = [1, 2, 3, 4, 5, 6, 7]
              
              override func viewDidLoad() {
                  super.viewDidLoad()
              
                  for index in 0...sounds.count-1 {
                      let fileName : String = "note\(sounds[index])"
              
                      if let soundURL = Bundle.main.url(forResource: fileName, withExtension: "wav") {
                          AudioServicesCreateSystemSoundID(soundURL as CFURL, &sounds[index])
                      }
                  }
              }
              
              
              
              @IBAction func notePressed(_ sender: UIButton) {
                  switch sender.tag {
                  case 1:
                      AudioServicesPlaySystemSound(sounds[0])
                  case 2:
                      AudioServicesPlaySystemSound(sounds[1])
                  case 3:
                      AudioServicesPlaySystemSound(sounds[2])
                  case 4:
                      AudioServicesPlaySystemSound(sounds[3])
                  case 5:
                      AudioServicesPlaySystemSound(sounds[4])
                  case 6:
                      AudioServicesPlaySystemSound(sounds[5])
                  default:
                      AudioServicesPlaySystemSound(sounds[6])
                  }
              }
              }
              

              import UIKit
              import AVFoundation
              
              class ViewController: UIViewController, AVAudioPlayerDelegate{
              
              var audioPlayer : AVAudioPlayer!
              
              override func viewDidLoad() {
                  super.viewDidLoad()
              }
              
              @IBAction func notePressed(_ sender: UIButton) {
              
                  let soundURL = Bundle.main.url(forResource: "note\(sender.tag)", withExtension: "wav")
              
                  do {
                      audioPlayer = try AVAudioPlayer(contentsOf: soundURL!)
                  }
                  catch {
                      print(error)
                  }
              
                  audioPlayer.play()
              
              }
              }
              

              【讨论】:

                【解决方案17】:

                Xcode 9.2工作

                if let soundURL = Bundle.main.url(forResource: "note1", withExtension: "wav") {
                   var mySound: SystemSoundID = 0
                   AudioServicesCreateSystemSoundID(soundURL as CFURL, &mySound)
                   // Play
                    AudioServicesPlaySystemSound(mySound);
                 }
                

                【讨论】:

                  【解决方案18】:

                  Swift 代码示例

                  import UIKit
                  import AudioToolbox
                  
                  class ViewController: UIViewController {  
                  
                  override func viewDidLoad() {
                      super.viewDidLoad()
                  }
                  
                  @IBAction func notePressed(_ sender: UIButton) {
                  
                      // Load "mysoundname.wav"
                  
                      if let soundURL = Bundle.main.url(forResource: "note1", withExtension: "wav") {
                          var mySound: SystemSoundID = 0
                          AudioServicesCreateSystemSoundID(soundURL as CFURL, &mySound)
                      // Play
                  
                          AudioServicesPlaySystemSound(mySound);
                      }
                  }
                  

                  【讨论】:

                  • 请添加更多详细信息说明此代码为何有用。
                  【解决方案19】:

                  Swift 4 和 iOS 12

                  var audioPlayer: AVAudioPlayer?
                  
                  override func viewDidLoad() {
                      super.viewDidLoad()
                  
                  
                  
                  }
                  
                  @IBAction func notePressed(_ sender: UIButton) {
                  
                      // noise while pressing button
                  
                      _ = Bundle.main.path(forResource: "note1", ofType: "wav")
                  
                      if Bundle.main.path(forResource: "note1", ofType: "wav") != nil {
                          print("Continue processing")
                      } else {
                          print("Error: No file with specified name exists")
                      }
                  
                      do {
                          if let fileURL = Bundle.main.path(forResource: "note1", ofType: "wav") {
                              audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: fileURL))
                          } else {
                              print("No file with specified name exists")
                          }
                      } catch let error {
                          print("Can't play the audio file failed with an error \(error.localizedDescription)")
                      }
                  
                  
                      audioPlayer?.play()    }
                  

                  }

                  【讨论】:

                  【解决方案20】:

                  在 Swift 中使用这个函数发声(你可以在你想发声的地方使用这个函数。)

                  首先添加 SpriteKit 和 AVFoundation 框架。

                  import SpriteKit
                  import AVFoundation
                   func playEffectSound(filename: String){
                     runAction(SKAction.playSoundFileNamed("\(filename)", waitForCompletion: false))
                   }// use this function to play sound
                  
                  playEffectSound("Sound File Name With Extension")
                  // Example :- playEffectSound("BS_SpiderWeb_CollectEgg_SFX.mp3")
                  

                  【讨论】:

                    【解决方案21】:

                    此代码适用于我:

                    class ViewController: UIViewController {
                    
                        var audioFilePathURL : NSURL!
                        var soundSystemServicesId : SystemSoundID = 0
                    
                        override func viewDidLoad() {
                            super.viewDidLoad()
                            // Do any additional setup after loading the view, typically from a nib.
                            audioFilePathURL = NSBundle.mainBundle().URLForResource("MetalBell", withExtension: "wav")
                    
                            AudioServicesCreateSystemSoundID( audioFilePathURL, &soundSystemServicesId)
                    
                    
                        }
                    
                        override func didReceiveMemoryWarning() {
                            super.didReceiveMemoryWarning()
                            // Dispose of any resources that can be recreated.
                    
                    
                        }
                    
                    
                        @IBAction func PlayAlertSound(sender: UIButton) {
                    
                             AudioServicesPlayAlertSound(soundSystemServicesId)
                        }
                    }
                    

                    【讨论】:

                      【解决方案22】:

                      对于 Swift 3

                      extension SystemSoundID {
                          static func playFileNamed(_ fileName: String, withExtenstion fileExtension: String) {
                              var sound: SystemSoundID = 0
                              if let soundURL = Bundle.main.url(forResource: fileName, withExtension: fileExtension) {
                                  AudioServicesCreateSystemSoundID(soundURL as CFURL, &sound)
                                  AudioServicesPlaySystemSound(sound)
                              }
                          }
                      }
                      

                      【讨论】:

                        【解决方案23】:

                        Swift 3 我就是这样做的。

                        {
                        
                        import UIKit
                        import AVFoundation
                        
                                let url = Bundle.main.url(forResource: "yoursoundname", withExtension: "wav")!
                                do {
                        
                                    player = try AVAudioPlayer(contentsOf: url); guard let player = player else { return }
                        
                                    player.prepareToPlay()
                                    player.play()
                                } catch let error as Error {
                                    print(error)
                        
                                }
                            }
                        

                        【讨论】:

                          【解决方案24】:

                          你不能只import AVFoundation,选择音频播放器(var audioPlayer : AVAudioPlayer!),然后播放声音吗? (let soundURL = Bundle.main.url(forResource: "sound", withExtension: "wav")

                          【讨论】:

                            猜你喜欢
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 2022-12-18
                            相关资源
                            最近更新 更多