基于 MediaMTX 的微信小程序 & Web 实时音视频实操方案

我现在有一个微信小程序,里面有个实时音视频功能,目前用的是腾讯云的。考虑到成本问题,我想自己基于开源的livekit 搭建一个代替腾讯云的实时音视频。请问方案是否可行,如果可行,帮我写出详细的落地方案。

很现实的一个需求!毕竟TX实时音视频的费用是越来越贵!!
向 ChatGPT 提问的时候,我只知道一个 Livekit,根本不知道 MediaMTX

实际使用实时音视频场景 主要是医生PC端,医生小程序端,患者小程序端。可以继续沿用live-pusher 和live-player。给出详细的实施方案。目前使用的是腾讯的实时音视频 trtc的方案 https://cloud.tencent.com/document/product/647/116548

二、ChatGPT 提供的几种方案对比

方案 A:全部使用 MediaMTX(推荐)

医生端 (Web)  ---> WebRTC 推流 ---> MediaMTX ---> RTMP/FLV ---> 小程序
   ↑                                                   ↑
  FLV 播放 <--- MediaMTX <--- RTMP 推流 <--- 小程序

优点:

  • MediaMTX 原生支持 WebRTC → RTMP/FLV 转换
  • 配置简单,一个服务器搞定
  • 不需要 LiveKit

缺点:

  • 小程序只能使用 RTMP/FLV,延迟略高
  • 不支持复杂多房间逻辑

方案 B:全部使用 LiveKit(最佳体验)

医生端 (Web)  ---> WebRTC ---> LiveKit <---> WebRTC ---> 小程序
   ↑                                                  ↑
 WebRTC 接收 <--- LiveKit <---> WebRTC <--- 小程序

优点:

  • 端到端低延迟,体验最好
  • 多人会议和房间管理方便

缺点:

  • 小程序无法直接使用 live-pusher mode="RTC" 连接
  • 需要 TRTC SDK 或自研 WebRTC adapter
  • 实现复杂,生产环境门槛高

方案 C:简化 RTMP + FFmpeg(快速验证)

医生端 (Web) ---> WebM ---> 后端 FFmpeg ---> RTMP ---> MediaMTX ---> FLV ---> 小程序
   ↑                                                             ↑
  FLV 播放 <--- MediaMTX <--- RTMP <--- live-pusher (小程序)

优点:

  • 实现简单,可快速验证
  • 利用现有 MediaMTX,无需 LiveKit

缺点:

  • 后端依赖 FFmpeg
  • 延迟较高(2-5 秒)

三、本地快速验证步骤(方案 C)

  1. 部署 MediaMTX

    docker-compose up -d
    
    • 暴露端口:7880 (WebRTC/HTTP),1935 (RTMP),8889 (FLV)
  2. 启动 Node 后端
    提供 RTMP 推流和 FLV 播放地址

    cd server
    npm install
    node server.js
    

    如果提示端口被占

    netstat -ano | findstr ":<端口号>"
    

    结束 PID 进程

    taskkill /pid <PID号> /f
    
  3. 启动医生端 React 前端

    cd web-doctor
    npm install
    npm run dev
    
    • 浏览器访问 http://localhost:5173
    • 通过 WebRTC 推流到 MediaMTX
    • 使用 flv.js 播放患者端 RTMP 推来的流
  4. 小程序患者端

    • 使用 live-pusher 推 RTMP 到 MediaMTX
    • 使用 live-player 播 FLV

四、实操

本地进行方案 调试过程,开始想着是方案C 最后走到了 A。

初始代码是ChatGPT直接生成的一个zip包,这点很赞,不像DeepSeek,给的链接或是包都是虚构的。。。

文件结构

livekit-demo/
├── docker-compose.yml        # 启动 LiveKit + MediaMTX
├── server/
│   ├── package.json
│   ├── server.js             # Node 后端
└── miniprogram/
    ├── app.js
    ├── app.json
    ├── pages/
    │   └── index/
    │       ├── index.wxml
    │       ├── index.js
    │       └── index.wxss

docker-compose.yml (放在 livekit-demo 根目录)

version: '3.8'

services:
  livekit:
    image: livekit/livekit-server
    container_name: livekit
    ports:
      - "7880:7880"
      - "7881:7881/tcp"
      - "7882:7882/udp"
    volumes:
      - ./livekit.yaml:/livekit.yaml
    command: --config /livekit.yaml

  mediamtx:
    image: bluenviron/mediamtx:latest
    container_name: mediamtx
    ports:
      - "1935:1935"    # RTMP
      - "8554:8554"    # RTSP
      - "8889:8889"    # WebRTC/HLS
    restart: always

调试过程,全程使用 claude !

docker-compose down
docker-compose up -d
docker-compose restart mediamtx
docker logs -f mediamtx
docker logs mediamtx --tail 50

web医生端能显示来自微信小程序端的视频,但是微信小程序端无法看到web端的画面。。

在这里插入图片描述

在这里插入图片描述
投喂日志,docker logs mediamtx

在这里插入图片描述

在这里插入图片描述
flv 有两种格式 h265 和 h264 注意所选播放器组件要支持 h265

live-player的坑
live-player只支持 flv 与 rtmp,不支持 fMp4 格式的 HLS

双向视频正常了,手机端听不到声音!

docker logs mediamtx 2>&1 | Select-String "opus|Opus|RTMP.*doctor" -Context 1

在这里插入图片描述

在这里插入图片描述

依旧没有声音

docker logs mediamtx --tail 30 | Select-String "doctorStream_aac"

终于在 context 用光之前,画面声音都有了

在这里插入图片描述
在这里插入图片描述
试了一下,延迟太严重了!
在这里插入图片描述


五、结果复盘

在本次验证中,我们尝试用 自建 MediaMTX + FFmpeg + 小程序 live-player 的方式,替代腾讯云 TRTC,实现“医生端(Web)↔患者端(小程序)”的实时音视频通信。

架构上:

医生端 (Web) → WebRTC 推流 → FFmpeg 转 RTMP/HLS → MediaMTX → live-player 播放
患者端 (小程序) → live-pusher 推 RTMP → MediaMTX → flv.js 播放

该方案在功能上完全可行,但在延迟测试中出现 3–7 秒延迟,难以满足实时问诊场景的要求。以下是延迟来源的详细拆解与优化建议。


延迟来源分析

1️⃣ HLS 协议延迟(约 2–4 秒)

  • HLS 的基本原理是将流切片(默认 1 秒/片)后按顺序播放。

  • 常见默认配置:

    3个分片 × 1秒/分片 = 3秒基础延迟
    
  • 小程序 live-player 在播放 HLS 流时,会有额外的缓冲保护,进一步增加 0.5~1 秒延迟。

📉 小结:HLS 设计目标是稳定播放而非低延迟,天生有 2~4 秒延迟


2️⃣ FFmpeg 转码延迟(约 0.5–1 秒)

  • 当前实现中使用 FFmpeg 转码:

    • 视频:VP8/WebM → H.264/FLV
    • 音频:Opus → AAC
  • 转码会产生缓冲 + 编码延迟(特别是音频 AAC)。

  • -re 参数使 FFmpeg 按实时速度推流,本身会限制处理速度

📉 小结:转码是“兼容性补丁”,但引入了约 0.5–1 秒延迟


3️⃣ RTMP 播放延迟(约 1–2 秒)

  • 微信小程序端的 live-player RTMP 模式在默认设置下会自动缓冲以保证流畅度。
  • RTMP 本身也有 TCP 传输 + 首屏缓存延迟。
  • 如果未启用“实时模式”,延迟可轻易到 2 秒以上。

📉 小结:RTMP 协议偏向“低延迟点播”而非“超低延迟实时通信”。


🚧 总延迟汇总

阶段协议 / 模块延迟范围
医生推流 → FFmpegWebRTC + 转码0.5 – 1s
FFmpeg → MediaMTXRTMP / HLS 输出2 – 4s
MediaMTX → 小程序RTMP / HLS 播放1 – 2s
总计3 – 7 秒

⚠️ 在医疗问诊场景中,3 秒以上延迟会严重影响交互体验(打断、错位、听觉回声等)。


优化方向

优化方向目标方法
改用 WebRTC 全链路延迟 < 500ms医生端 → WebRTC → MediaMTX → live-player (RTC)
去除 FFmpeg 转码减少 1 秒延迟让浏览器端直接推送 H.264 + AAC(MediaMTX 可直接收)
启用低延迟 RTMP延迟 < 2 秒调整 live-player 播放模式为 mode="live",禁用缓存
优化 HLS 参数延迟降至 1.5 秒使用 LHLS (Low-Latency HLS),分片 0.5s,预加载片段
启用 MediaMTX 内置 WebRTC无需转码直接 WebRTC ↔ WebRTC 传输,最简链路

⭐️ ChatGPT给出的改进方向,优化后小程序端又没有声音了

医生端使用浏览器原生 getUserMedia + RTCPeerConnection 推 WebRTC。

MediaMTX 自动中转 WebRTC → RTMP → FLV。

小程序端仍可用 RTMP 或 HLS 播放,后续可平滑升级到 WebRTC。

该方案无需 FFmpeg,延迟可降至 1 秒以内,并保持架构简洁、运维成本低。

⭐️关键兼容性问题:WebRTC 仅支持 Opus 音频,导致小程序端无声

🎧 问题现象

医生端使用浏览器(WebRTC)推流,患者端小程序使用 live-player 播放时,视频正常但无声音

🧩 原因分析

WebRTC 与 RTMP/HLS 的音频编码格式存在根本差异:

链路协议默认音频编码支持格式
浏览器 (WebRTC)RTPOpusOpus、G.711、(部分支持 PCM)
RTMP / FLV / HLSRTMP / FLV / HLSAACAAC、MP3
微信小程序live-playerAAC仅支持 AAC(不支持 Opus)

因此,当浏览器推送 WebRTC(Opus)流时,即使视频通过转封装进入 RTMP/HLS,小程序端也无法解码音频,因为它只认 AAC。

这意味着:

  • MediaMTX 无法直接将 Opus 透传给 RTMP/HLS 客户端
  • FFmpeg 转码是必需的环节(将 Opus → AAC)

🔧 解决方案方向
方案原理优点缺点
① FFmpeg 转码 (现有方式)WebRTC → FFmpeg 转 AAC → RTMP小程序可直接播放延迟 +1s,资源消耗高
② 浏览器端 AAC 编码Web Audio API → MediaRecorder(AAC) → 推流可绕过转码需实验特性,仅部分浏览器支持
③ MediaMTX 内置转码MediaMTX 使用 ffmpeg filter 将 Opus → AAC整合度高,自动化功能新,需编译带 ffmpeg
④ 改用全 WebRTC 链路医生端 WebRTC → MediaMTX (WebRTC) → 小程序 WebRTC 播放端到端低延迟,无转码小程序不支持 WebRTC,需二次开发或使用 WebRTC 网关

⭐️结论,还是绕不开 ffmpeg~

在这里插入图片描述

⭐️这版延迟好些了,起码音画同步了。。

demo效果!

WEB端:
在这里插入图片描述
小程序端:

在这里插入图片描述

模型消耗情况

在这里插入图片描述

⭐️最终方案,没有用到 livekit,属于改良版的方案 A**

在这里插入图片描述

六、进一步优化方向 (Claude)

1️⃣ 降低延迟(患者→医生) ⚠️ 当前最大瓶颈

当前问题:

  • 患者→医生:1.3-1.5秒(HLS 固有延迟)
  • 医生→患者:0.8-1.0秒(已优化到位)

优化思路:

方案 1.1:尝试 LL-HLS(低延迟 HLS)

mediamtx.yml

hlsVariant: lowLatency # 或 fmp4
hlsSegmentDuration: 200ms
hlsPartDuration: 200ms
预期延迟:降至 0.5-0.8秒
风险:浏览器兼容性,需要 hls.js 特殊配置

方案 1.2:换用 MSE + WebSocket 推流

小程序 RTMP → MediaMTX → WebSocket → 浏览器 MSE 播放
预期延迟:降至 0.3-0.5秒
代价:需要中间服务器转换,架构变复杂

方案 1.3:小程序接入 WebRTC SDK(终极方案)
  • 使用腾讯 TRTC SDK / 声网 SDK
  • 双端都用 WebRTC,延迟 < 500ms
    代价:回到付费方案(但比纯 TRTC 便宜,可自建信令服务器)

2️⃣ 生产环境部署优化

2.1 HTTPS + 域名

当前:http://192.168.124.5:8889
目标:https://video.yourdomain.com
必要性:小程序正式版必须 HTTPS

2.2 推流认证

mediamtx.yml

paths:
doctorStream:
publishUser: doctor
publishPass: “strong_password”

目的:防止非法推流
2.3 录制功能

paths:
doctorStream:
record: true
recordPath: ./recordings/%path/%Y-%m-%d_%H-%M-%S.mp4
用途:医疗合规、纠纷追溯


3️⃣ 移除 FFmpeg 转码(架构简化)

核心矛盾:

浏览器只支持 Opus ❌ ─────┐
FFmpeg 转码 (CPU 消耗)
小程序只支持 AAC ❌ ─────┘

优化思路:

方案 3.1:医生端改用原生 App
  • React Native / Flutter App
  • 可以推 AAC 音频的 RTMP
  • 无需 FFmpeg 转码
方案 3.2:小程序端改用 uni-app + nvue
  • 接入 WebRTC 插件
  • 支持 Opus 音频
  • 无需 FFmpeg 转码

收益:

  • 去掉 FFmpeg 容器
  • 降低服务器 CPU 占用 50%+
  • 延迟再降 150ms

4️⃣ 性能优化

4.1 FFmpeg 硬件加速

transcode.sh

ffmpeg -hwaccel vaapi
-hwaccel_device /dev/dri/renderD128

收益:CPU 占用从 80% → 20%
4.2 多实例负载均衡
               ┌─> MediaMTX 实例1

Nginx 负载均衡 ──┼─> MediaMTX 实例2
└─> MediaMTX 实例3
适用:并发 > 20 路

4.3 CDN 加速

用户 → CDN → MediaMTX HLS
用途:全国跨地域播放加速


5️⃣ 监控和运维

5.1 添加监控

mediamtx.yml

metrics: true
metricsAddress: :9998
配合 Prometheus + Grafana

5.2 自动重启策略

docker-compose.yml

restart: unless-stopped
healthcheck:
test: [“CMD”, “curl”, “-f”, “http://localhost:9997”]

5.3 日志收集
 docker logs mediamtx | grep ERROR

配合 ELK / Loki


📊 优化优先级
优先级方向成本收益推荐度
🔥 P0HTTPS + 域名生产必须⭐⭐⭐⭐⭐
🔥 P0推流认证安全必须⭐⭐⭐⭐⭐
🚀 P1LL-HLS 降延迟-500ms 延迟⭐⭐⭐⭐
🚀 P1录制功能合规需求⭐⭐⭐⭐
💡 P2FFmpeg 硬件加速-60% CPU⭐⭐⭐
💡 P2监控告警运维友好⭐⭐⭐
🎯 P3小程序 WebRTC< 500ms⭐⭐
🎯 P3移除 FFmpeg架构简化⭐⭐

💡 建议路线

近期(1-2周)
  1. ✅ 部署到龙蜥服务器(已准备好脚本)
  2. 配置 HTTPS + 域名
  3. 启用推流认证
  4. 小范围测试(5-10 路并发)
中期(1个月)
  1. 尝试 LL-HLS 降低延迟
  2. 添加录制功能
  3. 配置监控告警
  4. 压力测试(50 路并发)
长期(3个月+)
  1. 评估是否需要 WebRTC 双端(看业务延迟要求)
  2. FFmpeg 硬件加速 / 移除 FFmpeg
  3. 多实例 + 负载均衡(如果量大)

🎯 核心建议

当前方案已经很优秀:
  • ✅ 成本低(¥700/月)
  • ✅ 架构简洁
  • ✅ 延迟可接受(~1秒)
  • ✅ 功能完整(双向音视频)
如果要进一步优化,建议按优先级:
  1. 先上生产(HTTPS + 认证 + 录制)
  2. 再降延迟(LL-HLS / WebRTC)
  3. 后优化性能(硬件加速 / 负载均衡)
不用追求完美,够用就好,关键是快速上线验证商业价值! 🚀

🔍LiveKit vs 当前方案对比

LiveKit 的定位

LiveKit 是一个 WebRTC SFU (Selective Forwarding Unit) 服务器,专为:
  • 多人视频会议(Zoom/Teams 类应用)
  • 复杂房间管理
  • 双向 WebRTC 通信
  • 低延迟(< 500ms)
你当前方案的定位
  • 1对1 远程医疗
  • 医生端用浏览器(WebRTC 推流)
  • 患者端用小程序(RTMP 推流)
  • 可接受 ~1秒延迟

❌ 为什么不需要 LiveKit?

1. 小程序不支持 WebRTC 标准协议

LiveKit 核心能力:WebRTC ↔ WebRTC

小程序能力:只支持 RTMP/TRTC 私有协议

结果:LiveKit 帮不上忙 ❌
事实:
  • LiveKit 假设双端都是 WebRTC 客户端
  • 微信小程序 只支持 RTMP/HLS
  • LiveKit 无法直接与小程序通信

2. 增加复杂度,没有收益

项目当前方案 (MediaMTX)加入 LiveKit
架构MediaMTX + FFmpegMediaMTX + LiveKit + FFmpeg
容器数2个3个
配置复杂度简单复杂
延迟0.8-1.5秒0.8-1.5秒(无改善)
成本¥700/月¥700+/月
小程序支持✅ RTMP 原生❌ 需要额外转换

3. MediaMTX 已经够用

MediaMTX 提供的能力:
✅ WebRTC 推流(WHIP 协议) → 医生端已用
✅ RTMP 推流/播放 → 小程序已用
✅ HLS 播放 → 医生端已用
✅ 协议互转(WebRTC↔RTMP↔HLS)→ 核心能力
✅ 低资源占用 → 单实例支持数十路

LiveKit 额外能力(你用不上):
❌ 多房间管理 → 你只需要 1对1
❌ 复杂权限控制 → 简单场景不需要
❌ 双向 WebRTC → 小程序不支持
❌ SFU 转发优化 → 你只有 2 端,不需要


📊 架构对比

如果加入 LiveKit(复杂且无意义)

医生端 (WebRTC)

LiveKit Server ────┐
↓ │ 都要转 RTMP/HLS
MediaMTX ──────────┘ 给小程序

小程序 (RTMP/HLS)

问题:
  • LiveKit 和 MediaMTX 功能重叠
  • 小程序还是只能用 RTMP/HLS
  • LiveKit 变成多余的中间层

当前方案(精简高效)

医生端 (WebRTC)

MediaMTX (核心)

FFmpeg (仅转码音频)

小程序 (RTMP/HLS)

优势:
  • 每个组件都有明确职责
  • 没有冗余环节
  • 维护简单

💡 什么情况下需要 LiveKit?

✅ 适合用 LiveKit 的场景

1. 双端都是浏览器/App(支持 WebRTC)

医生 App (WebRTC) ↔ LiveKit ↔ 患者 App (WebRTC)

2. 多人会议

主治医师 + 专家1 + 专家2 + 患者
(4人以上视频会议)

3. 需要复杂房间管理
  • 分诊室、会诊室、手术室
  • 动态权限控制(禁言、踢人)
  • 录制、旁观者模式
4. 极致低延迟要求(< 500ms)

远程手术、实时竞拍、直播连麦

❌ 不适合用 LiveKit 的场景(你的情况)

  1. 一端是小程序(不支持标准 WebRTC)
  2. 简单 1对1 通话
  3. 可接受 1秒延迟
  4. 成本敏感

🎯 结论

100% 确定:不需要 LiveKit!

原因总结:

#原因影响
1小程序不支持 WebRTC 标准LiveKit 核心能力用不上
2MediaMTX 已提供所需功能LiveKit 变成冗余组件
3增加架构复杂度维护成本↑,收益为 0
4没有延迟改善瓶颈在 HLS,LiveKit 帮不上
5额外学习成本LiveKit 配置复杂且无意义

📝 建议

当前架构保持不变(最优)

✅ MediaMTX:核心流媒体服务器
✅ FFmpeg:音频转码(Opus → AAC)
❌ LiveKit:不需要

唯一需要 LiveKit 的时机

如果未来患者端改用原生 App(支持 WebRTC):

医生 App (WebRTC) ↔ LiveKit ↔ 患者 App (WebRTC)
这时可以考虑:
  • 替换整个 MediaMTX + FFmpeg 架构
  • 双端都用 LiveKit SDK
  • 延迟降到 < 500ms
但前提是:放弃小程序,改用原生 App。

💰 成本对比(再次确认)

方案月成本延迟复杂度小程序支持
腾讯云 TRTC¥7,3000.3s简单
LiveKit + MediaMTX¥1,000+0.8s复杂❌ 需转换
MediaMTX(当前)¥7001.0s简单✅ 原生

🚀 最终答案

不要用 LiveKit,理由充分:
  1. ❌ 小程序不支持
  2. ❌ 功能重叠浪费
  3. ❌ 增加复杂度
  4. ❌ 无延迟改善
  5. ✅ MediaMTX 已完全够用
保持当前架构,专注于业务上线! 🎯
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不老刘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值