HOOOS

如何用 PipeWire 将旧安卓手机调教为 PC 的无线音箱?(超低延迟无损方案)

0 530 Arch玩家阿修 PipeWireLinux安卓玩机
Apple

家里吃灰的旧安卓手机,除了换盆,其实非常适合压榨出最后一丝剩余价值——当成 PC 的无线音箱。

在 Linux 步入 PipeWire 时代后,网络音频传输的配置变得前所未有的简单和高效。相比传统的 PulseAudio,PipeWire 拥有更低的内部延迟和更优秀的线程调度。

这里提供两种**纯开源、无广告、不需要安装任何国产全家桶/闭源商业软件(如 AudioRelay)**的调教方案。


准备工作

  1. 网络环境:确保你的 Linux PC 和旧安卓手机处于同一个局域网(最好是 5G 频段的 Wi-Fi,2.4G 容易受到蓝牙和微波炉干扰,导致爆音)。
  2. 确认音频服务:你的 Linux 发行版需要运行 PipeWire,并且安装了 pipewire-pulse 兼容层。现代发行版(如 Arch Linux, Fedora, Ubuntu 22.10+)默认就是这个配置。可以通过以下命令确认:
    pactl info | grep "Server Name"
    # 如果输出中包含 "on PipeWire",说明完全没问题
    

方案一:TCP 极简流传输(适合单设备,极度稳定)

这个方案通过 TCP 协议将 PC 的音频直接推送到手机端。它的优势是连接简单、音质无损、非常稳定,几乎没有断连的可能。

1. 安卓端准备

在安卓手机上安装 Simple Protocol Player。

  • 这是一款开源且完全免费的轻量级软件。
  • 你可以在 F-Droid 商店搜索下载,或者直接去 GitHub 搜索该项目的 Release 页面下载 APK。

2. PC 端开启音频广播

我们利用 pipewire-pulse 提供的简单协议模块,直接在运行时动态加载一个 TCP 发送端口:

打开终端,执行以下命令:

pactl load-module module-simple-protocol-tcp rate=48000 format=s16le channels=2 port=8010 record=true

参数解释:

  • rate=48000:采样率设置为 48kHz(安卓系统的原生采样率,避免手机端二次重采样引入延迟和失真)。
  • format=s16le:16位 CD 级音质,兼顾带宽与听感。
  • port=8010:监听端口,可以自定义。
  • record=true:这是核心。它代表录制 PC 正在播放的声音(即 Monitor 监听流),而不是等待接收声音。

执行后,终端会返回一串数字(模块 ID),说明服务已在后台运行。

3. 获取 PC 的局域网 IP

ip route get 1.1.1.1 | awk '{print $7}'
# 记下输出的 IP 地址,例如 192.168.31.100

4. 手机端连接播放

  1. 打开手机上的 Simple Protocol Player。
  2. 在 IP Address 中填入刚才获取的 PC IP(如 192.168.31.100)。
  3. Port 填入 8010。
  4. Sample Rate 选择 48000。
  5. Format 选择 16bit SE。
  6. 点击 Play。

现在,PC 上播放任何声音,手机都会同步播放。


方案二:RTP 组播广播(适合多设备同步、超低延迟)

如果你对延迟有着极致的要求(比如看视频要对口型),或者想让好几部旧手机在家里不同的房间同时播放 PC 的声音,RTP(实时传送协议)组播是唯一的标准答案。

RTP 基于 UDP 协议,不进行 TCP 那样繁琐的握手确认,延迟可以压到微秒级。

1. PC 端加载 RTP 广播模块

在终端中执行:

pactl load-module module-rtp-send

就这么简单。PipeWire 会自动将当前默认输出设备的音频流打包,通过局域网组播地址(默认通常是 224.0.0.56,端口 4004)广播出去。

如果你想查看具体的组播配置,或者自定义 IP 和端口,可以编辑 ~/.config/pipewire/pipewire.conf(如果没有,从 /usr/share/pipewire/ 拷贝一份),在 context.modules 中添加 libpipewire-module-rtp-sink,不过对于普通用户,使用上述的一键 pactl 命令就已经足够。

2. 安卓端接收

由于 RTP 是工业标准协议,安卓端甚至不需要安装专用客户端,任何支持网络流的播放器(例如 VLC for Android 或 MX Player)都可以直接接收。

  1. 打开手机上的 VLC。
  2. 选择 More(更多) -> New Stream(新建流)。
  3. 输入以下网络 URL:
    rtp://@224.0.0.56:5004
    
    (注意:如果使用的是默认的 module-rtp-send,默认端口可能是 5004,请根据实际测试,或者直接使用专门的 RTP Receiver App 自动扫网)
  4. 点击播放,音频即刻同步呈现。

进阶调优与避坑指南

1. 声音卡顿、爆音(Buffer Underrun)怎么解?

无线网络抖动是网络音箱最大的杀手。如果出现零星的“滋啦”声,可以尝试在加载模块时增大缓冲区。

对于方案一(TCP),可以在加载命令中加入 buffer 参数:

pactl load-module module-simple-protocol-tcp rate=48000 format=s16le channels=2 port=8010 record=true buffer=16384

同时,在安卓的 Simple Protocol Player 设置里,将 Buffer Size 往调大一档(例如调到 200ms 以上)。延迟和稳定性永远是天平的两端,需要根据你家 Wi-Fi 的质量寻找平衡点。

2. 怎么让 PC 扬声器和手机同时发声?

默认情况下,有些桌面环境在你连上网络音频源后,会自动把本地输出静音。
打开 pavucontrol(脉冲音频控制面板),切换到“播放”选项卡。你可以把特定播放器(如网易云音乐、浏览器)的输出设备手动指向 Monitor of [你的物理声卡],确保本地和网络端都有信号流过。

3. 一键开关脚本(免去每次敲命令)

每次都在终端里输入长命令很痛苦,可以写两个极简的 Shell 脚本。

开启脚本 start_phone_speaker.sh:

#!/bin/bash
# 卸载旧模块防止冲突
pactl unload-module module-simple-protocol-tcp 2>/dev/null
# 启动新模块
pactl load-module module-simple-protocol-tcp rate=48000 format=s16le channels=2 port=8010 record=true
echo "无线音箱服务已启动,请在手机端连接。"

关闭脚本 stop_phone_speaker.sh:

#!/bin/bash
pactl unload-module module-simple-protocol-tcp
echo "无线音箱服务已关闭。"

给它们可执行权限 chmod +x *.sh,以后想用的时候双击运行即可。

点评评价

captcha
健康