跳到主要内容

微信小程序方案

微信小程序方案

国内业务做实时音视频,绕不开微信小程序。微信不开放 RTCPeerConnection,原生 <live-pusher> / <live-player> 是 RTMP/HLS 推拉流标签,不是 P2P。要做真正的 RTC,要么用厂商 SDK(TRTC 小程序版、声网小程序版),要么靠服务端转发到 RTMP/HLS。本篇讲清楚这几条路的边界。

1. 关键事实

  • 微信小程序不支持 WebRTC API:没有 RTCPeerConnection、没有 getUserMedia、没有 MediaStream
  • <live-pusher> 默认是 RTMP 推流,部分场景可走"实时音视频"模式(底层走 UDP/QUIC,腾讯私有协议)。
  • <live-player> 默认是 RTMP/FLV/HLS 拉流,"实时音视频" 模式拉低延迟流。
  • 二者不是 P2P,不是 ICE,不是 SRTP。是客户端 ↔ 边缘节点单向流。
  • 接入 <live-pusher> 需要满足"类目白名单":直播、社交、教育、医疗、金融等,并通过认证。新主体小程序无法直接用

什么时候适用:业务必须覆盖微信生态,团队接受厂商 SDK 锁定,或者就只是单向直播/连麦。 什么时候不适用:纯 P2P / 端到端加密 / 不希望流量过厂商云,这种场景小程序天然做不到。

2. 三条路的对比

方案底层延迟上行/下行互通能力类目要求适用场景
<live-pusher> + <live-player>(RTMP)RTMP/HTTP-FLV1~3 s双向但需自建链路与 H5/原生不直接互通严格单向直播
<live-pusher mode="RTC">腾讯实时音视频私有200~500 ms双向通过 TRTC 与各端互通严格1v1/连麦
TRTC 小程序 SDK(基于 live-pusher 封装)同上200~500 ms双向TRTC 房间严格多人会议 / 语聊房
声网 / 即构 小程序 SDK各家私有200~500 ms双向厂商房间严格同上
WebView H5 套 WebRTCiOS / Android 系统 WebView同 H5双向与 H5 直接互通看 webview 类目弱兼容,不推荐

注:小程序里嵌 <web-view> 跑 H5 WebRTC——iOS 内核不允许调摄像头,这条路在 iOS 上不通,即使 Android 通了也只是"同城见面通过 H5",不是小程序原生体验。

3. live-pusher / live-player 详解

3.1 模式

<live-pusher mode="...">

mode协议延迟用途
liveRTMP1~3 s一对多直播
RTC腾讯私有低延迟200~500 ms连麦、语聊房、1v1
SmartGTC腾讯智能码率~1 s介于两者之间

<live-player mode="..."> 类似,多了 mode="live"mode="RTC"

3.2 最小代码

<!-- 推 -->
<live-pusher
url="rtmp://your-cdn/live/stream-{{userId}}"
mode="RTC"
enable-camera="{{true}}"
enable-mic="{{true}}"
device-position="front"
beauty="0"
whiteness="0"
bindstatechange="onPushState"
binderror="onPushError"
style="width:100%; height:300px;">
</live-pusher>

<!-- 拉 -->
<live-player
src="rtmp://your-cdn/live/stream-other"
mode="RTC"
autoplay="{{true}}"
bindstatechange="onPlayState"
binderror="onPlayError"
style="width:100%; height:300px;">
</live-player>
Page({
onPushState(e) {
// 1001 已经连接推流服务器
// 1002 已经与服务器握手完毕,开始推流
// -1301 网络断连
console.log('push state', e.detail.code);
},
onPushError(e) {
console.error('push err', e.detail);
},
});

3.3 状态码摘录

code含义
1001已连接推流服务器
1002推流握手完毕
1003摄像头打开
1004录屏开始
1005推流分辨率改变
1006推流动态调整码率
-1301推流连接断
-1302推流连接超时
-1307网络断连,多次重试无效

业务必须监听 -1301/-1307,做断线重连。

3.4 与 H5 互通的真实链路

要让 H5 的 WebRTC 和小程序的 live-pusher 出现在同一个"房间",必须有服务端做协议转换:

小程序 live-pusher (RTMP) ─┐
├─→ CDN/SFU 协议转换层 ─→ WebRTC (H5)
H5 WebRTC (SRTP/UDP) ────┘ 原生 (iOS/Android libwebrtc)

实现方式:

  1. 腾讯 TRTC:小程序、H5、原生 SDK 都接 TRTC 房间,房间内部做协议互通。
  2. 自研 SFU + RTMP 网关:让 SFU 同时收 SRTP(H5/原生)和 RTMP(小程序),转换 RTP 包。
  3. 声网 / 即构 等:与 TRTC 同思路。

绝大多数业务选 1 或 3,避开自研网关。

4. TRTC 小程序 SDK

4.1 安装

npm install trtc-wx-sdk --save

project.config.json

{
"setting": {
"useStrictMode": true
}
}

工具类目里勾选

  • 摄像头
  • 麦克风
  • 后台音频

类目要求"实时音视频通话"或"音视频通话"已通过审核。

4.2 进房

import TRTC from 'trtc-wx-sdk';

const trtc = TRTC.create();

await trtc.enterRoom({
sdkAppId: 1400000000,
userId: 'user_123',
userSig: '<服务端签的>',
strRoomId: 'room_001',
scene: 'rtc', // 'rtc' / 'live'
});

await trtc.startLocalAudio();
await trtc.startLocalVideo();

trtc.on('REMOTE_USER_JOIN', (e) => {
trtc.startRemoteVideo({ userId: e.userId, streamType: 'main' });
});

4.3 与 live-pusher / live-player 的关系

TRTC 小程序 SDK 不是脱离 &lt;live-pusher> / &lt;live-player> 的——它内部就是把这两个标签 + 信令封装起来。所以:

  • 必须在 wxml 里放 &lt;live-pusher>&lt;live-player>,由 SDK 通过 selectComponent 接管。
  • 小程序"实时音视频"类目权限 SDK 也要。
  • 一个页面同时只能有 1 个 &lt;live-pusher>

4.4 wxml 模板

<view class="rtc">
<live-pusher
id="trtc-pusher"
mode="RTC"
autopush
binderror="onError"
bindnetstatus="onNet"
bindstatechange="onState"
/>
<view class="remotes">
<live-player
wx:for="{{remoteUsers}}"
wx:key="userId"
id="player-{{item.userId}}"
src="{{item.url}}"
mode="RTC"
autoplay
/>
</view>
</view>

5. 后台 / 锁屏

小程序进入后台后:

状态live-pusherlive-playerTRTC 行为
微信切到聊天页视频自动推黑帧视频暂停,音频保持业务无感
锁屏视频停采,音频可保持(开后台音频权限)视频停渲染,音频继续视通话仍在房间
系统返回桌面iOS 30~60s 后断;Android 视厂商同上必须重连逻辑
来电中断推流暂停拉流暂停通话结束自动恢复

后台音频要在 app.json 配:

{
"requiredBackgroundModes": ["audio"]
}

且小程序类目支持"后台音频"。

6. 失败时的样子

现象原因处理
&lt;live-pusher> 节点找不到类目未通过 / 基础库版本太低类目申请 + base library ≥ 2.10
进房没声音也没图没调 startLocalVideo / startLocalAudio显式调用
iOS 上推流绿屏摄像头被其他 App 占用释放、重启 live-pusher 组件
切后台 60s 后断后台时间限制TRTC 会自动重连,业务监听 onConnectionStateChange
H5 收不到小程序房间未对接同一 RTC 平台必须都接 TRTC / 声网
多个 live-pusher 同页面微信限制一页只能一路推流
切前后置摄像头黑屏switchCamera 后内部没重连等 STATE_CHANGE 1003 再渲染
弱网卡顿推流码率没自适应mode="RTC" 自带,或 bitrate 设小

7. 与支付宝 / 抖音 / 快手小程序的差异

维度微信支付宝抖音快手
推拉流标签live-pusher / live-playerlive-pusher / live-player(限场景)字节自有
实时音视频TRTC、声网、即构蚂蚁 RTC火山引擎 RTC快手内部 RTC
类目门槛
与微信房间互通自然必须服务端桥必须服务端桥必须服务端桥

跨多家小程序的统一方案见 uni-app跨端策略.mdL6-跨端连麦SDK

8. 性能与体验要点

  • live-pusher 默认 aspect="9:16",强制竖屏;横屏要 aspect="3:4""16:9" 并自己旋转。
  • min-bitrate / max-bitrate 一定写,否则弱网下码率不收敛。
  • 美颜参数 beauty / whiteness 限 0~9,过高会糊。
  • 多路 &lt;live-player> 同页面:iOS 上同时播 4 路以上极易闪退,建议 ≤ 4。
  • 视频帧率:mode="RTC" 默认 15 fps,要 30 fps 必须 min-frame-rate="30"

9. 类目与合规

要在微信使用音视频组件,必须满足:

  1. 类目:小程序服务类目里包含支持的类目(社交-直播、社交-社区、教育-在线视频课程、医疗、金融、政务等)。
  2. 资质:直播类需 ICP + 网络文化经营许可证 / 网络出版服务许可证。
  3. 实名:用户首次开播前必须实名。
  4. 内容审核:直播流必须接入截图审核或视频审核(腾讯云、阿里云的实时审核服务)。
  5. 隐私协议:明确告知摄像头、麦克风采集用途。

不满足,组件 API 直接报错或审核被拒。

10. 反模式

反模式后果
把 live-pusher / live-player 当成 P2P 用设计错位,弱网下体验崩
不申请实时音视频类目就上线组件不可用
一个页面塞 6 路 live-playeriOS 必崩
不监听 -1301/-1307 错误码断线无感,用户莫名其妙
在 setData 里塞整个 live-player URL 数组每秒刷render 卡顿
跨厂商互通靠"自己写 RTMP 解协议"工作量超估,3 个月做不完
小程序里通过 web-view 跑 H5 WebRTCiOS 内核拒绝,无解
后台音频权限漏勾切微信看消息就断流

11. 选型 Checklist

  • 业务方向是单向直播还是双向连麦
  • 是否需要与 H5 / 原生 / 其他小程序互通
  • 类目是否支持,资质是否齐全
  • 内容审核怎么接
  • 是否接受厂商锁定(TRTC / 声网 / 即构)
  • 监控告警怎么做(必须接厂商质量监控 API)
  • 弱网兜底是否能降级到普通 RTMP 直播
  • 跨端 SDK 是否在 iOS / Android 微信都通过性能验证

12. 权威资料