Skip to main content
Re:Linked

借助 PulseAudio 在 Telegram 进行音乐广播

· #devops · 约 4.1k 字
本文距离上次更新已经超过 900 天。因此,其中的信息可能已经过时。

Telegram 更新了语音聊天功能,然而中文 TG 用户大多是不会真的用 TG 语音聊天的。那就用它来做音乐/广播串流吧。

(注:码率只有不到 50kbps,全损音质可能)

Telegram 的语音聊天功能只是个引子,本文实际上描述了一个更大的需求面:即使用输出作为输入。除了语音聊天之外,像是通过 Zoom 或其它会议服务进行的动画视频鉴赏会之类。主要的需求是:

  • 以设备的音频输出作为这些软件的音频输入
  • 不使用物理输入设备(例如麦克风)
  • Extra: 不影响自己使用物理音频输出

开始

在本文中可能会用到的软件:

  • PulseAudio,本文的主角 (pulseaudio)
  • PulseAudio Volume Control(下称 pavucontrol),图形化控制 PulseAudio 的软件。PulseAudio 的命令行 pacmd 可以替代它,但是这个界面要方便得多。 (pavucontrol)
  • VLC 播放器 (vlc)
  • Telegram,或任何你需要用来进行音频串流的工具

一些术语解释

输入和输出

关于音频的传输主要分为两部分,输入和输出。这里的输入和输出是对于设备而言的,也就是说:

  • 输入 (input):从(物理或虚拟)设备获取音频到系统软件,也就是「录制」的方向。
  • 输入设备 (source):输入的源(物理或虚拟)设备。在 PulseAudio 中一般被称为 source。例如麦克风、有麦克风功能的耳机、还有下文会提到的 monitor 等。
  • 输出 (output):从系统软件传递音频至(物理或虚拟)设备,也就是「播放」的方向。
  • 输出设备 (sink):输出的目标(物理或虚拟)设备。在 PulseAudio 中一般被称为 sink。例如扬声器、耳机等。

图解的话,大概就是这样:

     Source             Client               Sink

                     +----------+
                -->  | Telegram |  ---
                |    +----------+    |
                |                    |
  +----------+  |    +----------+    |    +----------+
  | Micphone |  -->  | Recorder |  ---->  | Earphone |
  +----------+  |    +----------+    |    +----------+
                |                    | 
                |    +----------+    |
                -->  |   Zoom   |  ---
                     +----------+

Monitor

在 PulseAudio 中,每一个输出一般都有一个 Monitor,用于将此输出用作输入。通过命令 pacmd list-sources 可以看到有一些 name 结尾为 .monitor 的输入源,它们就是对应输出的 Monitor。在想把输出作为输入的时候,可以直接使用它们。在本文提到的解决方案中,我们就利用了 Monitor 将输出转化为输入。也就是说,所有的 monitor 都是 source,可以向软件提供音频信息。

Client、Source 与 Sink

PulseAudio clients can send audio to "sinks" and receive audio from "sources".

About PulseAudio

每一个从 PulseAudio 获取声音的程序都是一个 "client"。通过 pacmd list-clients 可以查看 client 的列表。Client 可以从 source 中获取音频,也可以将音频输入至 sink。

Monitors

简单方案

如果自己不需要物理音频输出来做其它事情的话,直接使用物理输出作为输入即可。一般是 "Mirror of [你的设备]"。

或者,更复杂但更优雅的方案

创建新的输出设备

我们可以创建一个新输出,直接让播放器(例如 VLC)把音乐这个输出,然后使用这个输出的 Monitor 作为输入,将这个输入传输到其它应用中。用图表示就是大概这样:

     Source                  Client                  Sink

        -----------------------------------------------
        |                                             |
        |                                             |
        |             +------------------+       +----------+
        |             | Player (eg. VLC) |  -->  | Loopback |
        |             +------------------+       +----------+
        v
  +------------+     +---------------------+
  | LB Monitor | --> | Telegram, Zoom etc. |
  +------------+     +---------------------+

在 Linux 上,我们可以使用 PulseAudio 方便地达到这个目的。

Windows 也有类似的虚拟音频输出端口工具: VB-CABLE

我们只需要创建一个 null sink。记得设置好它的名字。

pacmd load-module module-null-sink sink_name=SinkOne

我们可以给它一个 description 方便后续查看。

pacmd update-sink-proplist SinkOne device.description=MySink

你可能会注意到,当 description 中出现空格的时候,pacmd 不愿意接收参数。这种时候请这么做:

pacmd 'update-sink-proplist SinkOne device.description="A description sentence"'

(ref)

这样就有了一个新的输出。

New sink

我们可以把任何需要通过音频输入串流的音频内容输出到这个输出。例如,在 VLC 中是这样设置:

VLC: Change output device

切换音频输入

之后,我们就可以用这个输出的 Monitor 作为输入,将播放的内容进行串流。选择名字类似 "Monitor of Null Output" 的输入(如果你没有更改它的名字的话)即可。

你也可以使用 pacmd update-source-proplist 来修改这个输入的 description。只要在 pacmd list-sources 找到它的 ID,pacmd update-source-proplist <ID> device.description="Name" 即可。

...或者使用 PulseAudio 指定音频输入

有些软件内部可以切换音频输入源,例如 Telegram:

Switching the input source on Telegram

然而,在它们的输入源列表中,可能看不到特殊输入源(例如本文需要的 Monitor)。比较好的方法是,在这些软件内选择默认的音频输入源,而在 PulseAudio 端切换输入源。在 pavucontrol 中的 "Recording" 标签下找到对应的软件,使用右侧的下拉列表切换输入即可。

Switching the input source on PulseAudio

注意 Telegram 可能需要先使用其它输入录音(开麦)一次之后才能在 pavucontrol 中看到。

最后

找点好音乐,开始你的 Telegram DJ 之旅吧!

另见

  • https://endless.ersoft.org/pulseaudio-loopback/ - 描述了一个更复杂的客制化 PulseAudio 用例。

评论



LIKE