更新记录
1.0.0(2026-08-14)
- 初始版本
- 支持加入/离开 LiveKit 房间
- 支持麦克风和摄像头开关
- 支持前后摄像头切换
- 支持屏幕共享
- 支持通过 LiveKitVideo 组件渲染远端视频流
平台兼容性
uni-app x(5.0)
| Chrome | Safari | Android | Android插件版本 | iOS | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|---|
| × | × | 8.0 | 1.0.0 | × | × | × |
livekit-plugin
基于 LiveKit 的 uni-app x 实时音视频插件,用于会议场景。目前只支持 Android。
依赖
- uni-app x(HBuilderX 内置支持)
- Android minSdkVersion 24
- livekit-android 2.27.0(版本见 utssdk/app-android/config.json)
快速开始
导入插件后:
import {
onEvent,
connect,
disconnect,
enableMic,
enableCamera,
startScreenShare,
stopScreenShare,
destroy,
} from "@/uni_modules/livekit-plugin"
1. 监听事件
onEvent((event : any) => {
switch (event.type) {
case "connected":
break
case "participant_join":
break
case "error":
break
}
})
2. 连接房间
connect("wss://your-server.livekit.cloud", "jwt_token")
token 需要由自己的服务端签发,插件不负责生成。首次调用 connect 会自动初始化,一般不需要手动调 init()。
3. 控制设备
enableMic(true) // 打开麦克风
enableCamera(true) // 打开摄像头
startScreenShare() // 开始屏幕共享
stopScreenShare() // 停止屏幕共享
4. 断开
disconnect() // 断开当前房间
destroy() // 页面卸载时调用,释放全部资源
API
init()
初始化插件,注册 Activity 回调用于接收屏幕共享授权结果。connect 内部会自动调用,一般不需要手动调用。
onEvent(callback)
注册事件回调。单回调,每次调用会覆盖上一次注册的回调。回调参数是一个对象,type 字段区分事件类型,其余字段视类型而定。
connect(url, token)
加入房间。url 是 LiveKit 服务地址(ws/wss),token 是服务端签发的 JWT。已在房间内重复调用会触发 already_connected 事件。
disconnect()
主动断开连接,触发 disconnect 事件。
enableMic(enable)
开关麦克风。未连接房间时调用无效果。
enableCamera(enable)
开关摄像头。未连接房间时调用无效果。
startScreenShare()
开始屏幕共享,会弹出系统授权对话框。用户拒绝时触发 screen_share_denied 事件。
stopScreenShare()
停止屏幕共享。
destroy()
断开连接并释放全部资源(渲染器、音频等)。页面卸载时应调用。
事件
| type | 字段 | 说明 |
|---|---|---|
| connected | 无 | 加入房间成功 |
| already_connected | 无 | 重复 connect |
| participant_join | identity | 参与者加入(有轨道订阅时也会触发) |
| participant_leave | identity | 参与者离开 |
| camera_subscribed | identity, source | 摄像头轨道就绪,source 为 "CAMERA" |
| screen_share_subscribed | identity, source | 屏幕共享轨道就绪,source 为 "SCREEN_SHARE" |
| audio_subscribed | identity, source | 麦克风音频轨道就绪,source 为 "MICROPHONE" |
| track_unsubscribed | identity, source | 轨道取消订阅 |
| track_muted | identity, source, muted | 轨道静音/取消静音 |
| speakers | ids | 当前正在说话的用户列表 |
| disconnected | 无 | 房间断开(对端断开或掉线) |
| disconnect | 无 | 本地调用 disconnect() |
| mic | enable | 本地麦克风状态变更 |
| camera | enable | 本地摄像头状态变更 |
| screen_share_denied | 无 | 用户拒绝屏幕共享授权 |
| error | message | 错误信息 |
source 字段取值是轨道枚举名:CAMERA / SCREEN_SHARE / MICROPHONE。
远端视频渲染
用 native-view 承载 LiveKitVideo:
<native-view @init="onNativeViewInit" style="width:100%;height:100%" />
import LiveKitVideo from "uts.sdk.modules.livekitPlugin.LiveKitVideo"
let mainVideo : LiveKitVideo | null = null
function onNativeViewInit(e : UniNativeViewInitEvent) {
mainVideo = new LiveKitVideo(e.detail.element)
}
收到 camera_subscribed / screen_share_subscribed 事件后绑定轨道:
mainVideo?.attachRemoteTrack(identity, "CAMERA") // 渲染摄像头
mainVideo?.attachRemoteTrack(identity, "SCREEN_SHARE") // 渲染屏幕共享
其它方法:
setMuted(muted):隐藏/显示画面,远端静音时用clear():解绑当前轨道removeTrack(identity, source):解绑并自动切到该用户另一路视频(例如共享结束切回摄像头)destroy():释放渲染器
调用示例
完整页面示例,参考 pages/livekit/livekit.uvue:
<template>
<view class="page">
<native-view @init="onNativeViewInit" style="width:100%;height:100%" />
<view class="toolbar">
<text>{{connected ? "已连接" : "连接中..."}}</text>
<text @click="leaveMeeting">离开</text>
</view>
<view class="action-bar">
<text @click="toggleMic">{{micOn ? "关麦" : "开麦"}}</text>
<text @click="toggleCamera">{{cameraOn ? "关摄像头" : "开摄像头"}}</text>
<text @click="toggleScreenShare">{{isSharing ? "停止共享" : "屏幕共享"}}</text>
</view>
</view>
</template>
<script setup lang="uts">
import {
onEvent, connect, disconnect, destroy,
enableMic, enableCamera, startScreenShare, stopScreenShare,
} from "@/uni_modules/livekit-plugin"
import LiveKitVideo from "uts.sdk.modules.livekitPlugin.LiveKitVideo"
const connected = ref<boolean>(false)
const micOn = ref<boolean>(true)
const cameraOn = ref<boolean>(true)
const isSharing = ref<boolean>(false)
let mainVideo : LiveKitVideo | null = null
function onNativeViewInit(e : UniNativeViewInitEvent) {
const mv = mainVideo
if (mv != null) {
mv.destroy()
}
mainVideo = new LiveKitVideo(e.detail.element)
}
onEvent((event : any) => {
const e = event as UTSJSONObject
const type = e["type"] as string
switch (type) {
case "connected":
connected.value = true
break
case "camera_subscribed":
case "screen_share_subscribed":
// 有远端画面轨道就绪,绑到渲染器上
mainVideo?.attachRemoteTrack(e["identity"] as string, e["source"] as string)
break
case "track_muted":
mainVideo?.setMuted(e["muted"] as boolean)
break
case "screen_share_denied":
isSharing.value = false
break
case "error":
uni.showToast({ title: e["message"] as string, icon: "none" })
break
case "disconnected":
connected.value = false
break
}
})
function toggleMic() {
micOn.value = !micOn.value
enableMic(micOn.value)
}
function toggleCamera() {
cameraOn.value = !cameraOn.value
enableCamera(cameraOn.value)
}
function toggleScreenShare() {
if (isSharing.value) {
stopScreenShare()
isSharing.value = false
} else {
startScreenShare()
isSharing.value = true
}
}
function leaveMeeting() {
disconnect()
destroy()
uni.navigateBack()
}
onShow(() => {
// 相机/麦克风运行时权限,需要业务方自行申请
try {
const pages = getCurrentPages()
const currentPage = pages[pages.length - 1] as UniPage
const activity = currentPage.getAndroidActivity()
if (activity != null) {
UTSAndroid.requestSystemPermission(
activity,
["android.permission.CAMERA", "android.permission.RECORD_AUDIO"],
() => {},
() => {
uni.showToast({ title: "请在设置中开启相机/麦克风权限", icon: "none" })
},
true
)
}
} catch (err) {
console.log("request permission error", err)
}
})
onMounted(() => {
// url / token 一般由自己的服务端下发,这里只是示例
connect("wss://your-server.livekit.cloud", "jwt_token")
})
onUnmounted(() => {
mainVideo?.destroy()
mainVideo = null
destroy()
})
</script>
注意点:
onShow里申请权限是因为此时页面已入栈、能拿到 Activity,直接传给requestSystemPermission才能弹窗。- 一个页面同时只有一路画面(
native-view只有一个),要看谁的画面由业务自己决定,示例里简化成谁先订阅就显示谁。 - 离开页面时记得
mainVideo.destroy()和插件destroy(),避免渲染器泄漏。
权限
插件已在 manifest 中声明以下权限:
- INTERNET
- CAMERA
- RECORD_AUDIO
- FOREGROUND_SERVICE
- FOREGROUND_SERVICE_MEDIA_PROJECTION
- MODIFY_AUDIO_SETTINGS
相机/麦克风是运行时权限,需要业务方在页面里自行申请(示例用 UTSAndroid.requestSystemPermission)。屏幕共享授权由系统弹窗处理,不需要额外申请。
已知限制
- 仅 Android,不支持 iOS。
onEvent是单回调,多个页面同时监听时后注册的会覆盖之前的。- 插件不提供本地画面预览,
native-view只渲染远端画面。 - 屏幕共享开启时,本地麦克风关闭会把系统声音通过麦克风轨道推出去,远端听到的是该用户的 mic 轨道声音。

收藏人数:
购买源码授权版(
试用
赞赏(0)
下载 13
赞赏 0
下载 12506281
赞赏 1942
赞赏
京公网安备:11010802035340号