【问题标题】:Convert NSSound to AVAudioPlayer将 NSSound 转换为 AVAudioPlayer
【发布时间】:2016-08-21 11:19:12
【问题描述】:

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

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 实例?

【问题讨论】:

  • 如果音频文件不存在,这条线不会崩溃吗? aSound.sound = NSSound(contentsOfURL: aSound.path)!
  • 是的,但对于这种情况,.sound 永远不会为空。
  • 老实说,我认为您无法从 NSSound 获取声音数据。
  • @brimstone 有办法验证吗?
  • 我不太确定你在问什么。你想要一个自定义的AVAudioPlayer 初始化器,它接受NSSound 并返回AVAudioPlayer?我认为AVAsset 可能更适合您的需求。

标签: swift macos audio avaudioplayer nssound


【解决方案1】:

所以我没有看到从 NSSound 对象获取 URL 的公共接口,所以我去挖掘 private headers 看看我能找到什么。原来有私有实例方法url_url,它们返回NSSound 的URL。大概这些是NSURL ivar 或属性的吸气剂。

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

@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 那样可用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-28
    • 1970-01-01
    • 2015-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多