快速创建和播放声音


103

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

对于Objective-C来说就像这样:

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

然后播放,我会做:

AudioServicesPlaySystemSound(Explosion);

有人知道我该怎么做吗?


2
这个问题的根源是如何快速调用C函数。我对此也很好奇。
67樱桃2014年

此行可以创建声音网址: var url :NSURL = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("mysoundname", ofType: "wav"))
Connor

@connor感谢您的工作,但AudioServicesCreateSystemSoundID怎么样
Jacob Banks

对此我不确定。我只能从Swift调用Objective-C API。
康纳2014年

Answers:


83

这是我添加到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爱您可以在使用它之前就声明audioPlayer,但是请确保在与声明它相同的函数中调用play()(而不是好的答案)。此外,我会声明coinSoundaudioPlayerwith letvar因为您不想在以后的时间更改这些对象。
fat32

3
在Swift 2中,请记住以这种方式运行它,do { (player object) } catch _ { }否则您将得到一个错误!:)
ParisNakitaKejser 2015年

1
但是注意!它将暂停播放器的背景音乐。要播放短声音,我们必须使用下面的答案
Nikita Pronchik 2015年

Downvote-这不是系统声音,它使用不同的API
William Entriken

119

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

// 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在完成后调用跟他们。


1
您还需要导入AudioToolbox
Brody Robertson

您是否需要致电AudioServicesDisposeSystemSoundID(mySound)以释放内存?如果您立即执行此操作,则声音基本上不会播放(立即清除),因此我做了dispatch_after,并在10秒后将其清除了。
owenfi'9

@owenfi我的答案中的代码片段与问题中的代码片段在Swift中是等效的。AudioServices的一般模式是在应用启动时加载声音,在整个应用中使用它们,并在应用关闭时进行处理,但是每个应用都会有所不同。
马特·吉布森

@ozgur为什么要使用Xcode的过时版本?我们需要知道“不起作用”的含义,如果您有特定问题,最好提出一个新问题。
马特·吉布森

实际上,这是播放wav文件的唯一方法。AVPlayer似乎不起作用。

18

便捷的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)替代
diachedelic

14

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

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
}

您是否尝试编译代码?我收到错误消息“无法转换扩展名的类型'Unmanaged <CFURL>!”。在此行中输入“ CFString””“让soundURL = CFBundleCopyResourceURL(CFBundleGetMainBundle(),“ Cha-Ching”,“ aiff”,nil)“
bpolat 2014年


2
鉴于提供的Obj-C示例基于AudioToolBox框架
eharo2,2014年

@JochenBedersdorfer,由于Core Foundation对象是自动进行内存管理的,您可能会遇到错误。
XCool 2015年

8

使用类和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()

2
我喜欢这个答案。同样因为它是系统声音,所以我没有收到系统消息,AVAudioPlayer会在控制台中抛出
xcode8。– TPot

请帮助我做同样的事情,声音播放但是音量太低。听不到
veeresh kumbar '19

5
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)
装箱

5

该代码对我有用。对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()
    }
}

4
var mySound = NSSound(named:"Morse.aiff")
mySound.play()

“ Morse.aiff”是OSX的系统声音,但是如果您在XCode中单击“命名”,则可以查看(在“快速帮助”窗格中)此函数在其中搜索声音的位置。它可以在您的“ Supporting files”文件夹中


4
问题是关于iOS。
rmaddy14年

确实...无法在模拟器中实现。迄今为止没有可用的文档
philippe 2014年

4

根据新的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()

3

这正在使用Swift 4:

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

2
请解释一下您的代码。仅代码的答案没有解释的价值。
Vincent

@Vincent +1,实际上我在想&操作员。这可能在声音和记忆之间被引用。
elia

您必须添加导入AudioToolbox然后添加上面的代码
Mohammad Aboelnasr

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

2

让我们来看一个更新的方法来解决这个问题:

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

1
该代码在Swift 4上运行良好,但显然发出的声音不符合媒体音量
David Vargas,

1

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

1

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

}
}

1

在...工作 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);
 }

1

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

请添加更多有关此代码为何有用的详细信息。
Berendschot

1

您可以在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()
    }

1

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

}


不要只是发布代码-请解释它的作用!stackoverflow.com/help/how-to-answer
Nino Filiu

请参阅这篇文章的问题。您可以找到答案!谢谢@NinoFiliu
Gulsan Borbhuiya

0

使用此功能在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")

0

该代码对我有用:

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

0

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

0

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)

        }
    }

0

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


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

}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.