更新记录

1.0.4(2026-10-21)

  • 首次发布 wd-livekit-native 插件。
  • 支持 Android App 端(nvue 页面)接入 LiveKit,基于官方原生 SDK(非 WebView、非 JS SDK)。
  • 提供基础音视频控制:connect / disconnect / setMicrophoneEnabled / setCameraEnabled / switchCamera / setSpeakerphoneOn。
  • 提供原生渲染组件 livekit-video-view(viewRole="local" | "remote"):轨道自动绑定画面,无需手动管理 track。
  • 内置小窗拖动、点击交换全屏/小窗交互,由原生层实现。
  • 支持弱网自动重连(onReconnecting / onReconnected)与对端网络质量回调(onNetworkQuality)。
  • iOS 端 Swift 实现已提供,但未经编译验证,暂不建议用于生产。

平台兼容性

uni-app(4.76)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
- - - - - - - - -
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
- - - - - - - - - - - -

wd-livekit-native

基于 LiveKit 官方原生 SDK(Android: io.livekit:livekit-android,iOS: LiveKitClient)封装的 1v1 实时音视频通话 UTS 插件。非 WebView 方案、非 JS SDK 方案,画面由原生 WebRTC 渲染器(TextureViewRenderer)直出。

接入方只需要关心「连房间」和「挂断」两件事:

  • 画面全自动绑定:本地/远端轨道由插件原生层自动分发到渲染组件,无任何手动绑 track 的 API
  • 小窗交互内置:小窗拖动、点击交换全屏/小窗,均在原生层实现,页面不用写手势
  • 弱网自动重连:瞬断由 SDK 自动恢复,业务层只需在回调里切换提示

平台支持

平台 支持 说明
Android App(nvue 页面) ✅ 已实测 minSdkVersion 21
iOS App ⚠️ 代码已提供 Swift 实现未经编译验证;onNetworkQuality / onReconnecting / onReconnected 回调暂未桥接
H5 / 小程序 ❌

渲染组件 livekit-video-view 仅可在 nvue 页面 使用。

快速上手(3 步)

参考资料:https://www.yuque.com/bian-trriw/ruwq76/yn7s3669i9d6ktnc

1. nvue 页面放两个渲染组件

<template>
    <view>
        <!-- 远端全屏 -->
        <livekit-video-view viewRole="remote" class="vc-remote"></livekit-video-view>
        <!-- 本地小窗(mirror 镜像) -->
        <livekit-video-view viewRole="local" :mirror="true" class="vc-local"></livekit-video-view>
    </view>
</template>
/* 样式示例:远端全屏铺满,小窗位置见下文「必须遵守的写法」第 4 条 */
.vc-remote { position: absolute; top: 0; left: 0; right: 0; bottom: 0; }
.vc-local { position: absolute; }

connect 成功后本地画面自动进小窗,对方画面到达后自动进全屏,不需要也不能手动绑 track。

2. 拿 token 连房间

token 由你的后端调 LiveKit Server API 签发(见下文「后端要求」)。

import { connect } from '@/uni_modules/wd-livekit-native'

const res = await uni.request({ url: 'https://your-server/api/video/token?roomId=xxx' })
const { token, url } = res.data.data

connect(url, token, {
    onConnected: () => {},                          // 接通
    onTrackSubscribed: (sid, identity, kind) => {}, // kind='VIDEO' 即对方画面到达
    onDisconnected: (reason) => {},                 // 'participant-left' 对方挂断
    onError: (msg) => {},
    onNetworkQuality: (level) => {},                // 对端网络质量,见 RoomEvents
    onReconnecting: () => {},                       // 瞬断自动重连中
    onReconnected: () => {}                         // 重连成功
})

3. 操作与挂断

import { disconnect, setMicrophoneEnabled, switchCamera, setSpeakerphoneOn } from '@/uni_modules/wd-livekit-native'

setMicrophoneEnabled(false) // 静音
switchCamera()              // 翻转前后摄像头
setSpeakerphoneOn(false)    // 切听筒(true=扬声器外放,连接后默认扬声器)
disconnect()                // 挂断。页面 onUnload 里必须调,否则摄像头不释放

API 一览

API 说明
connect(url, token, events) 连房间,成功后自动开摄像头/麦克风/扬声器
disconnect() 断开并释放资源,退出页面必须调
setMicrophoneEnabled(bool) 麦克风开关
setCameraEnabled(bool) 摄像头开关
switchCamera() 前后摄切换
setSpeakerphoneOn(bool) 扬声器/听筒切换
swapVideoViews() 手动交换全屏/小窗画面(一般不用,点小窗原生层已自动交换)
getDebugState() 调试用状态快照字符串

RoomEvents 回调(全部可选)

回调 参数 说明
onConnected - 房间接通
onTrackSubscribed sid, identity, kind 对方轨道到达,kind = 'AUDIO' | 'VIDEO'
onTrackUnsubscribed sid 对方轨道移除
onDisconnected reason 'participant-left' 对方离开 | 'disconnected' 房间断开,仅在彻底失败时触发
onError message 出错(连接失败等)
onNetworkQuality level 对端网络质量:excellent / good / poor / lost / unknown
onReconnecting - 瞬断自动重连中(SDK 自动恢复,无需重拨)
onReconnected - 重连成功

渲染组件 livekit-video-view

属性 类型 默认 说明
viewRole String 'remote' 'remote' 远端画面(全屏)| 'local' 本地预览(小窗)
mirror Boolean false 本地画面是否镜像

必须遵守的写法(违反会黑屏/失效)

  1. 两个组件放在 page 根节点直接子级,不要包在 absolute + overflow:hidden 容器里
  2. 组件不要写 background-color 样式
  3. 组件常驻挂载,别用 v-if 控制显隐(未接通用占位 view 盖住即可)
  4. 小窗用内联 style 定位时,值要乘 screenWidth / 750(UTS 组件 px 与 weex px 不一致),参考:
// onLoad 里算补偿系数
const sys = uni.getSystemInfoSync()
this.compRatio = (sys.screenWidth || 750) / 750
// 内联样式里使用
this.style = `top:${Math.round(top * this.compRatio)}px;left:${Math.round(left * this.compRatio)}px;width:${Math.round(192 * this.compRatio)}px;height:${Math.round(300 * this.compRatio)}px;`
  1. 别给组件包 @click/@touch —— 收不到事件,小窗拖动/交换已在原生层实现
  2. Android 需预申请运行时权限 CAMERA / RECORD_AUDIO(建议连同 MODIFY_AUDIO_SETTINGS),拒绝时原生 SDK 会给出明确错误
  3. 修改插件源码后需重新云打包自定义基座才能生效

后端要求

需要自己部署 LiveKit Server,并提供一个签发 token 的接口:

GET /api/video/token?roomId=xxx
返回:{ "url": "wss://your-livekit-server", "token": "eyJ..." }

同一房间的双方拿各自 token 进房即可互通。呼叫/接听/挂断等信令(STOMP WebSocket、IM 通道等)由业务层自行实现,本插件不参与信令。

完整示例里,哪些代码和插件有关?

下面用一个完整通话页(含呼叫流程)说明边界——插件相关的只有 4 块,其余都是业务代码:

代码块 归属 作用
两个 <livekit-video-view> 组件及其样式 插件 渲染本地/远端画面
connect(url, token, {...}) 插件 进房间
setMicrophoneEnabled / switchCamera / setSpeakerphoneOn 插件 通话操作
disconnect()(放在 onUnload / 清理函数里) 插件 挂断并释放摄像头/麦克风
STOMP/WebSocket 信令(invite / accept / reject / hangup) 业务 决定「谁和谁、何时、进哪个房间」
获取 token 的后端接口 业务 后端签发 LiveKit 凭证
状态文案、计时、网络质量 UI、图标字体、占位头像等 业务 界面展示

也就是说:不实现呼叫信令也能用本插件——写个测试按钮直接调 connect() 就能进房间看到画面。信令只是决定通话的时机和对象。

完整工程示例(信令 + UI + 插件接入):参考 pages/myPage/videoCall.nvue(本项目内)。

隐私、权限声明

1. 本插件需要申请的系统权限列表:

android.permission.CAMERA(摄像头,用于采集本地视频画面)、android.permission.RECORD_AUDIO(麦克风,用于采集本地音频)、android.permission.MODIFY_AUDIO_SETTINGS(音频输出方式切换,用于扬声器/听筒切换)

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件自身不采集、不存储任何用户数据。接入后 LiveKit SDK 会将音视频流及房间连接信息实时传输到接入方自建的 LiveKit 服务器(服务器地址由接入方配置),仅用于实现实时音视频通话。

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

无

暂无用户评论。