分类
嵌入式开发

两台运行openwrt+wfb-ng的路由器,如何实现语音实时对讲沟通功能?

在两台运行OpenWrt + WFB-NG的路由器之间实现实时语音对讲是完全可行的。

其核心原理是:利用WFB-NG(WiFiBroadcast Next Generation)建立一个透明、低延迟的无线数据链路,然后在这个链路上运行一个轻量级的VoIP(网络电话)或音频流应用。

下面我将为你分解实现步骤,从基本概念到具体的配置方案。

1. 核心概念与架构

  1. WFB-NG链路层:WFB-NG利用Wi-Fi网卡的监听模式(Monitor Mode)和原始帧注入(Frame Injection)功能,创建了一个单向或双向的、不依赖标准Wi-Fi连接(AP/STA模式)的“无线网线”。这个链路对于上层应用来说是透明的,你可以把它看作一根虚拟的、点对点的以太网线。
  2. IP网络层:在WFB-NG创建的虚拟网络接口上(例如 wfb0),我们需要配置静态IP地址,让两台路由器能够互相通信。例如,路由器A配置为192.168.99.1,路由器B配置为192.168.99.2
  3. 音频应用层:在建立好的IP网络上,运行一个能够捕捉麦克风音频、编码、通过网络发送,并在另一端接收、解码、播放的应用程序。

2. 硬件准备

  1. 两台OpenWrt路由器:确保它们有足够的性能(CPU和RAM)来处理音频编码/解码。
  2. 兼容WFB-NG的Wi-Fi网卡:每个路由器至少需要一张支持监听模式和帧注入的USB Wi-Fi网卡。
  3. USB声卡:路由器通常没有内置声卡,所以每台路由器都需要一个USB声卡。市面上常见的免驱USB声卡即可。
  4. 麦克风和扬声器/耳机:连接到USB声卡上。

3. 软件与配置步骤

步骤一:安装必要的软件包

通过SSH登录到两台OpenWrt路由器,安装以下软件包:

# 更新软件包列表
opkg update

# 1. 安装USB声卡驱动和ALSA音频工具
opkg install kmod-usb-audio alsa-utils

# 2. 安装网络工具 (netcat是必须的)
opkg install netcat

# 3. (推荐) 安装音频编码/解码工具,以降低带宽占用
# Opus是目前最高效的语音编解码器,强烈推荐
opkg install opus-tools 
# 或者使用speex,如果opus-tools不可用
# opkg install speex

步骤二:配置WFB-NG并建立网络链路

你需要先成功配置并运行WFB-NG,确保两台路由器之间的数据链路是通畅的。这里假设你已经完成了这一步。

关键在于,你需要为WFB-NG创建的虚拟网络接口配置IP地址。

  1. 编辑网络配置文件 /etc/config/network
  2. 在文件末尾添加以下内容(两台路由器都要添加,但IP地址不同):

    在路由器A上:

    config interface 'wfb'
        option proto 'static'
        option ifname 'wfb0'  # 假设WFB-NG创建的接口是wfb0
        option ipaddr '192.168.99.1'
        option netmask '255.255.255.0'
    

    在路由器B上:

    config interface 'wfb'
        option proto 'static'
        option ifname 'wfb0' # 假设WFB-NG创建的接口是wfb0
        option ipaddr '192.168.99.2'
        option netmask '255.255.255.0'
    
  3. 应用配置:
    /etc/init.d/network restart
    # 或者
    ifup wfb
    
  4. 验证网络连通性:在路由器A上 ping 192.168.99.2,如果能ping通,说明WFB-NG上的IP网络已经建立成功。

步骤三:测试声卡

  1. 将USB声卡、麦克风和耳机连接到路由器。
  2. 重启路由器或手动加载模块 insmod kmod-usb-audio
  3. 查看声卡设备:

    arecord -l  # 查看录音设备
    aplay -l    # 查看播放设备
    

    记下你的USB声卡的设备号,例如 card 1, device 0,在命令中表示为 hw:1,0

  4. 本地回环测试:测试麦克风和耳机是否工作正常。

    # 从声卡hw:1,0录音,然后直接通过该声卡播放出来
    # -D 指定设备, -f 指定格式, -r 指定采样率, -c 指定声道数
    arecord -D hw:1,0 -f S16_LE -r 8000 -c 1 | aplay -D hw:1,0 -f S16_LE -r 8000 -c 1
    

    对着麦克风说话,如果能从耳机听到自己的声音,说明声卡工作正常。注意: 采样率 -r 8000 (8kHz) 对于语音来说足够了,且能显著降低数据量。


4. 实现语音对讲的方案

这里提供两种方案,从简单原始到高效实用。

方案A:简单粗暴 – 使用 netcatarecord/aplay (未压缩)

这个方案直接传输原始的PCM音频流,延迟最低,但非常消耗带宽。

在路由器A上执行:

# 1. 接收来自B的音频并播放 (后台运行)
nc -l -p 12345 | aplay -D hw:1,0 -f S16_LE -r 8000 -c 1 &

# 2. 从本地录音并发送给B (前台运行)
arecord -D hw:1,0 -f S16_LE -r 8000 -c 1 | nc 192.168.99.2 12345

在路由器B上执行:

# 1. 接收来自A的音频并播放 (后台运行)
nc -l -p 12345 | aplay -D hw:1,0 -f S16_LE -r 8000 -c 1 &

# 2. 从本地录音并发送给A (前台运行)
arecord -D hw:1,0 -f S16_LE -r 8000 -c 1 | nc 192.168.99.1 12345

说明:
* 这是一个全双工的对讲,两边同时运行这些命令。
* nc -l -p 12345 监听在12345端口。
* nc <IP> 12345 连接到对方的12345端口。
* & 让第一个命令在后台运行。
* 缺点: 8000Hz采样率、16位、单声道的原始音频带宽为 8000 * 16 * 1 = 128,000 bps = 128 kbps,这对于无线链路来说可能是一个不小的负担。

方案B:高效推荐 – 使用 opus 编码压缩

这个方案在发送前使用opusenc进行编码,接收后使用opusdec解码,极大地减少了带宽占用,是实现高质量对讲的推荐方法。

脚本化实现

为了方便管理,我们可以创建两个脚本。

在路由器A (192.168.99.1) 上创建脚本 talk.sh:

#!/bin/sh

# 对方的IP地址
REMOTE_IP="192.168.99.2"
# 使用的端口
PORT="12345"
# ALSA设备
AUDIO_DEVICE="hw:1,0"

# 音频参数
FORMAT="S16_LE"
RATE="8000"
CHANNELS="1"

# Opus编码参数 (bitrate 16kbps,对于语音来说质量已经很不错了)
OPUS_BITRATE="16"

echo "启动语音对讲..."
echo "接收端启动..."
# 接收并解码播放 (后台运行)
nc -l -p {PORT} | opusdec --force-rate{RATE} - - | aplay -D {AUDIO_DEVICE} -f{FORMAT} -r {RATE} -c{CHANNELS} &
RECEIVE_PID=!

echo "发送端启动..."
# 录音、编码并发送
arecord -D{AUDIO_DEVICE} -f {FORMAT} -r{RATE} -c {CHANNELS} | opusenc --bitrate{OPUS_BITRATE} - - | nc {REMOTE_IP}{PORT}

# 当发送停止时 (例如Ctrl+C),也杀掉接收进程
kill ${RECEIVE_PID}
echo "语音对讲已停止."

在路由器B (192.168.99.2) 上创建同样的脚本 talk.sh,只需修改一行:

# ... 其他内容和上面一样 ...

# 对方的IP地址
REMOTE_IP="192.168.99.1" # <--- 修改这里

# ... 其他内容和上面一样 ...

使用方法:
1. 将脚本保存到两台路由器上,例如 /root/talk.sh
2. 给予执行权限: chmod +x /root/talk.sh
3. 在两台路由器上同时运行: /root/talk.sh
4. 现在,对着一边的麦克风说话,另一边就能听到。按 Ctrl+C 可以停止对讲。

5. 进阶与优化

  • Push-to-Talk (PTT) 按键通话:可以通过路由器的GPIO连接一个物理按键。编写一个脚本来检测按键状态,按下时才启动arecord | opusenc | nc发送进程,松开时则终止它。接收进程可以一直保持在后台运行。
  • 延迟优化:可以调整aplayarecord的缓冲区参数(例如 -B--buffer-size)来尝试降低延迟,但这需要反复试验。Opus本身延迟极低,主要延迟来自网络和系统缓冲区。
  • 开机自启:可以将运行脚本的命令添加到 /etc/rc.local 中,实现开机自动启动对讲功能。
  • 健壮性:上面的nc方案比较脆弱,如果网络中断重连可能会失败。更健壮的方案是使用专门的VoIP软件,如Mumble。你可以在一台路由器上运行Mumble服务器(murmur),两台都运行命令行Mumble客户端。Mumble专为低延迟通信设计,能更好地处理网络抖动和丢包,但配置会更复杂一些。

总结:方案B(opus + netcat)是在性能、资源占用和实现复杂度之间的一个极佳平衡点,强烈建议你从这个方案开始尝试。它能为你提供一个稳定、清晰、低带宽的实时语音对讲系统。