更新记录
1.0.0(2026-11-03)
- 首次发布:uni-app x 标准模式插件(uts-vue-component),同时支持蒸汽(Vapor)模式
- module 方式:
takePhoto / startRecord / stopRecord / isRecording / deleteFile / getSupportedSizes / requestPermission,页面直接 import 调用,无需原生视图
- 组件方式:
<zy-camera-x> 预览相机,支持预览拍照、预览录像、前后摄像头切换、闪光灯 off/on/auto/torch
- 画质按档位传入:拍照
quality(uhd / fhd / hd / sd,不传取最大 JPEG 尺寸)与录像 quality(默认 fhd),component 与 module 一致;JPEG 压缩质量改用 jpegQuality
getSupportedSizes:查询设备支持的画质档位(uhd / fhd / hd / sd),按像素总数从大到小排列,quality 可直接传给 takePhoto / startRecord
- 预览画面等比铺满,不变形、无黑边
- 回调统一为
success / fail(UniError 规范),组件同时通过 @onEvent 派发原生事件
- 仅支持 Android,运行与调试需使用自定义基座
平台兼容性
uni-app x(4.27)
| Chrome |
Safari |
Android |
Android插件版本 |
iOS |
鸿蒙 |
微信小程序 |
| - |
- |
6.0 |
1.0.0 |
- |
- |
- |
zy-camera-x
uni-app x 无预览 自定义 标准模式相机插件(拍照 / 录像,uts-vue-component,支持蒸汽 Vapor 模式)。
- 仅实现 Android
- 两套用法:module 方式(页面直接 import 函数)与 组件方式(
<zy-camera-x> 预览相机)
- 回调统一为
success / fail(fail 为 UniError 规范实现的 CameraFail,带 errCode / errMsg)
- 必须使用自定义基座运行与打包
主要功能
- 无预览拍照 / 录像:不创建任何预览画面也能拍照、录像,适合后台抓拍、打卡补拍等场景
- 预览拍照 / 录像:
<zy-camera-x> 预览画面,支持边预览边录像,返回文件路径 / 大小 / 时长
- 前后摄像头切换、闪光灯(off / on / auto / torch)
- 自定义输出:画质档位(
uhd / fhd / hd / sd)、JPEG 压缩质量(1~100)、是否录音、
自定义文件名、自定义保存目录(绝对路径)、是否额外返回 base64
- 能力查询:查询摄像头支持的画质档位、查询当前是否正在录像
- 文件与权限:删除指定图片 / 视频文件(兼容
file:// 前缀)、一键申请相机 + 录音运行时权限
- 拍照 / 录像文件默认落在应用专属外部存储
Android/data/<包名>/files/zy-camera/photo|video,无需存储权限
一、module 方式(无需任何视图)
import {
takePhoto,
startRecord,
stopRecord,
deleteFile,
getSupportedSizes,
requestPermission
} from '@/uni_modules/zy-camera-x'
// 1. 先申请权限
requestPermission({
audio: true, // 是否同时申请录音权限:true=相机+录音,false=仅相机(默认 false)
success: (res) => console.log('granted=' + res.granted + ' audio=' + res.audioGranted),
fail: (err) => console.log(err.errCode + ' ' + err.errMsg)
})
// 2. 无预览拍照
takePhoto({
front: false, // 摄像头朝向:false=后置(默认),true=前置
quality: 'fhd', // 画质档位:'uhd' | 'fhd' | 'hd' | 'sd',不传则取最大 JPEG 尺寸
jpegQuality: 95, // JPEG 压缩质量 1~100,默认 95
base64: true, // 结果是否额外返回 base64(data:image/jpeg;base64,...),默认 false
success: (res) => console.log(res.path + ' ' + res.width + 'x' + res.height + ' ' + res.size),
fail: (err) => console.log(err.errCode + ' ' + err.errMsg)
})
// 3. 无预览录像
startRecord({
quality: 'fhd', // 画质档位:'uhd' | 'fhd' | 'hd' | 'sd',默认 'fhd'
audio: false, // 是否录制声音,默认 false(true 需已有录音权限)
success: (res) => console.log(res.msg)
})
// 结束并拿到文件信息
stopRecord({
success: (res) => console.log(res.path + ' ' + res.size + ' ' + res.duration),
fail: (err) => console.log(err.errMsg)
})
// 4. 查询摄像头支持的画质档位(按像素总数降序)
getSupportedSizes({
success: (res) => console.log(JSON.stringify(res.list))
})
// 5. 删除拍照/录像文件(路径兼容 file:// 前缀)
deleteFile({ path: '/storage/emulated/0/Android/data/xxx/files/zy-camera/photo/a.jpg' })
| 方法 |
说明 |
takePhoto(options) |
无预览拍照,返回值含 path / name / size / width / height / base64 |
startRecord(options) |
开始无预览录像(成功仅代表已开始) |
stopRecord(options) |
结束无预览录像,返回值含 path / name / size / duration |
deleteFile(options) |
删除指定文件,文件本就不存在也算成功(deleted=false) |
getSupportedSizes(options) |
查询摄像头支持的画质档位列表 |
requestPermission(options) |
申请相机权限(audio:true 时同时申请录音权限) |
isRecording() |
同步返回当前是否正在无预览录像 |
参数说明
requestPermission(options)
| 参数 |
类型 |
默认值 |
说明 |
audio |
boolean |
false |
是否同时申请录音权限:true=相机 + 录音,false=仅相机 |
success |
(res) => void |
- |
res = { code, msg, granted, audioGranted },granted 为相机权限结果 |
fail |
(err) => void |
- |
权限被拒绝(9200002)或拿不到 Activity(9200001) |
takePhoto(options)
| 参数 |
类型 |
默认值 |
说明 |
front |
boolean |
false |
摄像头朝向:false=后置,true=前置 |
quality |
string |
不限制 |
画质档位:'uhd'(4K) / 'fhd'(1080P) / 'hd'(720P) / 'sd'(480P);不传或未知值表示取该摄像头最大 JPEG 尺寸 |
jpegQuality |
number |
95 |
JPEG 压缩质量 1~100,超出范围按边界截断 |
fileName |
string |
时间戳命名 |
文件名,可带或不带 .jpg;重名自动追加 _1、_2 |
dir |
string |
外部存储目录/zy-camera/photo |
保存目录绝对路径,需自行保证可写 |
base64 |
boolean |
false |
true 时 res.base64 返回 data:image/jpeg;base64,... |
success |
(res) => void |
- |
res = { code, msg, path, name, size, width, height, base64 } |
fail |
(err) => void |
- |
失败原因见错误码表(9200002 / 9200003 / 9200004 / 9200010) |
startRecord(options)
| 参数 |
类型 |
默认值 |
说明 |
front |
boolean |
false |
摄像头朝向:false=后置,true=前置 |
quality |
string |
'fhd' |
画质档位:'uhd'(4K) / 'fhd'(1080P) / 'hd'(720P) / 'sd'(480P);档位不受支持时自动退到可用档位 |
audio |
boolean |
false |
是否录制声音,true 时必须已有录音权限,否则 9200002 |
fileName |
string |
时间戳命名 |
文件名,可带或不带 .mp4;重名自动追加 _1、_2 |
dir |
string |
外部存储目录/zy-camera/video |
保存目录绝对路径 |
success |
(res) => void |
- |
res = { code, msg },仅代表已开始录制,文件信息在 stopRecord 返回 |
stopRecord(options)
| 参数 |
类型 |
说明 |
success |
(res) => void |
res = { code, msg, path, name, size, duration },duration 单位毫秒 |
fail |
(err) => void |
当前没有正在进行的录像 / 输出文件无效(9200006) |
getSupportedSizes(options)
| 参数 |
类型 |
默认值 |
说明 |
front |
boolean |
false |
查询前置还是后置摄像头 |
success |
(res) => void |
- |
res = { code, msg, front, list: [{ quality, width, height }] },list 按像素总数降序,quality 可直接传给 takePhoto / startRecord |
fail |
(err) => void |
- |
相机服务不可用 / 该摄像头不支持对应输出(9200003) |
deleteFile(options)
| 参数 |
类型 |
说明 |
path |
string |
必填,文件绝对路径,兼容 file:// 前缀;空串或目录返回 9200009 |
success |
(res) => void |
res = { code, msg, path, deleted },文件本就不存在时也算成功(deleted=false) |
fail |
(err) => void |
删除失败(9200008) |
isRecording():无参数,同步返回 boolean,表示当前是否有无预览录像在进行。
保存目录:默认 App 外部存储目录/zy-camera/photo(图片)、.../zy-camera/video(视频),即
/storage/emulated/0/Android/data/<包名>/files/zy-camera/...,属于应用专属外部存储,不需要存储权限;
外部存储不可用时自动回退到内部 filesDir。拍照/录像均支持 dir(绝对路径)与 fileName 自定义。
二、组件方式(预览相机)
easycom 规范,无需 import 即可使用:
<template>
<view class="page">
<zy-camera-x ref="camRef" class="camera" @load="onload" @onEvent="onevent"></zy-camera-x>
<button @click="startPreview">开始预览</button>
<button @click="snap">拍照</button>
<button @click="record">开始录像</button>
<button @click="stopRec">停止录像</button>
</view>
</template>
<script setup lang="uts">
const camRef = ref<ComponentPublicInstance | null>(null)
function onload() {
console.log('组件初始化完成')
}
function startPreview() {
camRef.value?.$callMethod('start', {
front: false,
flash: 'off',
success: (res) => console.log('预览就绪 ' + res.width + 'x' + res.height),
fail: (err) => console.log(err.errCode + ' ' + err.errMsg)
})
}
function snap() {
camRef.value?.$callMethod('takePhoto', {
quality: 'fhd', // 画质档位
jpegQuality: 95, // 压缩质量
success: (res) => console.log('拍照成功 ' + res.path)
})
}
function record() {
camRef.value?.$callMethod('startRecord', { audio: false })
}
function stopRec() {
camRef.value?.$callMethod('stopRecord', {
success: (res) => console.log(res.path + ' ' + res.duration)
})
}
function onevent(e: UniNativeViewEvent) {
// { type: 'ready' | 'takePhoto' | 'startRecord' | 'stopRecord' | 'switchCamera' | 'flash' | 'error',
// code, msg, data }
console.log(JSON.stringify(e.detail))
}
</script>
<style>
.camera {
width: 100%;
height: 300px;
background-color: #000000;
}
</style>
| 组件方法 |
说明 |
start(options) |
开始预览,预览真正就绪时才触发 success(返回 front / width / height / flash) |
stop() |
停止预览并释放相机(无回调) |
takePhoto(options) |
预览拍照(quality 画质档位 / jpegQuality 压缩质量 / base64),返回 path / name / size / width / height / base64 |
startRecord(options) |
开始预览录像(quality: 'uhd'\|'fhd'\|'hd'\|'sd'、audio) |
stopRecord(options) |
结束预览录像,返回 path / name / size / duration |
switchCamera(options) |
切换前后摄像头,返回 front;录像/拍照进行中会被拒绝(9200010) |
setFlash(options) |
设置闪光灯 off / on / auto / torch,返回 flash |
onEvent 事件
| type |
时机 |
data |
ready |
预览就绪 |
{ front, width, height, flash } |
takePhoto |
拍照结束 |
{ path, name, size, width, height, base64 } |
startRecord |
录制已开始 |
{} |
stopRecord |
录制已结束 |
{ path, name, size, duration } |
switchCamera |
切换完成 |
{ front } |
flash |
闪光灯生效 |
{ flash } |
error |
相机断开等运行时错误 |
{} |
错误码
| errCode |
说明 |
| 9200001 |
无法获取当前应用环境(Activity 为空) |
| 9200002 |
未获得相机权限(或被拒绝) |
| 9200003 |
相机不可用(未找到摄像头 / 打开失败 / 被占用 / 组件已销毁) |
| 9200004 |
拍照失败 |
| 9200005 |
录像启动失败 |
| 9200006 |
录像停止失败(未在录制 / 输出文件无效) |
| 9200007 |
文件不存在 |
| 9200008 |
文件删除失败 |
| 9200009 |
参数不合法 |
| 9200010 |
当前状态不允许该操作(正在拍照 / 正在录制) |