我喜欢在我的应用中播放声音。我发现了很多例子,也可以在Swift 3上编译和运行它们。但是它们总是用于iOS。当在我的应用程序中使用此代码时,AVAudioSession保持未定义。我需要做什么? OSX有什么不同的东西吗?
import AVFoundation
...
var audioPlayer = AVAudioPlayer()
func PlaySound( ) {
let alertSound = URL(fileURLWithPath: Bundle.main.path(forResource: "Sound", ofType: "mp3")!)
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
} catch _ {
}
do {
try AVAudioSession.sharedInstance().setActive(true)
} catch _ {
}
do {
audioPlayer = try AVAudioPlayer(contentsOf: alertSound)
} catch _{
}
audioPlayer.prepareToPlay()
audioPlayer.play()
}
答案 0 :(得分:6)
Swift 3/4 / 4.2 / 5 - 最简单的解决方案:
NSSound(named: "customSound")?.play()
答案 1 :(得分:5)
我将以下函数与Swift 3和Cocoa项目结合使用。
import AVFoundation
func playSound(file:String, ext:String) -> Void {
let url = Bundle.main.url(forResource: file, withExtension: ext)!
do {
let player = try AVAudioPlayer(contentsOf: url)
player.prepareToPlay()
player.play()
} catch let error {
print(error.localizedDescription)
}
}
//用法//
playSound(file: "sound", ext: "caf") // where the file name is sound.caf.
确保在Xcode项目中选择音频文件时,目标成员资格复选框已打开。
答案 2 :(得分:0)
El Tomato答案的修改版本, 这是我经常用于声音的Swift 4.2类:
用法:
/// EXAMPLE 1
//calling this will create a "bop.m4a" player in memory, and, play it immediately
MakeSound.shared.playSound("bop.m4a")
//calling it a second time has a lot less overhead because the player is already in memory
MakeSound.shared.playSound("bop.m4a")
///EXAMPLE 2
//simply calls the above many times
MakeSound.shared.playSound(["bop.m4a", "beep.m4a", "bong.m4a"])
// EXAMPLE 3
//registers a shorthand, for quick calling
MakeSound.shared.registerSound(fileName: "bop", fileExtension: "m4a", shortHand: "b")
//plays using the shorthand, mostly handy because you define the actual file once,
//and can change the one line of code without having to change every reference
MakeSound.shared.playSound("b")
和班级
class MakeSound {
private var players = [String : AVAudioPlayer]()
static var shared = MakeSound()
func playSound(fileName: String, fileExtension: String) {
if registerSound(fileName: fileName, fileExtension: fileExtension, shortHand: fileName+"."+fileExtension) {
playSound(fileName+"."+fileExtension)
}
}
//thought about naming this "playsoundS", but i like it with the same name, makes it easier to type
func playSound(_ shortHands : [String]){
for sh in shortHands{
playSound(sh)
}
}
///playSound("shorthand") OR playSound("mySound.mp3")
func playSound(_ shortHand : String) {
if let player = players[shortHand] {
player.prepareToPlay()
player.play()
} else {
if shortHand.contains(".") {
//going to assume that coder will not send "." as a filepath
//also going to assume that coder will not send "xyz." as filepath
var comp = shortHand.components(separatedBy: ".")
let ext = comp.last!
comp.removeLast()
if registerSound(fileName: comp.joined(separator: "."), fileExtension: ext, shortHand: shortHand) {
playSound(shortHand)
}
} else {
print("Sound request sent to makesound, no such shorthand, not a valid filename either.")
}
}
}
///registers a sound with makeSound, and returns a bool based on the success
@discardableResult func registerSound(fileName : String, fileExtension: String, shortHand: String) -> Bool {
guard let url = Bundle.main.url(forResource: fileName, withExtension: fileExtension) else {
print("Unable to register sound: \(shortHand). Filepath not valid.")
return false
}
do {
let player = try AVAudioPlayer(contentsOf: url)
players[shortHand] = player
} catch let error {
print("Audioplayer \"\(shortHand)\" unable to initialize:\n" + error.localizedDescription)
return false
}
return true
}
}
现在,我承认NSSound
是迄今为止最简单,最直接的方法,但是,我们中有些人更喜欢AVFoundation
,因为我们拥有更多的控制权。 (讽刺的是,此类控件已在我的课程中删除)