在 macOS 上播放声音
Posted
技术标签:
【中文标题】在 macOS 上播放声音【英文标题】:Playing a sound on macOS 【发布时间】:2016-12-10 13:07:31 【问题描述】:我喜欢在我的应用中播放声音。我找到了很多示例,也可以在 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()
【问题讨论】:
【参考方案1】:Swift 3 / 4 / 4.2 / 5 - 最简单的解决方案:
NSSound(named: "customSound")?.play()
【讨论】:
本话题与NSSound无关。 @ElTomato 不是吗?The NSSound class provides a simple interface for loading and playing audio files
developer.apple.com/reference/appkit/nssound
阅读原文。发布此主题的人指的是 AVAudioSession,而不是 NSSound。
主题作者并没有要求只坚持 AV* 类。所以,NS* 类的答案也是有效的。
我可以用你的方法改变音量、音高和速度等因素吗?【参考方案2】:
我将以下函数与 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 项目中的音频文件时,目标成员资格复选框已打开。
【讨论】:
对我来说也是:“使用未解析的标识符”。我已经导入了AVFoundation
。【参考方案3】:
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
,因为我们有更多的控制权。 (讽刺的是,这种控制在我的课堂上被删除了)
【讨论】:
以上是关于在 macOS 上播放声音的主要内容,如果未能解决你的问题,请参考以下文章