更新记录

1.0.0(2026-09-30)

  • 首次发布:uni-app x 标准模式 UVC 摄像头组件
    • 打开 / 关闭摄像头、预览、拍照、录像
    • 设备列表获取与切换、分辨率获取与设置、旋转与镜像
    • UVC 参数读写(绝对值 / 百分比)、亮度与对比度调节

平台兼容性

uni-app x(4.27)

Chrome Safari Android Android插件版本 iOS 鸿蒙 微信小程序
- - 6.0 1.0.0 - - -

其他

多语言 暗黑模式 宽屏模式 蒸汽模式
× × × √

zy-uvc-x

USB 摄像头(UVC)uni-app x 标准模式组件(uts-vue-component)。

  • 仅实现 Android(iOS / HarmonyOS 提供占位实现,调用回传 9010010 当前平台暂不支持)
  • 回调式 API:方法入参传 { success, fail },同时通过 @onResult 事件回传相同内容

功能

  • 打开 / 关闭摄像头,开启 / 关闭预览
  • 获取设备列表、按设备名 / id / 产品名 / 索引切换摄像头
  • 获取 / 设置预览分辨率、旋转、镜像,获取预览配置
  • 拍照(可选时间戳水印、自定义文件名)、录像 / 停止录像(含录音开关、码率、帧率)
  • 读写全部 UVC 参数(亮度、对比度、饱和度等 25 项),支持绝对值与百分比

快速开始

easycom 规范,无需 import 即可直接使用:

<template>
    <view class="page">
        <zy-uvc-x ref="uvcRef" class="camera" @load="onload" @onResult="onResult" @onDeviceState="onDeviceState"></zy-uvc-x>
        <button @click="open">打开摄像头</button>
    </view>
</template>

<script setup lang="uts">
    const uvcRef = ref<ComponentPublicInstance | null>(null)

    function onload() {
        console.log("组件初始化完成")
    }

    function open() {
        uvcRef.value?.$callMethod('openCamera', {
            success: (result) => {
                // result: { code: 0, msg: "摄像头已打开", data: { deviceName, previewing } }
                console.log(result.msg + " " + JSON.stringify(result.data))
            },
            fail: (error) => {
                // error: { code: 9010001, message: "未发现USB摄像头设备" }
                console.log(error.code + " " + error.message)
            }
        })
    }

    function onResult(e: UniNativeViewEvent) {
        // 与 success / fail 回调内容一致:{ type: "openCamera", data: { code, msg, data } }
        console.log(JSON.stringify(e.detail))
    }

    function onDeviceState(e: UniNativeViewEvent) {
        // { type: "onCameraOpen" | "onCameraClose" | "onDetach" | "onCancel" | "onError", ... }
        console.log(JSON.stringify(e.detail))
    }
</script>

<style>
    .camera {
        width: 100%;
        height: 300px;
    }
</style>

调用说明

  • 组件已通过 defineExpose 显式暴露全部方法,vapor 模式下使用 $callMethod('方法名', options) 调用。
  • success / fail 每次调用最多触发一次,回调在主线程派发。
  • 未传 success / fail 时,仍可从 @onResult 事件中拿到 type 与结果。
  • 部分方法(openCamera、switchCamera、takePicture、startRecord、stopRecord)为异步原生流程,结果可能在调用后的下一个事件循环返回。

预览控制

openCamera 默认 autoPreview: true,打开成功后自动开始预览。若只想暂停画面而不拔出摄像头,用 stopPreview / startPreview:

// 停止预览(摄像头仍保持打开)
uvcRef.value?.$callMethod('stopPreview', {
    success: (result) => {
        // result.data = { previewing: false }
        console.log(result.msg)
    }
})

// 恢复预览
uvcRef.value?.$callMethod('startPreview', {
    success: (result) => {
        // result.data = { previewing: true }
        console.log(result.msg)
    }
})
  • 摄像头未打开时调用回传 9010006;原生启动 / 停止预览失败回传 9010008。
  • 预览是否正在输出可用 isCameraOpen 查询(isPreviewing 字段)。
  • 停止预览期间拍照、录像、参数读写仍需摄像头处于打开状态,与预览开关无关。
  • 重新调用 startPreview 或切换分辨率(setResolution)都会重新启动预览。

读取全部可调参数(标准 TS 取值)

getAllParams 的 data 是 UTSJSONObject,推荐 JSON.stringify + JSON.parse<T> 转成类型化对象后直接按属性访问:

uvcRef.value?.$callMethod('getAllParams', {
    success: (result) => {
        const data: ParamsData | null = JSON.parse<ParamsData>(JSON.stringify(result.data))
        if (data == null || data.params == null) return
        const params = data.params
        for (let i = 0; i < params.length; i++) {
            const p = params[i]
            if (p.supported != true) continue
            console.log(p.label + " " + p.current + " [" + p.min + "," + p.max + "]")
        }
    }
})

type ParamRaw = {
    name: string
    label: string
    supported: boolean
    isBool: boolean
    current: number
    percent: number
    min: number
    max: number
    def: number
}
type ParamsData = {
    count: number
    params?: ParamRaw[]
}

个别参数(如部分摄像头的 brightness、autoExposureMode)可能 supported = true 但 min === max(驱动未上报范围),生成滑块前请先判断 max > min。

API

方法

所有方法的 success 收到 UvcResult { code, msg, data },fail 收到 UvcError { code, message }。

方法 入参 Options 说明
openCamera OpenCameraOptions 打开摄像头并预览;不传参数时自动选择第一台设备
closeCamera UvcCallbackOptions 关闭摄像头(若正在录像会先停止录像)
startPreview UvcCallbackOptions 开启预览,摄像头已打开但预览已停止时调用;成功 data = { previewing: true }
stopPreview UvcCallbackOptions 停止预览画面,摄像头保持打开、状态查询仍为已打开;成功 data = { previewing: false }
getCameraList UvcCallbackOptions 获取当前 USB UVC 设备列表
switchCamera SwitchCameraOptions 切换摄像头;不传参数时在多台设备间轮换
getSupportedResolutions UvcCallbackOptions 获取支持的分辨率列表(需已打开摄像头)
getCurrentResolution UvcCallbackOptions 获取当前生效的分辨率
setResolution SetResolutionOptions 设置预览分辨率(成功后自动重新预览)
setRotation SetRotationOptions 设置旋转角度,仅支持 0 / 90 / 180 / 270
setMirror SetMirrorOptions 设置镜像模式,仅支持 0 / 1 / 2 / 3
getPreviewConfig UvcCallbackOptions 获取预览配置(旋转、镜像)
isCameraOpen UvcCallbackOptions 查询打开 / 预览 / 录像状态
takePicture TakePictureOptions 拍照,保存到应用私有目录 uvcX
startRecord RecordOptions 开始录像(可配置录音、码率、帧率)
stopRecord UvcCallbackOptions 停止录像并落盘
getAllParams UvcCallbackOptions 获取全部 UVC 参数(25 项)
getParam GetParamOptions 按 name 读取单个参数,返回该参数的完整字段(current 为绝对值,percent 为换算好的百分比)
setParam SetParamOptions 按 name 写入绝对值 value,不做百分比换算,value 需落在该参数 [min, max] 内
getParamPercent GetParamOptions 按 name 读取百分比,返回结构与 getParam 相同,percent 即 0~100 的百分比
setParamPercent SetParamPercentOptions 按 name 写入百分比 percent(0~100),内部按 [min, max] 换算成绝对值后再写入
resetParams UvcCallbackOptions 重置全部参数为默认值
getBrightnessPercent UvcCallbackOptions 读取亮度百分比(brightness 的快捷方法)
setBrightnessPercent SetPercentOptions 设置亮度百分比
getContrastPercent UvcCallbackOptions 读取对比度百分比(contrast 的快捷方法)
setContrastPercent SetPercentOptions 设置对比度百分比

类型定义见 utssdk/interface.uts。

Options 类型

每个 Options 均可携带 success / fail 回调(下表最后两行统一说明,其余类型不再重复列出含义)。

类型 字段 说明
通用 success?: (result: UvcResult) => void 成功回调,result = { code, msg, data }
通用 fail?: (error: UvcError) => void 失败回调,error = { code, message }
OpenCameraOptions deviceName?: string 指定设备节点名,如 /dev/bus/usb/001/090,取自 getCameraList
deviceId?: number 指定 USB deviceId(UsbDevice.getDeviceId())
productName?: string 指定 USB 产品名
index?: number 按设备列表下标选择,从 0 开始
size?: number[] 打开时指定预览分辨率 [宽, 高],优先精确匹配该尺寸;匹配不到或不传时自动选择(优先 MJPEG 格式)
autoPreview?: boolean 打开后是否自动开启预览,默认 true
SwitchCameraOptions deviceName? / deviceId? / productName? / index? 目标设备的四种定位方式,语义同 OpenCameraOptions;全部不传时在已连接设备间轮换
TakePictureOptions addTimestamp?: boolean 是否在照片右上角叠加时间戳水印,默认 false
timestampFormat?: string 水印格式:"formatted" 输出 yyyy-MM-dd HH:mm:ss,其他值输出毫秒时间戳,默认 "raw"
fileName?: string 自定义文件名(含扩展名),默认 uvc_<毫秒时间戳>.jpg,保存于 uvcX 目录
RecordOptions audio?: boolean 是否录制声音,默认 true
bitRate?: number 视频码率(bps),默认 6553600
frameRate?: number 视频帧率,默认 25
SetResolutionOptions width: number / height: number 目标分辨率宽高(必填,须大于 0)
type?: number 视频格式,7 为 MJPEG(默认),其他值按摄像头支持的格式传入
fps?: number 目标帧率,默认 30
fpsList?: number[] 该分辨率支持的帧率列表,随格式一起下发
SetRotationOptions rotation: number 旋转角度,仅支持 0 / 90 / 180 / 270(其他值取模归一后仍需为四者之一)
SetMirrorOptions mirror: number 镜像模式:0 不镜像、1 水平、2 垂直、3 水平+垂直
GetParamOptions name: string 参数名,见上方「UVC 参数」表,如 brightness
SetParamOptions name: string 参数名
value: number 写入的绝对值,需落在该参数的 [min, max] 内
SetParamPercentOptions name: string 参数名
percent: number 写入的百分比,取值 0 ~ 100,内部按 [min, max] 换算为绝对值
SetPercentOptions percent: number 同上,配合 setBrightnessPercent / setContrastPercent 使用

success.data 结构

方法 data
openCamera { deviceName, previewing }
startPreview { previewing: true }
stopPreview { previewing: false }
getCameraList { count, devices: UvcDeviceInfo[], currentDeviceName }
switchCamera { switched: boolean, deviceName } 或 { deviceName, previewing }
getSupportedResolutions { count, sizes: UvcSize[] }
getCurrentResolution / setResolution { width, height, type, fps, fpsList }
setRotation { rotation }
setMirror { mirror }
getPreviewConfig { rotation, mirror }
isCameraOpen { isOpen, isPreviewing, isRecording, deviceName }
takePicture { path, uri }
startRecord { path }
stopRecord { path, uri }
getAllParams { count, params: ParamRaw[] }
getParam / getParamPercent / setParam / setParamPercent ParamRaw(单个参数)
resetParams { count }

ParamRaw 字段:name / label / supported / isBool / current / percent / min / max / def。

UVC 参数

name 名称 类型
brightness 亮度 数值
contrast 对比度 数值
saturation 饱和度 数值
hue 色调 数值
sharpness 锐度 数值
gamma Gamma 数值
whiteBalance 白平衡 数值
gain 增益 数值
backlightComp 背光补偿 数值
exposureTime 曝光时间 数值
focus 焦距 数值
zoom 变焦 数值
pan 水平 数值
tilt 垂直 数值
roll 滚转 数值
iris 光圈 数值
powerlineFrequency 电源频率 数值
autoExposureMode 曝光模式 数值
digitalMultiplier 数字增益 数值
focusAuto 自动对焦 布尔(0 / 1)
hueAuto 色调自动 布尔(0 / 1)
whiteBalanceAuto 白平衡自动 布尔(0 / 1)
contrastAuto 对比度自动 布尔(0 / 1)
exposureTimeAuto 曝光自动 布尔(0 / 1)
privacy 隐私遮蔽 布尔(0 / 1)

是否支持由摄像头固件决定,以返回的 supported 字段为准。

绝对值 vs 百分比

需求 使用
读当前绝对值,配合自己知道的 [min, max] 使用 getParam
读当前进度百分比(如进度条、显示“亮度 60%”) getParamPercent(或取 getParam 返回的 percent 字段)
写入已知范围的绝对值(如 brightness = 150) setParam
只知道进度比例、不想自己换算范围(如“设为 80%”) setParamPercent

换算规则:

  • 数值参数:percent = round((value - min) * 100 / (max - min)),写入时 value = min + round(percent * (max - min) / 100),结果截断在 [min, max] 内。
  • 布尔参数:current != 0 → 100,否则 0;写入时 percent >= 50 → 1,否则 0。
  • getBrightnessPercent / setBrightnessPercent、getContrastPercent / setContrastPercent 是 brightness / contrast 的百分比快捷方法,等价于 getParamPercent / setParamPercent。
  • 四个方法均要求摄像头已打开且参数 supported,否则回传 9010006(未打开)或 9010007(不支持的参数)。

事件

事件 说明
@onResult 各 API 调用结果:{ type, data: { code, msg, data } },与 success / fail 内容一致
@onDeviceState 设备状态:onCameraOpen / onCameraClose / onDetach / onCancel / onError
@load 组件初始化完成

错误码

错误码 含义
9010001 未发现 USB 摄像头设备 / 目标设备不存在 / 设备已拔出
9010002 设备无可用接口 / 切换摄像头失败
9010003 参数无效 / 拍照失败
9010004 录像相关失败(不支持录像、未在录像、开始 / 停止录像失败)
9010005 预留
9010006 摄像头未打开 / 未初始化
9010007 不支持的参数 / UVC 控制不可用 / 参数读写失败
9010008 预览或分辨率获取、设置失败
9010009 参数取值无效(分辨率、旋转角度、镜像模式非法)
9010010 当前平台不支持(iOS / HarmonyOS)
9010014 摄像头 / 录音权限被拒绝

权限

组件已在 utssdk/app-android/AndroidManifest.xml 中声明:

  • android.permission.CAMERA
  • android.permission.RECORD_AUDIO
  • <uses-feature android:name="android.hardware.usb.host" />

首次调用 openCamera 会自动申请运行时权限,被拒绝时回传 9010014。录像需额外的录音权限,被拒绝时同样回传 9010014。

注意事项

  • 依赖原生 AAR(utssdk/app-android/libs/libuvccamera-release.aar),运行至标准基座时原生部分不生效,需使用自定义基座。
  • <native-view> 不能作为带兄弟节点的元素的子节点,组件自身需具备宽高(width / height),且不支持 background / border 等样式。
  • 拍照、录像文件保存在应用私有目录 uvcX 下,success.data 中返回 path(绝对路径)与 uri。
  • setRotation 仅接受 0 / 90 / 180 / 270,setMirror 仅接受 0 / 1 / 2 / 3,取值非法回传 9010009。
  • 拔出 USB 设备会触发 @onDeviceState 的 onDetach,并回传 9010001。
  • 组件在 onUnmounted 时自动释放原生资源,页面卸载前无需手动调用销毁方法。

目录结构

zy-uvc-x/
├── components/zy-uvc-x/zy-uvc-x.uvue   # easycom 组件(方法转发 + defineExpose)
├── utssdk/
│   ├── interface.uts                   # 类型定义(Options / UvcResult / UvcError)
│   ├── app-android/
│   │   ├── index.uts                   # Android 实现
│   │   ├── utils.uts                   # 参数、设备、分辨率工具
│   │   ├── AndroidManifest.xml         # 权限与 USB feature 声明
│   │   └── libs/*.aar                  # libuvccamera
│   ├── app-ios/index.uts               # 占位实现(9010010)
│   └── app-harmony/index.uts           # 占位实现(9010010)
├── changelog.md
└── readme.md

参考

隐私、权限声明

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

"android.permission.CAMERA", "android.permission.RECORD_AUDIO"

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

无

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

无