在整理线上音乐节、广播节这类活动的音频直播方案时,很多人首先会想到“把视频推流出去”的常规做法。但音频类场景往往比视频更敏感:用户对声音卡顿、延迟、音量忽大忽小的容忍度更低。以 Taka & P.T.P - Voice BLARE FEST 2020 这类线上广播活动为背景,如果要面向大量听众提供稳定、低延迟、高可听性的音频直播,单纯套用视频直播模板往往不够。
这篇文章会从一场“以声音为核心”的线上活动出发,完整拆解音频直播的技术链路:从音频采集、编码、推流,到服务端接收、分发,再到前端低延迟播放。内容会覆盖 FFmpeg、SRS、NGINX-RTMP、HLS、WebRTC 等常用组件,并提供可复制的命令、配置和播放代码。适合正在做直播系统、音频社区、线上电台或远程音乐活动的开发者参考。
1. 背景:音频直播和视频直播的技术差异
1.1 为什么音频直播不能照搬视频直播方案
视频直播已经有非常成熟的方案:推流端使用 OBS 或 FFmpeg,服务端使用 SRS、NGINX-RTMP,播放端使用 HLS、HTTP-FLV 或 WebRTC。但这套方案在纯音频场景中会遇到几个问题。
第一,视频直播默认会为画面分配大量码率,而音频直播往往需要对音质做更精细的控制。如果直接沿用视频编码参数,音频很容易被压成“能听但不清楚”的结果。
第二,视频直播允许 2 到 5 秒左右的缓冲,用户不会觉得太明显。但音频直播一旦出现 1 秒以上延迟,听众在互动环节就会明显感到“滞后”。尤其是广播节、电台直播、在线演唱会这类场景,主持人说话和听众反馈之间的延迟会直接影响体验。
第三,视频直播对网络带宽的要求比较线性,而音频直播对网络抖动、丢包更敏感。声音的连续性一旦被破坏,听感会比画面卡顿更糟糕。
所以,音频直播的技术方案应该围绕“更低的延迟、更稳定的码率、更合理的音量处理”来设计,而不是简单地把视频流程中的音频部分抽出来。
1.2 线上广播节场景的整体技术链路
以 Taka & P.T.P - Voice BLARE FEST 2020 这样的线上广播活动为例,典型的技术链路包含这几个部分:
- 音频采集端:主持人或演出者的麦克风、调音台、声卡,或者直接使用电脑/手机内置麦克风。
- 编码推流端:将采集到的音频编码为 AAC、Opus 或 MP3,推送到流媒体服务器。
- 服务端分发:接收推流,将音频流转成适合不同播放端的格式,例如 RTMP、HLS、HTTP-FLV 或 WebRTC。
- 播放端:听众通过网页、小程序、App 或普通播放器收听。
这里的核心不是“某一个组件”,而是整条链路如何在延迟、音质、稳定性之间取得平衡。
1.3 本文技术范围
本文会重点演示一条可落地的音频直播链路:
- 采集端使用 FFmpeg 读取音频文件、麦克风或声卡输入。
- 编码端输出适合网络传输的音频流。
- 推流端使用 RTMP 或 SRT 协议将音频推送到服务端。
- 服务端使用 SRS 或 NGINX-RTMP 接收并分发。
- 播放端使用 hls.js 播放低延迟 HLS,或使用 WebRTC 实现更低延迟播放。
文中所有命令和配置都以“思路 + 示例”的方式呈现。不同工具版本差异较大,复制到你的项目时,需要根据实际环境做调整。
2. 环境准备与方案选型
2.1 操作系统和依赖工具
音频直播并不挑操作系统,但不同系统的音频采集设备名称、FFmpeg 参数会不一样。本文示例以常见的 Linux 服务器 + 本机测试环境为主,但会同时标注 Windows 和 macOS 的采集方式。
建议准备以下环境:
- 一台 Linux 服务器,用于部署流媒体服务。CentOS 7、Ubuntu 20.04 及以上版本均可。
- 一个本地电脑,安装 FFmpeg,用于推流测试。
- 浏览器,推荐 Chrome 或 Edge,用于测试 WebRTC 播放。
- 如果使用 Docker,可以快速启动 SRS 或 NGINX-RTMP 容器。
FFmpeg 的版本建议使用 4.4 以上版本。新版本对 Opus、SRT、WebRTC 相关协议的支持更好。不过我不建议盲目追求最新版本,关键是当前发行版或 Docker 镜像里的版本能否满足你的编码需求。
2.2 常见流媒体协议选型对比
音频直播中最容易混淆的是协议选择。下面从延迟、适用场景、播放器兼容性三个维度做对比。
| 协议 | 延迟范围 | 适用场景 | 播放器兼容性 |
|---|---|---|---|
| RTMP | 2-5 秒 | 推流端首选,兼容性最好 | Flash 已淘汰,但推流端仍在广泛使用 |
| HTTP-FLV | 1-3 秒 | 网页播放,支持较好 | 需要通过 flv.js 等播放器 |
| HLS | 5-15 秒 | 大规模分发,兼容性极强 | iOS、Android、Web 均可播放 |
| LL-HLS | 1-3 秒 | 低延迟 HLS 播放 | 需要播放器支持,参数较严格 |
| WebRTC | 0.2-1 秒 | 实时互动、语音聊天、在线演出 | 现代浏览器原生支持 |
| SRT | 0.5-2 秒 | 推流和跨国传输,抗丢包好 | 主要用于推流端,播放端需转封装 |
对于推流端,RTMP 依然是最稳妥的选择。对于播放端,如果想要的是“即点即播”的大规模分发,HLS 最通用;如果要做强互动或者追求极低延迟,WebRTC 更合适。
2.3 本文最终选型
为了让示例覆盖更多场景,本文采用双链路方案:
- 推流端:FFmpeg 将音频以 RTMP 协议推送到 SRS。
- 分发端:SRS 同时输出 HLS 和 HTTP-FLV。
- 低延迟播放:通过 SRS 的 WebRTC 能力,输出 RTC 流。
这种组合的好处是,一套推流源可以服务多种播放端。普通听众走 HLS,互动用户走 WebRTC,互不影响。
3. 音频采集与编码基础
3.1 采样率、位深、声道的基本概念
在配置 FFmpeg 之前,需要先明确几个概念。
采样率表示每秒采集声音样本的次数,单位是 Hz。常见值有 44100 Hz(CD 音质)、48000 Hz(视频制作常用)。音频直播建议使用 48000 Hz,因为它和视频帧率更容易对齐,而且在很多声卡上表现更稳定。
位深表示每个采样点用多少 bit 来表示。常见值有 16 bit 和 24 bit。直播场景一般用 16 bit 足够了,但如果是音乐现场,24 bit 能保留更多动态范围。
声道数则决定了是单声道、双声道还是多声道。线上语言类直播用单声道或双声道都可以。音乐演出建议保留双声道,但不要盲目使用 5.1 声道,因为绝大多数听众的终端设备无法还原。
3.2 常见音频编码格式选择
音频直播中,编码格式直接决定了音质和码率。
- AAC:兼容性最好,iOS 和 Android 都支持。常见码率 128 kbps 到 256 kbps,适合大多数网络环境。
- Opus:延迟更低,音质更好,在相同码率下优于 AAC。但旧设备兼容性稍差。WebRTC 场景几乎都使用 Opus。
- MP3:兼容性极强,但编码效率相对较低。适合需要兼容老设备的场景。
在 FFmpeg 推流时,一般推荐 AAC 作为 RTMP/HLS 的音频编码格式,Opus 作为 WebRTC / SRT 的音频编码格式。这样可以在兼容性和音质之间取得平衡。
3.3 FFmpeg 采集本机音频的常见命令
先看一个最简单的本地音频采集示例。下面的命令假设你在本地有一个音频文件,并希望把它作为直播音频源。
ffmpeg -re -i local_audio.mp3 -c:a aac -b:a 128k -ar 48000 -ac 2 -f flv rtmp://127.0.0.1:1935/live/audio解释一下参数:
-re:按文件原始速度读取,避免推流速度过快。-i local_audio.mp3:输入音频文件。-c:a aac:音频编码器设置为 AAC。-b:a 128k:音频码率设置为 128 kbps。-ar 48000:重置采样率为 48000 Hz。-ac 2:设置为双声道。-f flv:输出封装格式为 FLV,用于 RTMP 推流。
如果你是直接采集麦克风或声卡,则需要处理系统设备名。不同系统差异很大,这里给出三种常见写法。
Windows 下使用 dshow 设备采集:
ffmpeg -f dshow -i audio="麦克风" -c:a aac -b:a 128k -ar 48000 -ac 2 -f flv rtmp://127.0.0.1:1935/live/audioLinux 下使用 ALSA 设备采集:
ffmpeg -f alsa -i default -c:a aac -b:a 128k -ar 48000 -ac 2 -f flv rtmp://127.0.0.1:1935/live/audiomacOS 下使用 avfoundation 设备采集:
ffmpeg -f avfoundation -i ":0" -c:a aac -b:a 128k -ar 48000 -ac 2 -f flv rtmp://127.0.0.1:1935/live/audio注意,"麦克风"、":0"这些设备名需要根据你的机器实际环境修改。可以先运行ffmpeg -devices查看可用设备。
这里最重要的是理解:FFmpeg 采集音频后,会重新编码成直播流所需的格式。因此,即使输入设备或文件格式不同,推流端的参数都可以保持一致。
4. 用 FFmpeg 实现音频推流
4.1 准备测试音频内容
在正式测试前,建议准备一段 30 秒以上的音频文件。如果是一个线上广播活动的测试,可以准备一段主持人口播、一首歌的剪辑,或者直接生成一段正弦波用于链路连通性测试。
生成测试音频可以用 FFmpeg 的 sine 源:
ffmpeg -f lavfi -i "sine=frequency=440:duration=30" -c:a aac -b:a 128k test_audio.aac这条命令会生成一个 30 秒、频率为 440 Hz 的测试音频,方便判断链路是否通。注意,频率为 440 Hz 的声音听起来像持续的“嘟”声,不要误以为系统出了问题。
4.2 推流到 RTMP 服务
RTMP 是当前推流端最常用的协议。它虽然老旧,但兼容性极好,几乎所有流媒体服务都支持接收 RTMP 推流。
下面的命令将音频文件推送到 RTMP 地址:
ffmpeg -re -i test_audio.aac -c copy -f flv rtmp://127.0.0.1:1935/live/audio这里使用了-c copy,意思是直接复制编码后的音频数据,不再转码。因为test_audio.aac已经是 AAC 格式,RTMP 可以直接封装。如果是外部文件,则建议使用转码命令:
ffmpeg -re -i local_music.mp3 -c:a aac -b:a 128k -ar 44100 -ac 2 -f flv rtmp://127.0.0.1:1935/live/audio这里将码率设为 128 kbps,采样率设为 44100 Hz。不同活动对音质要求不同。语言类节目 96 kbps 也够用,音乐类节目建议 128 kbps 以上。
4.3 推流到 SRT 服务
SRT 协议适合网络不稳定的场景,尤其是跨区域推流。它具备自动重传和丢包恢复能力,比 RTMP 更抗抖动。
FFmpeg 推流到 SRT 的命令如下:
ffmpeg -re -i local_music.mp3 -c:a aac -b:a 128k -ar 48000 -ac 2 -f mpegts "srt://127.0.0.1:9000?mode=caller&latency=2000000"参数解释:
-f mpegts:SRT 通常使用 MPEG-TS 封装。mode=caller:当前 FFmpeg 作为发起连接的一方。latency=2000000:设置最大延迟为 2000000 微秒,也就是 2 秒。你可以根据网络情况调低或调高。
SRT 适合作为“推流侧”的增强方案。如果活动有多地分会场,主播和主会场之间网络不稳定,SRT 往往比 RTMP 更可靠。
4.4 生成低延迟 HLS 流
如果服务端不负责转码,你也可以用 FFmpeg 单独生成 HLS 分片。这种方法适合小规模活动或测试环境。
ffmpeg -i local_music.mp3 -c:a aac -b:a 128k -hls_time 2 -hls_list_size 6 -hls_flags delete_segments output.m3u8解释关键参数:
-hls_time 2:每个分片时长 2 秒。-hls_list_size 6:播放列表最多保留 6 个分片。-hls_flags delete_segments:删除已经过期的分片,避免磁盘占用膨胀。
这种方式的优点是简单,缺点是扩展性差。如果同时有几千人观看,建议还是使用 SRS 或 NGINX-RTMP 做服务端分发,而不是让 FFmpeg 直接输出 HLS 文件。
5. 服务端接收与分发
5.1 使用 SRS 搭建基础流媒体服务
SRS 是一个开源的流媒体服务器,支持 RTMP、HLS、HTTP-FLV、WebRTC 等多种协议。在音频直播场景中,SRS 可以做到“一路推流,多路分发”。
使用 Docker 启动 SRS 是最快的测试方式:
docker run --rm -p 1935:1935 -p 1985:1985 -p 8080:8080 -p 8000:8000/udp -p 8000:8000/tcp \ registry.cn-hangzhou.aliyuncs.com/ossrs/srs:5 \ ./objs/srs -c conf/srs.conf这条命令会映射 RTMP 端口 1935、HTTP API 端口 1985、HTTP 服务端口 8080,以及 WebRTC 使用的 8000 端口。不同镜像仓库和标签可能不同,如果你无法访问指定镜像,可以换成 Docker Hub 上的官方镜像。
启动后,SRS 默认会开启 RTMP 和 HLS。推流地址依然可以使用:
rtmp://127.0.0.1:1935/live/audio此时,可以通过以下地址播放:
- RTMP 播放:
rtmp://127.0.0.1:1935/live/audio - HLS 播放:
http://127.0.0.1:8080/live/audio.m3u8 - HTTP-FLV 播放:
http://127.0.0.1:8080/live/audio.flv
这些地址中的live是应用名,audio是流名。实际项目中可以把流名改为频道 ID 或节目编号。
5.2 SRS 的 WebRTC 低延迟播放配置
如果希望使用 WebRTC 播放音频,需要额外修改 SRS 配置。下面是一份简化的配置示例,字段可能随 SRS 版本变化,请以官方文档为准:
listen 1935; max_connections 1000; daemon off; srs_log_tank console; http_api { enabled on; listen 1985; } http_server { enabled on; listen 8080; dir ./objs/nginx/html; } rtmp_server { enabled on; listen 1935; chunk_size 4096; } http_hooks { enabled on; on_play http://127.0.0.1:8080/api/v1/streams; } webrtc_server { enabled on; listen 8000; candidate $CANDIDATE; }这份配置说明以下几点:
candidate是 WebRTC 连接时告诉播放端“可以向哪个地址发送数据”的关键配置。如果是公网服务器,需要设置为服务器公网 IP;如果是本机测试,可以设置为127.0.0.1。- WebRTC 播放时,拉流地址通常不是普通 HTTP 地址,而是类似
webrtc://127.0.0.1/live/audio这样的地址。 - 由于 WebRTC 对 UDP 端口依赖较高,服务器安全组或防火墙需要放行 UDP 8000 端口。
SRS 的 WebRTC 配置在不同版本中差异较大。如果你使用的是 SRS 5.0 以上版本,配置方式会和旧版不同。建议先用 Docker 跑通默认配置,再根据日志调整参数。
5.3 使用 NGINX-RTMP 作为备选方案
如果你的服务器已经部署了 Nginx,并且不希望引入额外服务,可以考虑使用 NGINX-RTMP 模块。这里给出一个最简配置:
rtmp { server { listen 1935; chunk_size 4096; application live { live on; record off; } } } http { server { listen 8080; location /live { types { application/vnd.apple.mpegurl m3u8; video/mp2t ts; } alias /tmp/hls; } } }配置完成后,需要创建 HLS 分片目录,并给 Nginx 进程写入权限:
mkdir -p /tmp/hls chmod 755 /tmp/hlsNGINX-RTMP 的优势是配置简单,和 Nginx 生态结合紧密。缺点是 WebRTC 支持较弱,如果你想主打低延迟互动,SRS 会更合适。
6. 播放端接入与低延迟调优
6.1 HLS 播放页面示例
HLS 的兼容性最强,适合大规模分发。下面是一个最简单的 HTML 播放器示例,使用 hls.js 在浏览器中播放 HLS 音频流。
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>音频直播 HLS 播放器</title> <script src="https://cdn.jsdelivr.net/npm/hls.js@1.5.7"></script> </head> <body> <h3>音频直播测试</h3> <audio id="audio" controls autoplay></audio> <script> const audio = document.getElementById('audio'); const streamUrl = 'http://127.0.0.1:8080/live/audio.m3u8'; if (Hls.isSupported()) { const hls = new Hls({ lowLatencyMode: true, maxBufferLength: 5 }); hls.loadSource(streamUrl); hls.attachMedia(audio); hls.on(Hls.Events.MANIFEST_PARSED, function () { audio.play(); }); } else if (audio.canPlayType('application/vnd.apple.mpegurl')) { audio.src = streamUrl; audio.addEventListener('loadedmetadata', function () { audio.play(); }); } </script> </body> </html>这里的lowLatencyMode: true和maxBufferLength: 5是降低播放延迟的关键。前者让 hls.js 尽量使用低延迟模式,后者限制最大缓冲长度为 5 秒,避免播放器因为缓冲太多而越播越慢。
6.2 WebRTC 音频播放思路
WebRTC 的播放需要经过信令协商,不能像 HLS 一样直接用一个audio标签播放。SRS 提供了 WebRTC 播放能力的 HTTP API 和 JavaScript SDK。
实际项目中,你可以按照如下流程实现:
- 从播放端向服务端请求 WebRTC 拉流地址。
- 服务端返回 SDP 应答。
- 播放端拿到 SDP 后通过 RTCPeerConnection 建立连接。
- 将远端音频轨道绑定到
<audio>标签。
由于不同版本 SDK 差异较大,这里不贴死一个版本的代码。建议参考 SRS 官方提供的 WebRTC 播放示例。整体思路是:播放端不是直接请求流媒体地址,而是先通过信令接口完成协商,再建立对等连接。
6.3 延迟优化参数参考
音频直播的延迟来自采集、编码、推流、服务端分发、播放缓冲多个环节。下面是一个优化方向表:
| 优化点 | 建议值或做法 | 注意事项 |
|---|---|---|
| 音频采样率 | 48000 Hz | 避免多次采样率转换 |
| 音频码率 | 96-192 kbps | 根据场景和带宽调整 |
| GOP / 分片时长 | HLS 2 秒 | 分片越短延迟越低,但服务端压力越大 |
| 播放端缓冲 | 3-5 秒 | 缓冲越大越稳定,但延迟越高 |
| 服务端队列 | 根据并发调整 | 不要设置过大的 GOP 缓存 |
| 网络协议 | WebRTC 用于互动 | HLS 用于大规模广播 |
需要注意的是,低延迟和高稳定性是矛盾关系。不要为了追求 300ms 延迟而牺牲所有客户端的稳定性。建议在测试环境中做多组对比,找出当前网络质量下的最优值。
7. 常见问题与排查思路
7.1 推流后播放端没有声音
| 问题现象 | 常见原因 | 解决思路 |
|---|---|---|
| 推流命令正常,但播放端无声音 | 音频设备静音或输入源为空 | 检查播放器音量、系统音量,确认 FFmpeg 日志中有音频流数据 |
| 只有画面没有声音 | 音频编码格式与播放器不兼容 | 统一使用 AAC 音频编码,检查播放器是否支持当前封装格式 |
| 播放端延迟越来越大 | 播放缓冲设置过大 | 调小播放器缓冲,检查服务端 GOP 缓存 |
排查时,先看 FFmpeg 推流日志里是否有类似Audio: aac的输出信息。如果没有,说明输入源本身没有采集到声音。可以在 FFmpeg 命令中去掉推流地址,先输出到本地文件,验证输入源是否正常。
ffmpeg -f alsa -i default -t 10 output.wav如果本地文件正常,再排查推流和服务端配置。
7.2 WebRTC 播放失败或连接超时
| 问题现象 | 常见原因 | 解决思路 |
|---|---|---|
| 浏览器无法播放 WebRTC 流 | 服务器端口未放行 | 检查 UDP/TCP 8000 端口是否开放 |
| 连接超时 | candidate 地址配置错误 | 将 candidate 设置为可访问的公网 IP |
| 能连接但无声音 | 音频编解码器协商失败 | 确认推流端编码格式支持 Opus 或请服务端转码 |
WebRTC 问题大多和网络环境相关。建议先用官方 Demo 测试服务器是否正常,再接入业务代码。
7.3 HLS 播放列表 404 或持续加载
HLS 出现 404,通常是分片文件路径和播放列表路径不一致,或者服务端没有写入权限。
检查步骤:
- 确认 m3u8 文件是否生成。
- 确认 ts 分片文件是否在同一个目录。
- 确认 Nginx 或 SRS 的 HTTP 目录映射是否正确。
- 如果磁盘满了,也会出现分片无法写入的情况。
8. 最佳实践与工程建议
8.1 音频源质量和音量标准化
音频直播最怕的是“源不好”。在实际广播活动中,建议在采集端接入调音台或声卡,避免直接使用电脑内置麦克风。推流前要统一响度,避免节目之间声音忽大忽小。
FFmpeg 可以使用 loudnorm 滤镜做响度标准化:
ffmpeg -i input.wav -af loudnorm=I=-16:TP=-1.5:LRA=11 -c:a aac -b:a 128k output.aac这里的I=-16表示目标响度为 -16 LUFS,属于比较适合网络直播的值。实际参数可以根据活动风格调整。需要提醒的是,响度处理会增加一定的转码延迟,如果对低延迟要求极高,可以在采集端或调音台先做好音量控制,不在推流端做过重处理。
8.2 推流安全与鉴权
不要把推流地址和播放地址直接暴露在公网。实际项目中至少需要做两件事。
第一,推流鉴权。SRS 可以通过回调接口或 HTTP 回调校验推流密钥。也就是说,推流端必须携带正确 token,服务端才允许写入。
第二,播放防盗链。HLS 播放地址建议加上时间戳签名,或者限制 Referer。对于 WebRTC 播放,更推荐通过业务后端动态签发临时 SDP 请求权限,而不是把固定流地址内置在客户端。
8.3 断流自动重推与监控
线上活动期间,推流端可能因为网络抖动、电脑休眠、声卡掉线等原因中断。建议在推流端写一个简单的守护脚本,检测 FFmpeg 进程是否存活,如果退出则自动重启。
以下是一个极简的 Shell 示例思路:
#!/bin/bash while true; do ffmpeg -re -i local_music.mp3 \ -c:a aac -b:a 128k -ar 48000 -ac 2 \ -f flv rtmp://127.0.0.1:1935/live/audio echo "推流进程退出,5秒后重启..." sleep 5 done这个脚本只适合测试。生产环境建议使用 systemd 或 supervisor 管理推流进程,并加入日志和告警。
8.4 生产环境配置建议
在生产环境发布前,建议按下面清单检查:
- 推流地址和播放地址是否做了鉴权。
- 防火墙是否只放行必要端口。
- 磁盘分片目录是否有独立空间,并设置了过期清理。
- 音频编码是否统一为 AAC 或 Opus,避免播放端兼容问题。
- 日志是否收集到统一平台,方便排查推流中断。
- 是否在低峰期做过压测,确认服务器并发能力。
音频直播的容错比视频直播更苛刻,因为“听不清”比“看不清”更容易造成用户流失。上线前,一定要用多个播放端、多种网络环境实测。
8.5 安全边界提醒
如果你是在业务系统中集成推流能力,涉及用户上传音频、麦克风采集、直播发布等功能,需要遵循最小权限原则。用户必须明确授权才能采集音频;服务端要限制推流 IP、推流时长和并发路数;不要允许任意用户推流到公共流名。
另外,涉及用户生成内容时,建议先录制或转存到安全存储,再决定是否公开分发。不要直接把用户原始音频流无限期暴露在公网。
9. 总结与下一步学习
这篇文章围绕线上广播活动的音频直播场景,梳理了从 FFmpeg 采集推流、SRS/NGINX-RTMP 服务端分发,到 HLS/WebRTC 播放的完整链路。你现在应该能理解音频直播和视频直播的核心差异,也知道如何通过编码参数、分发协议和播放缓冲来控制延迟和稳定性。
下一步可以分三个方向继续深入:
- 如果你侧重推流端,可以重点学习 FFmpeg 的滤镜系统和 SRT 协议,提升复杂网络下的推流稳定性。
- 如果你侧重服务端,可以深入学习 SRS 的 WebRTC 网关、鉴权回调、集群分发和监控指标。
- 如果你侧重播放端,可以研究 WebRTC 信令实现、低延迟 HLS 的播放器参数,以及移动端的音频焦点处理。
音频直播并不复杂,但它需要开发者在细节上更有耐心。建议你先用 FFmpeg 推一段本地音频到 SRS,再用浏览器分别通过 HLS 和 WebRTC 播放,亲手感受延迟差异。搭好这条链路后,再把鉴权、监控、响度处理等工程能力逐步加上去,就能支撑一场真正面向听众的线上广播活动了。