Appearance
使用方法
安卓UVC摄像头UTS原生插件集成了同一个组件可在一个页面多次加载不同摄像头,插件支持自定义摄像头排版,同时集成了录像、拍照、设置镜像、亮度调节,摄像头设备按钮监听等功能,拍照可自定义水印,插件支持uniapp和uniapp x,支持vue2和vue3的选项式和组合式
使用建议
在app启动的时候可以先调用API的清除缓存功能,因为插件中使用了持久性缓存,有可能在app异常退出的时候加载的摄像头在缓存中导致摄像头再次加载时失败
联系作者

关注微信公众号可联系作者
插件地址
权限
- android.permission.CAMERA
- android.hardware.camera
- android.hardware.camera.autofocus
- android.permission.WRITE_EXTERNAL_STORAGE
- android.permission.READ_EXTERNAL_STORAGE
- android.hardware.usb.host
API用法
在使用插件的地方引入以下代码:
js
import * as module from "@/uni_modules/leven-uts-uvc"js
import * as module from "@/uni_modules/leven-uts-uvc"组件用法
在使用插件的地方引入以下代码:
vue
<leven-uts-uvc ref="refLevenUvc" style="flex:1; height: 300px;" :configX="config" @onError="onError"
@onEvent="onEvent" @onEventMethod="onEventMethod">
</leven-uts-uvc>
//组件的引用
const refLevenUvc = ref<LevenUtsUvcElement | null>(null)vue
<leven-uts-uvc ref="refLevenUvcCamera" style="flex:1; height: 500px; margin-bottom: 20px;" :config="config"
@onError="onError" @onEvent="onEvent" @onEventMethod="onEventMethod"></leven-uts-uvc>页面内容
API页面
vue
<template>
<view>
<button type="primary" @click="ApiClearCache">清除缓存</button>
<button type="primary" @click="requestPermissions">申请插件所需权限</button>
<button type="primary" @click="getDeviceList">获取摄像头列表</button>
<!-- <button type="primary" @click="requestUsbPermission">获取摄像头权限</button> -->
<button type="primary" @click="ApiUsbStatusListener">监听usb状态</button>
</view>
</template>
<script setup>
import * as module from "@/uni_modules/leven-uts-uvc"
//监听usb状态
function ApiUsbStatusListener() {
module.usbStatusListener({
success: (res : any) => {
console.log(res)
},
fail: (res : any) => {
console.log(res)
},
complete: (res : any) => {
console.log(res)
}
})
}
// //获取摄像头权限
// function requestUsbPermission() {
// module.requestUsbPermission(res => {
// console.log(res)
// })
// }
//获取摄像头列表
function getDeviceList() {
module.getDeviceList({
success: (res : any) => {
console.log(res)
},
fail: (res : any) => {
console.log(res)
},
complete: (res : any) => {
console.log(res)
}
})
}
//申请插件所需权限
function requestPermissions() {
module.requestPermissions({
success: (res : any) => {
console.log(res)
},
fail: (res : any) => {
console.log(res)
},
complete: (res : any) => {
console.log(res)
}
})
}
//清除缓存
function ApiClearCache() {
module.clearCache({
success: (res : any) => {
console.log(res)
},
fail: (res : any) => {
console.log(res)
},
complete: (res : any) => {
console.log(res)
}
})
}
</script>
<style>
</style>vue
<template>
<view>
<button type="primary" @click="clearCache">清除缓存</button>
<button type="primary" @click="requestPermissions">申请插件所需权限</button>
<button type="primary" @click="getDeviceList">获取摄像头列表</button>
<button type="primary" @click="requestUsbPermission">获取摄像头权限</button>
<button type="primary" @click="usbStatusListener">监听usb状态</button>
</view>
</template>
<script>
import * as module from "@/uni_modules/leven-uts-uvc"
export default {
data() {
return {
deviceName: ""
}
},
methods: {
requestUsbPermission() {
// module.requestUsbPermission({
// deviceName: this.deviceName
// }, res => {
// console.log(res);
// })
},
getDeviceList() {
// module.getDeviceList(res => {
// console.log(res)
// if (res && res.data) {
// let deviceList = res.data.deviceList;
// if (Array.isArray(deviceList) && deviceList.length > 0) {
// this.deviceName = deviceList[0].deviceName;
// }
// }
// })
module.getDeviceList({
success: (res) => {
console.log(res)
},
fail: (res) => {
console.log(res)
},
complete: (res) => {
console.log(res)
}
})
},
requestPermissions() {
module.requestPermissions({
success: (res) => {
console.log(res)
},
fail: (res) => {
console.log(res)
},
complete: (res) => {
console.log(res)
}
})
},
clearCache() {
module.clearCache({
success: (res) => {
console.log(res)
},
fail: (res) => {
console.log(res)
},
complete: (res) => {
console.log(res)
}
})
},
usbStatusListener() {
module.usbStatusListener({
success: (res) => {
console.log(res)
},
fail: (res) => {
console.log(res)
},
complete: (res) => {
console.log(res)
}
})
}
}
}
</script>
<style>
</style>组件页面
vue
<template>
<!-- #ifdef APP -->
<scroll-view style="flex:1">
<!-- #endif -->
<view>
<view style="width: 750rpx; height: 300px; position: relative;">
<leven-uts-uvc ref="refLevenUvc" style="flex:1; height: 300px;" :configX="config" @onError="onError"
@onEvent="onEvent" @onEventMethod="onEventMethod">
</leven-uts-uvc>
</view>
<view>
<button type="primary" @click="open">开启摄像头</button>
<button type="primary" @click="close">关闭摄像头</button>
<button type="primary" @click="startPreview">开启预览</button>
<button type="primary" @click="stopPreview">关闭预览</button>
<button type="primary" @click="startRecording">开始录像</button>
<button type="primary" @click="stopRecording">结束录像</button>
<button type="primary" @click="takePicture">拍照</button>
<button type="primary" @click="getDeviceList">获取摄像头列表</button>
<button type="primary" @click="switchCamera">切换摄像头</button>
<button type="primary" @click="fullScreen">全屏</button>
<button type="primary" @click="getBrightnessPercent">获取摄像头亮度百分比</button>
<button type="primary" @click="setBrightnessPercent">设置摄像头亮度百分比</button>
<button type="primary" @click="getContrastPercent">获取摄像头的对比度百分比</button>
<button type="primary" @click="setContrastPercent">设置摄像头对比度百分比</button>
<button type="primary" @click="setMirror">设置镜像</button>
<button type="primary" @click="getPreviewSize">获取预览分辨率</button>
<button type="primary" @click="getSupportedSizeList">获取支持的分辨率</button>
<button type="primary" @click="setButtonCallback">监听按钮</button>
</view>
</view>
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
</template>
<script lang="uts" setup>
import JSONObject from 'com.alibaba.fastjson.JSONObject'
//组件引用
const refLevenUvc = ref<LevenUtsUvcElement | null>(null)
//组件初始化配置
const config : UTSJSONObject = {
//视图的圆角值
"radius": 10,
//摄像头旋转角度
"rotation": 90,
//图片文件保存目录
"pictureDir": "/storage/emulated/0/Pictures/LevenUvcCamera/",
//视频保存目录
"videoDir": "/storage/emulated/0/Movies/LevenUvcCamera/",
//默认打开的摄像头deviceName,如果不是通过这个打开默认摄像头请不需要此参数
// "deviceName": "/dev/bus/usb/003/003",
//默认打开的摄像头产品名称
// "productName": "RXGD-CAMERA",
//默认分辨率
// size: {
// width: 800,
// height: 600,
// fps: 30
// }
}
//摄像头列表
const deviceList = ref<JSONObject[] | null>(null)
//当前摄像头索引
const deviceIndex = ref<Number>(0)
//镜像模式
const mirror = ref<Number>(0)
//**********************************方法*********************************
//监听按钮
function setButtonCallback() {
refLevenUvc.value?.setButtonCallback()
}
//获取支持的分辨率
function getSupportedSizeList() {
refLevenUvc.value?.getSupportedSizeList()
}
//获取预览分辨率
function getPreviewSize() {
refLevenUvc.value?.getPreviewSize()
}
//设置镜像
function setMirror() {
mirror.value++;
if (mirror.value > 4) {
mirror.value = 0;
}
let options : UTSJSONObject = {
//参数
"mirror": mirror.value
};
let params : JSONObject = JSONObject.parse(JSON.stringify(options)) as JSONObject
refLevenUvc.value?.setMirror(params)
}
//设置摄像头对比度百分比
function setContrastPercent() {
let options : UTSJSONObject = {
//参数
"percent": 30
};
let params : JSONObject = JSONObject.parse(JSON.stringify(options)) as JSONObject
refLevenUvc.value?.setContrastPercent(params)
}
//获取摄像头的对比度百分比
function getContrastPercent() {
refLevenUvc.value?.getContrastPercent()
}
//设置摄像头亮度百分比
function setBrightnessPercent() {
let options : UTSJSONObject = {
//参数
"percent": 30
};
let params : JSONObject = JSONObject.parse(JSON.stringify(options)) as JSONObject
refLevenUvc.value?.setBrightnessPercent(params)
}
//获取摄像头亮度百分比
function getBrightnessPercent() {
refLevenUvc.value?.getBrightnessPercent()
}
//全屏
function fullScreen() {
refLevenUvc.value?.fullScreen()
}
//切换摄像头
function switchCamera() {
if (deviceList.value == null || deviceList.value.length == 0) {
uni.showToast({
title: "请先获取摄像头列表",
icon: "none"
})
return;
}
deviceIndex.value++;
if (deviceIndex.value >= deviceList.value.length) {
deviceIndex.value = 0;
}
let deviceName = deviceList.value[deviceIndex.value].getString("deviceName")
let options : UTSJSONObject = {
//参数
"deviceName": deviceName
};
let params : JSONObject = JSONObject.parse(JSON.stringify(options)) as JSONObject
refLevenUvc.value?.switchCamera(params)
}
//获取摄像头列表
function getDeviceList() {
refLevenUvc.value?.getDeviceList()
}
//拍照
function takePicture() {
//拍照参数
let options : UTSJSONObject = {
//是否返回base64数据,默认:false
"base64": false,
//水印
"water": [{
//水印内容
"text": "这是一条测试水印",
//文本颜色,默认:白色
"color": "#FFFFFF",
//文本大小,默认:20
"textSize": 40,
//文本样式,NORMAL:常规(默认),BOLD:加粗,ITALIC:斜体,BOLD_ITALIC:斜体加粗
"typeFace": "NORMAL",
//是否使用抗锯齿功能,默认:true
"antiAlia": true,
//透明度(0~255),默认:128
"alpha": 128,
//水印位置,0:左上角(默认),1.右上角,2.左下角,3.右下角
"position": 2,
//水印左边距,默认:40
"leftMargin": 40,
//水印右边距,默认:40
"rightMargin": 40,
//水印上边距,默认:40
"topMargin": 40,
//水印下边距,默认:40
"bottomMargin": 40
}]
};
let params : JSONObject = JSONObject.parse(JSON.stringify(options)) as JSONObject
refLevenUvc.value?.takePicture(params);
}
//结束录像
function stopRecording() {
refLevenUvc.value?.stopRecording();
}
//开始录像
function startRecording() {
refLevenUvc.value?.startRecording();
}
//关闭预览
function stopPreview() {
refLevenUvc.value?.stopPreview();
}
//开启预览
function startPreview() {
refLevenUvc.value?.startPreview();
}
//关闭摄像头
function close() {
refLevenUvc.value?.close();
}
//开启摄像头
function open() {
refLevenUvc.value?.open();
}
//**********************************事件*********************************
//其他事件回调
function onEvent(e : JSONObject) {
console.log("onEvent:" + e.toJSONString())
}
//方法事件回调
function onEventMethod(e : JSONObject) {
console.log("onEventMethod:" + e.toJSONString())
}
//错误事件
function onError(e : JSONObject) {
console.log("onError:" + e)
}
</script>
<style>
</style>vue
<template>
<view>
<leven-uts-uvc ref="refLevenUvcCamera" style="flex:1; height: 500px; margin-bottom: 20px;" :config="config"
@onError="onError" @onEvent="onEvent" @onEventMethod="onEventMethod"></leven-uts-uvc>
<view>
<button type="primary" @click="open">开启摄像头</button>
<button type="primary" @click="close">关闭摄像头</button>
<button type="primary" @click="startPreview">开启预览</button>
<button type="primary" @click="stopPreview">关闭预览</button>
<button type="primary" @click="startRecording">开始录像</button>
<button type="primary" @click="stopRecording">结束录像</button>
<button type="primary" @click="takePicture">拍照</button>
<button type="primary" @click="getDeviceList">获取摄像头列表</button>
<button type="primary" @click="switchCamera">切换摄像头</button>
<button type="primary" @click="fullScreen">全屏</button>
<button type="primary" @click="getBrightnessPercent">获取摄像头亮度百分比</button>
<button type="primary" @click="setBrightnessPercent">设置摄像头亮度百分比</button>
<button type="primary" @click="getContrastPercent">获取摄像头的对比度百分比</button>
<button type="primary" @click="setContrastPercent">设置摄像头对比度百分比</button>
<button type="primary" @click="setMirror">设置镜像</button>
<button type="primary" @click="getPreviewSize">获取预览分辨率</button>
<button type="primary" @click="getSupportedSizeList">获取支持的分辨率</button>
<button type="primary" @click="setButtonCallback">监听按钮</button>
</view>
</view>
</template>
<script>
export default {
data() {
return {
config: {
//视图的圆角值
radius: 10,
//摄像头旋转角度
rotation: 90,
//图片文件保存目录
pictureDir: "/storage/emulated/0/Pictures/LevenUvcCamera/",
//视频保存目录
videoDir: "/storage/emulated/0/Movies/LevenUvcCamera/",
//默认打开的摄像头deviceName,如果不是通过这个打开默认摄像头请留空
// deviceName: "/dev/bus/usb/001/003",
//默认打开的摄像头产品名称
// productName: "RXGD-CAMERA",
//默认分辨率
// size: {
// width: 800,
// height: 600,
// fps: 30
// }
},
//摄像头列表
deviceList: [],
//当前摄像头的索引
deviceIndex: 0,
//镜像模式
mirror: 0
}
},
methods: {
//事件
onEventMethod(e) {
console.log(e)
},
onEvent(e) {
console.log(e)
},
onError(e) {
console.log(e)
},
//按钮点击事件
setButtonCallback() {
this.$refs.refLevenUvcCamera.setButtonCallback()
},
//获取支持的分辨率
getSupportedSizeList() {
this.$refs.refLevenUvcCamera.getSupportedSizeList()
},
//获取摄像头的对比度百分比
getPreviewSize() {
this.$refs.refLevenUvcCamera.getPreviewSize()
},
//设置镜像
setMirror() {
if (this.$refs.refLevenUvcCamera) {
this.mirror++;
if (this.mirror > 4) {
this.mirror = 0;
}
this.$refs.refLevenUvcCamera.setMirror({
//镜像,0.正常,1.垂直,2.水平,3.垂直+水平
mirror: this.mirror
})
}
},
//设置摄像头对比度百分比
setContrastPercent() {
this.$refs.refLevenUvcCamera.setContrastPercent({
percent: 30
})
},
//获取摄像头的对比度百分比
getContrastPercent() {
this.$refs.refLevenUvcCamera.getContrastPercent()
},
//设置当前摄像头亮度百分比
setBrightnessPercent() {
this.$refs.refLevenUvcCamera.setBrightnessPercent({
percent: 30
})
},
//获取当前摄像头亮度百分比
getBrightnessPercent() {
this.$refs.refLevenUvcCamera.getBrightnessPercent()
},
//全屏
fullScreen() {
this.$refs.refLevenUvcCamera.fullScreen()
},
//切换摄像头
switchCamera() {
if (this.$refs.refLevenUvcCamera) {
if (this.deviceList.length == 0) {
this.showToast("请先获取摄像头列表")
return;
}
if (this.deviceIndex >= this.deviceList.length) {
this.deviceIndex = 0;
} else {
this.deviceIndex++;
}
this.$refs.refLevenUvcCamera.switchCamera({
//摄像头名称
deviceName: this.deviceList[this.deviceIndex].deviceName
})
}
},
//获取摄像头列表
getDeviceList() {
this.$refs.refLevenUvcCamera.getDeviceList()
},
//拍照
takePicture() {
if (this.$refs.refLevenUvcCamera) {
this.$refs.refLevenUvcCamera.takePicture({
//是否返回base64数据,默认:false
base64: true,
//水印列表,不传或为空不添加水印
water: [{
//水印内容
text: "这是一条测试水印",
//文本颜色,默认:白色
color: "#FFFFFF",
//文本大小,默认:20
textSize: 40,
//文本样式,NORMAL:常规(默认),BOLD:加粗,ITALIC:斜体,BOLD_ITALIC:斜体加粗
typeFace: "NORMAL",
//是否使用抗锯齿功能,默认:true
antiAlia: true,
//透明度(0~255),默认:128
alpha: 128,
//水印位置,0:左上角(默认),1.右上角,2.左下角,3.右下角
position: 0,
//水印左边距,默认:40
leftMargin: 40,
//水印右边距,默认:40
rightMargin: 40,
//水印上边距,默认:40
topMargin: 40,
//水印下边距,默认:40
bottomMargin: 40
}]
})
}
},
//结束录像
stopRecording() {
this.$refs.refLevenUvcCamera.stopRecording()
},
//开始录像
startRecording() {
this.$refs.refLevenUvcCamera.startRecording()
},
//关闭预览
stopPreview() {
this.$refs.refLevenUvcCamera.stopPreview()
},
//开启预览
startPreview() {
this.$refs.refLevenUvcCamera.startPreview()
},
//关闭摄像头
close() {
this.$refs.refLevenUvcCamera.close()
},
//开启摄像头
open() {
this.$refs.refLevenUvcCamera.open()
},
showToast(title) {
uni.showToast({
icon: "none",
title: title
})
}
}
}
</script>
<style>
</style>