如果你的小程序需要语音输入、视频通话或者实时直播,你会发现小程序的音视频能力和普通网页完全不同。浏览器里可以直接用WebRTC,但小程序运行在微信的沙箱环境中,有自己的一套组件和权限体系。

今天我们从零开始,梳理小程序音视频开发的完整技术路径——包括你需要提前准备什么、有哪些技术方案可选、以及核心功能的实现方法。

一、先确认门槛:你的小程序能做音视频吗?

这是最容易被忽略的问题。小程序的音视频能力不是所有账号都能用的。

第一关:企业认证。个人小程序无法使用live-pusher和live-player组件,必须是企业认证的小程序账号-7

第二关:类目审核。即使有企业账号,还需要你的小程序所属类目在微信开放的范围内。主要支持类目包括:社交直播、在线教育、互联网医院、在线问诊、金融等-1。提交类目申请后,审核通常需要1-3个工作日-1

第三关:接口权限开关。在微信公众平台的“开发-开发管理-接口设置”中,需要手动打开“实时播放音视频流”和“实时录制音视频流”两个开关-2-5

第四关:服务器域名配置。将RTC服务商的域名添加到request合法域名和socket合法域名中-1-2。这一步如果不做,真机上会直接黑屏。

以上任何一步没准备好,代码写得再好也无法运行。

二、方案选型:自研还是第三方SDK?

跨过门槛之后,下一步是选择技术实现方案。

方案一:自研

自研意味着你需要搭建WebSocket信令服务器(处理房间管理、用户进出通知),对接TURN/STUN服务器(处理NAT穿透),自行管理推拉流地址(通常是RTMP或WebRTC地址),还要处理复杂的网络状况和弱网优化。

适合场景:有专职音视频团队、对数据私有化要求极高、长期维护成本可控-1

方案二:第三方RTC SDK

对于大多数业务团队,第三方SDK是更务实的选择。主流方案的对比如下-1

 
 
维度 ZEGO即构 腾讯云TRTC 阿里云RTC
小程序原生支持 支持 支持 支持
免费额度 每月10000分钟 每月10000分钟 少量免费试用
国内平均延迟 <200ms <300ms 200-500ms
接入复杂度

本文以ZEGO为例进行说明,因为其小程序端接入步骤简洁,免费额度对中小项目可以零成本启动-1

三、核心组件:live-pusher与live-player

无论选择哪家SDK,底层使用的都是微信提供的两个原生组件。

live-pusher:实时音视频录制组件,负责采集摄像头和麦克风数据,推流到RTC服务器。关键属性包括:

live-player:实时音视频播放组件,负责从服务器拉取远端流并播放。关键属性包括:

需要注意的是,微信开发者工具不支持这两个组件的真实验证,必须用真机调试-7

四、代码实现:1v1视频通话

以ZEGO SDK为例,实现一个简单的1v1视频通话。

步骤1:引入SDK

javascript
npm install zego-express-engine-miniprogram

在微信开发者工具中点击“工具-构建npm”-1

步骤2:页面结构(WXML)

html
 
<view class="container">
  <!-- 本地推流(自己的画面) -->
  <live-pusher
    id="local-pusher"
    url="{{pushUrl}}"
    mode="RTC"
    autopush
    muted="{{isMuted}}"
    enable-camera="{{cameraOn}}"
    class="local-video"
  />

  <!-- 远端拉流(对方的画面) -->
  <live-player
    wx:for="{{remoteStreams}}"
    wx:key="streamID"
    src="{{item.playUrl}}"
    mode="RTC"
    autoplay
    class="remote-video"
  />
</view>

步骤3:初始化SDK并加入房间

javascript
const ZegoExpressEngine = require('../../miniprogram_npm/zego-express-engine-miniprogram/index');

Page({
  data: {
    pushUrl: '',
    remoteStreams: [],
    isMuted: false,
    cameraOn: true,
  },

  onLoad(options) {
    this.roomID = options.roomID || 'room_001';
    this.userID = options.userID || `user_${Date.now()}`;
    this.streamID = `stream_${this.userID}`;
    this.initEngine();
  },

  initEngine() {
    this.engine = ZegoExpressEngine.createEngine(APP_ID, APP_SIGN, true, {});
    this.registerCallbacks();
    this.joinRoom();
  },

  registerCallbacks() {
    // 监听房间内流的变化
    this.engine.on('roomStreamUpdate', (roomID, updateType, streamList) => {
      if (updateType === 'ADD') {
        const newStreams = streamList.map(stream => ({
          streamID: stream.streamID,
          playUrl: this.engine.startPlayingStream(stream.streamID),
        }));
        this.setData({
          remoteStreams: [...this.data.remoteStreams, ...newStreams],
        });
      } else if (updateType === 'DELETE') {
        const deletedIDs = new Set(streamList.map(s => s.streamID));
        this.setData({
          remoteStreams: this.data.remoteStreams.filter(s => !deletedIDs.has(s.streamID)),
        });
      }
    });
  },

  async joinRoom() {
    // 登录房间
    await this.engine.loginRoom(this.roomID, token, {
      userID: this.userID,
      userName: `用户${this.userID}`,
    });

    // 拉取已在房间内的流
    const existingStreams = await this.engine.getRoomStreamList(this.roomID);
    const remoteStreams = existingStreams.map(stream => ({
      streamID: stream.streamID,
      playUrl: this.engine.startPlayingStream(stream.streamID),
    }));
    this.setData({ remoteStreams });

    // 开始推送本地流
    const pushUrl = this.engine.startPublishingStream(this.streamID);
    this.setData({ pushUrl });
  },

  // 静音切换
  toggleMute() {
    this.setData({ isMuted: !this.data.isMuted });
  },

  // 摄像头切换
  toggleCamera() {
    this.setData({ cameraOn: !this.data.cameraOn });
  },

  onUnload() {
    this.engine.stopPublishingStream();
    this.engine.logoutRoom(this.roomID);
    ZegoExpressEngine.destroyEngine();
  },
});

五、语音识别:让小程序听懂人话

除了视频通话,语音识别也是小程序音视频能力的常见应用场景。

微信小程序提供了原生语音识别API,核心用法如下-6

javascript
// 启动语音识别
wx.startVoiceRecognition({
  lang: 'zh_CN',
  success: () => {
    console.log('识别服务启动成功');
  },
  fail: (err) => {
    console.error('启动失败', err);
  }
});

// 实时接收识别结果
wx.onVoiceRecognitionResult((res) => {
  this.setData({
    transcription: res.result
  });
});

关键配置:需要在app.json中声明requiredPrivateInfos: ["getVoiceRecognition"]权限,采样率推荐16kHz以获得最佳识别效果-6

六、常见问题与解决方案

根据多家RTC服务商的文档,以下是高频踩坑点汇总-1-2-5

 
 
问题现象 原因 解决方法
live-pusher不渲染,显示空白 小程序类目不支持实时音视频 在公众平台申请对应服务类目
推流成功但对方看不到画面 SDK域名未加入白名单 在开发设置中配置合法域名
真机黑屏,模拟器正常 未申请摄像头/麦克风权限 在app.json中声明permission
进入房间看不到已有成员 未主动拉取已有流列表 loginRoom后调用getRoomStreamList
iOS和Android画面比例不一致 系统渲染差异 统一设置object-fit: fillCrop

七、总结

小程序音视频开发的核心技术栈并不复杂:确认账号资质、选择RTC服务商、集成SDK、使用live-pusher和live-player组件实现推拉流、通过服务端API进行房间管理。

对于大多数业务场景,直接使用第三方RTC SDK是最务实的选择——你不需要成为音视频专家,也能在半小时内跑通第一个视频通话Demo。

电话咨询
QQ咨询
在线咨询
服务投诉