实时捕获 Windows 系统音频,通过 WebSocket 推送到浏览器播放。无需安装客户端,手机扫码即用。
┌─── Server (Windows) ──────────────────────────┐
│ │
│ WASAPI / FFmpeg 捕获 │
│ │ │
│ ▼ │
│ 静音检测 → 32→16bit 转换 → WebSocket 广播 │
│ │ │
│ HTTP :8080 │
└────────────────────────────────────┼──────────┘
│
┌────────────────────────┼──────────────┐
│ 浏览器 (任意设备) │
│ AudioContext + WebSocket 播放 │
│ 媒体控制 / 码率切换 / 播放状态显示 │
└───────────────────────────────────────┘
- WASAPI Loopback 捕获系统音频(免驱动,原生低延迟)
- FFmpeg 后端(DirectShow / WASAPI / PulseAudio)
- 浏览器 Web 播放器,无需安装任何客户端
- 二维码扫码访问,mDNS 自动发现
- 32-bit float → 16-bit int 实时转换
- 多码率适配(64 ~ 3072 kbps,低码率保持双声道)
- 媒体键远程控制(播放/暂停/上一曲/下一曲)
- SMTC 集成,显示歌曲标题、进度、专辑信息
- 静音检测,跳过无声片段减少带宽
需要 Go 1.24+ 和 CGO 环境(MinGW-w64)。
# 方式一:使用构建脚本(推荐)
.\build.ps1
# 方式二:手动编译
$env:CGO_ENABLED='1'
go build -ldflags="-s -w" -o server.exe ./cmd/server
smtc.dll用于 SMTC 媒体状态查询。如果未安装 Visual Studio Build Tools,构建脚本会跳过 DLL 编译,SMTC 功能降级为不可用,不影响音频传输。
SMTC 默认关闭(
-smtc显式开启):SMTC 由explorer.exe承载,任何 SMTC 交互(创建会话管理器、枚举会话、异步拉取元数据)都可能在部分系统上冻结资源管理器,与查询频率无关。关闭时播放状态回退为 WASAPI 音频能量检测,媒体控制按键(SendInput 虚拟键)不受影响。运行server.exe -smtc可开启。
# 启动服务端(默认 WASAPI + Web 播放器 :8080)
.\server.exe
# 使用 FFmpeg 后端
.\server.exe -capture ffmpeg
# 指定 FFmpeg 设备
.\server.exe -capture ffmpeg -device "立体声混音 (Realtek High Definition Audio)"
# 禁用 Web 播放器
.\server.exe -web ""
# 列出 FFmpeg 可用设备
.\server.exe -list-devices启动后终端会显示二维码,用手机扫码即可在浏览器中播放系统音频。
| 参数 | 默认值 | 说明 |
|---|---|---|
-web |
:8080 |
Web 播放器监听地址(空字符串禁用) |
-capture |
wasapi |
音频捕获后端:wasapi 或 ffmpeg |
-device |
"" |
FFmpeg 音频设备名(留空自动检测) |
-list-devices |
false |
列出 FFmpeg 可用音频设备并退出 |
-buf |
65536 |
音频缓冲区大小(字节) |
-log |
"" |
调试日志类别,逗号分隔:wasapi,ffmpeg,webplayer,media,capture,latency 或 all。启用后进入 debug 模式,只输出 [DEBUG] 行,软件正常日志被静音 |
-log-normal |
false |
debug 模式下一并输出软件正常日志(未启用 -log 时正常日志本就照常输出) |
-log latency 每 2 秒输出一行服务端管线的分段延迟(毫秒,avg/max):
[DEBUG][latency] 内部延迟 avg/max(ms): 总 20.0/21.4 | 采集块 10.0/10.0 | 入队 0.00/0.02 |
转换 0.00/0.00 | 分包 9.9/10.9 | 客户端队列 0.00/0.00 | 写出 0.05/0.55 |
读取间隔 10.0/11.0 | 丢包 ingest=0 client=0 | 样本 100/2000ms
总 是逐包实测的「采样离开声卡 → WebSocket 写出完成」耗时,不含浏览器播放缓冲(那部分见网页上的「缓冲」)。同一份数据也在 GET /stats 的 latency 字段里,不开日志也能随时查。
cmd/server/
main.go # 入口:标志解析、捕获初始化、Web 服务、信号处理
internal/capture/
capture.go # Capture 接口定义
wasapi.go # Windows WASAPI Loopback 实现
ffmpeg.go # FFmpeg 子进程捕获
capture_stub.go # 非 Windows 桩实现
internal/webplayer/
webplayer.go # WebSocket Hub:广播、格式转换、HTTP 服务
player.html # 嵌入式 Web UI(embed.FS)
command.go # 媒体命令解析
mediakeys.go # Windows 媒体键模拟(SendInput)
mediastate.go # 播放状态轮询(SMTC + 音频能量检测)
mediastate_dll.go # SMTC C++/WinRT DLL 查询
mediastate_stub.go # 非 Windows 桩实现
mediaseek.go # 进度条拖动
audiosession.go # Windows 音频会话查询
internal/silence/
silence.go # 静音检测(int16 / float32)
internal/logx/
logx.go # 分类调试日志
build.ps1 # Windows 构建脚本
连接 /ws 端点后:
- 服务端发送 JSON 格式信息:
{"type":"format","sample_rate":48000,"channels":2,"bits_per_sample":16} - 服务端推送二进制 16-bit PCM 音频帧(约 50ms 一批)
- 服务端定期广播播放状态:
{"type":"state","playing":true,"title":"...","position":...,"duration":...} - 客户端可发送命令:
play_pause— 播放/暂停previous/next— 上一曲/下一曲seek_to— 跳转到指定位置(毫秒)set_volume— 设置音量set_bitrate— 切换码率(64/96/128/192/256/384/512/768/1024/1536/2048/3072 kbps)get_state— 请求当前播放状态
| 组件 | 要求 |
|---|---|
| 操作系统 | Windows 10/11(音频捕获) |
| 浏览器 | Chrome / Edge / Firefox / Safari(播放端) |
| Go | 1.24+(仅编译时) |
| CGO | 需要 GCC/Clang(MinGW-w64) |
| FFmpeg | 可选,仅 -capture ffmpeg 时需要 |
| VS Build Tools | 可选,仅编译 smtc.dll 时需要 |
MIT License