swift - 将 NSSound 转换为 AVAudioPlayer

标签 swift macos audio avaudioplayer nssound

我有一些 NSSound 对象,我想将其转换为 AVAudioPlayer 实例。我有与 NSSound 对象关联的文件路径 (NSURL),但原始文件可能不存在。这是我目前所拥有的:

class SoundObj: NSObject {
    var path: NSURL?
    var sound: NSSound?
    var player: AVAudioPlayer
}

let aSound = SoundObj()
aSound.path = NSURL(fileURLWithPath: "file:///path/to/sound.m4a")
aSound.sound = NSSound(contentsOfURL: aSound.path)!

do {
    try aSound.player = AVAudioPlayer(contentsOfURL: aSound.path)
} catch {
    // perhaps use AVAudioPlayer(data: ...)?
}

如何将 NSSound 对象转换为 AVAudioPlayer 实例?

最佳答案

所以我没有看到从 NSSound 对象获取 URL 的公共(public)接口(interface),所以我深入研究了 private headers看看我能找到什么。原来有私有(private)实例方法 url_url 返回 NSSound 的 URL。大概这些是 NSURL ivar 或属性的 getter。

使用 Objective-C 这会很容易:我们只需将方法添加到新接口(interface)或扩展。对于纯 Swift,事情有点棘手,我们需要通过 Objective-C 协议(protocol)公开访问器:

@objc protocol NSSoundPrivate {
    var url: NSURL? { get }
}

因为 url 是一个实例方法,你可以使用 func url() -> NSURL? 而不是使用变量来获得更好的结果。您的经验可能有所不同:使用 var 来模拟只读属性的行为似乎对我有用。

我在 AVAudioPlayer 的扩展中写了一个新的便利初始化程序:

extension AVAudioPlayer {
    convenience init?(sound: NSSound) throws {    
        let privateSound = unsafeBitCast(sound, NSSoundPrivate.self)    
        guard let url = privateSound.url else { return nil }
        do {
            try self.init(contentsOfURL: url)
        } catch {
            throw error
        }
    }
}

用法:

let url = NSURL(...)    
if let sound = NSSound(contentsOfURL: url, byReference: true) {
    do {
        let player = try AVAudioPlayer(sound: sound)
        player?.play()
    } catch {
        print(error)
    }        
}

在尝试在 NSSound 的 ivars、实例方法和属性中找到与 NSData 相关的任何内容之后,我得出的结论是,无论您使用什么来初始化 >NSSound 在类的实现中的某个地方被混淆了,并且不像 URL 那样可用。

关于swift - 将 NSSound 转换为 AVAudioPlayer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36885087/

相关文章:

windows - Windows 和 OS X 上的 GTK+ 是使用 native 小部件还是模拟它们?

python - 如何通过 Python 为 Python 脚本创建 Mac 应用程序包

java - 强制音频进入麦克风

android - html声音元素中无法识别nativescript-audio录音

ios - 使用 Swift 包管理依赖项分发 iOS 框架

ios - 在快速滚动 collectionview 时,第一行数据在最后一行重复

ios - 设置对象 :forKey: mutating method sent to immutable object

html - 使用 Alamofire 的谷歌搜索失败(iOS、Swift、JSON、HTML)

macos - 如何在 OS X 上卸载 Subversion

actionscript-3 - as3删除flv播放类我仍然可以听到声音