获取设备音频输出

时间:2021-02-24 20:41:58

标签: swift macos cocoa audio

我正在尝试获取我的 Mac 主音频输出,并点击它,然后使用语音在其上发送文本。

我目前遇到的问题是让我的 Mac 主声音输出。例如,如果我在 Youtube 上播放视频,它会将声音输出到我的笔记本电脑扬声器。我正在尝试利用该输出。

我正在使用

AVAudioEngine.mainMixerNode

但是,我没有得到任何输出。我也试过 AVAudioEngine.outputNode

这是我尝试过的:

engine = AVAudioEngine()
let _ = engine.mainMixerNode
engine.prepare()
do {
    try engine.start()
} catch {
    print("Start Error")
    return
}

do {
    let settings = engine.mainMixerNode.outputFormat(forBus: 0).settings
    print("FileType: \(settings[AVAudioFileTypeKey])") // Returns nil
    self.file = try! AVAudioFile(forWriting: url, settings: settings)
    
    engine.mainMixerNode.installTap(onBus: 0, bufferSize: 1024, format: nil) { // I've tried with a format and without
        (buffer: AVAudioPCMBuffer?, time: AVAudioTime!) -> Void in
        do {
            // Buffer must be empty because the CAF audio length is correct, but there's no sound. It's flat.
            try self.file.write(from: buffer!)
        } catch _{
            print("Problem Writing Buffer")
        }
    }
}

上面的代码设置了 Privacy - Microphone Usage Description。 (即使我不想点击麦克风)

这里的第一个问题是我不确定应该为我的输出使用什么文件类型。我试过 CAF,但在 GarageBand 中打开它没有声音(虽然有长度) 我已尝试将文件重命名为 m4awav,但 Apple 的 Music 只是不想播放它。

我做错了什么? 非常感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

不幸的是,像这样访问系统声音输出并非易事(从安全角度来看,这可能是一件好事)。

解决方案通常涉及设置可以播放音频的“假”音频设备,而不是您选择的默认输出设备。例如,这就是 BlackHole (https://github.com/ExistentialAudio/BlackHole) 和更年长的 SoundFlower (https://github.com/mattingalls/Soundflower) 使用的方法。这两个链接都指向源代码,您可以开始挖掘这些链接以了解它们如何实现这一点——同样,比 SO 答案保证的更深入。

就您正在探索的 mainMixerNode 而言,虽然名称听起来像是一个系统范围的设备,但它实际上只是控制应用程序声音的混音器。因此,尽管您可以点击它,但它只会让您访问正在播放的内容。这就是为什么你录制的文件是扁平的——除非你正在播放输出,否则它不会被录制。