更新记录
1.0.1(2026-05-06)
修复安卓拍照返回带file头
1.0.0(2026-05-06)
支持android ios 自定义摄像头
平台兼容性
uni-app(4.0)
| Vue2 | Vue2插件版本 | Vue3 | Vue3插件版本 | Chrome | Safari | app-vue | app-vue插件版本 | app-nvue | app-nvue插件版本 | Android | Android插件版本 | iOS | iOS插件版本 | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| √ | 1.0.1 | √ | 1.0.1 | × | × | √ | 1.0.1 | √ | 1.0.1 | 8.0 | 1.0.1 | 12 | 1.0.1 | × |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| × | × | × | × | × | × | × | × | × | × | × | × |
uni-app x(4.0)
| Chrome | Safari | Android | Android插件版本 | iOS | iOS插件版本 | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|---|---|
| × | × | 8.0 | 1.0.1 | 12 | 1.0.1 | × | × |
jl-camera
jl-camera 是一个面向 uni-app / uni-app x App 端的 UTS 原生相机组件,当前支持 Android、iOS,提供相机预览、打开/关闭摄像头、切换前后摄像头、控制闪光灯、拍照、录像和 Base64 返回能力。
功能说明
- 打开摄像头并显示原生预览画面
- 关闭摄像头并回调关闭结果
- 切换前后摄像头
- Android 支持获取设备摄像头列表
- 打开或关闭闪光灯,并回调当前状态
- 拍照并返回临时图片路径、Base64 数据
- 支持拍照参数对象,可选控制
needBase64、quality(1-100)、enableWatermark - 支持开始录像、暂停录像、继续录像、停止录像
- 支持拍照水印,水印内容取自与相机同级容器中的可见叠加视图
- iOS 支持录像水印;Android 当前录像会保留原始视频文件,不对最终视频做水印合成
平台支持
| 能力 | Android | iOS |
|---|---|---|
| 打开/关闭摄像头 | 支持 | 支持 |
| 切换摄像头 | 支持 | 支持 |
| 闪光灯控制 | 支持 | 支持 |
获取摄像头列表 getCameras |
支持 | 不支持 |
| 拍照 | 支持 | 支持 |
| 拍照水印 | 支持 | 支持 |
| 开始/停止录像 | 支持 | 支持 |
| 暂停/继续录像 | 支持 | 当前回调提示暂不支持 |
| 录像水印 | 当前不支持最终视频合成 | 支持 |
组件属性
cameraId
- 类型:
Number - 默认值:
0 - 说明:默认摄像头,
0表示后置,1表示前置
scene
- 类型:
String - 默认值:
default - 说明:相机场景模式,当前可传
default、scan、photo - 平台差异:当前 iOS 已接入,Android 暂未使用该属性
videoGravity
- 类型:
String - 默认值:
fill - 说明:预览填充方式,可传
fill、fit、stretch - 平台差异:当前 iOS 已接入,Android 暂未使用该属性
orientation
- 类型:
Number - 默认值:
-1 - 说明:预览/录像方向,
-1为自动,其余值由原生侧解释
preview
- 类型:
Boolean - 默认值:
true - 说明:当前 iOS 组件保留该属性,暂未单独控制预览开关
- 平台差异:Android 当前未声明该属性
对外方法
通过 ref 获取组件实例后调用。
openCamera()
- 说明:打开摄像头
- 参数:无
- 返回值:无
- 成功/失败回调:事件
onOpen
closeCamera()
- 说明:关闭摄像头并释放资源
- 参数:无
- 返回值:无
- 成功/失败回调:事件
onClose
switchCamera()
- 说明:切换前后摄像头
- 参数:无
- 返回值:无
- 成功/失败回调:事件
onSwitch
getCameras()
- 说明:获取当前设备可用摄像头列表,仅 Android 支持
- 参数:无
- 返回值:无
- 成功/失败回调:事件
onGetCameras
this.$refs.camera.getCameras()
// 通过 onGetCameras 获取结果
onGetCameras(e) {
console.log(e.detail)
}
flashOpen()
- 说明:打开闪光灯
- 参数:无
- 返回值:无
- 成功/失败回调:事件
onFlash
flashClose()
- 说明:关闭闪光灯
- 参数:无
- 返回值:无
- 成功/失败回调:事件
onFlash
takePhoto(options)
- 说明:拍照
- 参数:
options?: { needBase64?: boolean, quality?: number, enableWatermark?: boolean } - 默认值:
- Android:
{ needBase64: false, quality: 75, enableWatermark: false } - iOS:
{ needBase64: false, quality: 75, enableWatermark: true }
- Android:
- 返回值:无
- 成功/失败回调:事件
onTakePhoto
startRecord(options)
- 说明:开始录像
- 参数:
options?: { videoEncodingBitRate?: number, videoWidth?: number, videoHeight?: number, orientation?: number, enableWatermark?: boolean, videoFrameRate?: number, audioSource?: number, outputFormat?: number, audioEncoder?: number, videoEncoder?: number } - 默认值:
- Android:
{ videoEncodingBitRate: 1920 * 1080, videoWidth: 1920, videoHeight: 1080, orientation: -1, enableWatermark: false, videoFrameRate: 30, audioSource: 1, outputFormat: 2, audioEncoder: 3, videoEncoder: 2 } - iOS:
{ videoEncodingBitRate: 1920 * 1080, videoWidth: 1920, videoHeight: 1080, orientation: -1, enableWatermark: true }
- Android:
- 平台差异:
videoFrameRate、audioSource、outputFormat、audioEncoder、videoEncoder当前仅 Android 使用 - 返回值:无
- 成功/失败回调:事件
onStartRecord
pauseRecord()
- 说明:暂停录像
- 参数:无
- 返回值:无
- 成功/失败回调:事件
onPauseRecord
resumeRecord()
- 说明:继续录像
- 参数:无
- 返回值:无
- 成功/失败回调:事件
onResumeRecord
stopRecord()
- 说明:停止录像并返回视频路径
- 参数:无
- 返回值:无
- 成功/失败回调:事件
onStopRecord
事件说明
onReady
- 说明:组件原生视图已创建完成,可以安全调用组件方法
- 返回示例:无参数
onOpen
- 说明:打开摄像头结果回调
{
detail: {
success: true,
errMsg: 'ok'
}
}
onClose
- 说明:关闭摄像头结果回调
{
detail: {
success: true,
errMsg: 'ok'
}
}
onSwitch
- 说明:切换摄像头结果回调
{
detail: {
success: true,
errMsg: 'ok'
}
}
onFlash
- 说明:设置闪光灯结果回调
{
detail: {
success: true,
errMsg: 'ok'
}
}
onGetCameras
- 说明:获取摄像头列表结果回调,仅 Android 支持
{
detail: {
success: true,
cameras: [
{
id: '0',
facing: 'back',
orientation: 90
},
{
id: '1',
facing: 'front',
orientation: 270
}
]
}
}
onTakePhoto
- 说明:拍照结果回调
- 说明:当
needBase64为false时,base64Str返回空字符串 - 说明:
quality取值范围为1-100,数值越大图片越清晰 - 说明:
enableWatermark为true时,插件会尝试把同级可见叠加视图绘制到最终图片中
{
detail: {
success: true,
tempImagePath: 'file:///xxx.jpg',
base64Str: 'xxxx',
errMsg: ''
}
}
onStartRecord
- 说明:开始录像结果回调
{
detail: {
success: true,
errMsg: 'ok'
}
}
onPauseRecord
- 说明:暂停录像结果回调
{
detail: {
success: true,
errMsg: 'ok'
}
}
onResumeRecord
- 说明:继续录像结果回调
{
detail: {
success: true,
errMsg: 'ok'
}
}
onStopRecord
- 说明:停止录像结果回调
- 说明:Android 侧结果对象可能额外包含
tempVideoPath和duration
{
detail: {
success: true,
path: 'file:///xxx.mp4',
errMsg: 'ok'
}
}
使用示例
<template>
<view class="container">
<view class="camera-stage" :style="{ width: windowWidth + 'px', height: windowHeight * 0.4 + 'px' }">
<jl-camera
ref="camera"
:cameraId="0"
scene="photo"
videoGravity="fill"
@onReady="onReady"
@onOpen="onOpen"
@onClose="onClose"
@onSwitch="onSwitch"
@onFlash="onFlash"
@onTakePhoto="onTakePhoto"
@onStartRecord="onStartRecord"
@onPauseRecord="onPauseRecord"
@onResumeRecord="Record"
@onStopRecord="onStopRecord"
style="display:flex;align-items:center;"
:style="{ width: windowWidth + 'px', height: windowHeight * 0.4 + 'px' }"
/>
<view class="watermark-layer">
<text class="watermark-title">巡检拍摄</text>
<text class="watermark-text">2026-04-07 10:30 深圳南山巡检点</text>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
windowWidth: 0,
windowHeight: 0,
isReady: false,
isOpen: false
}
},
onLoad() {
const sys = uni.getSystemInfoSync()
this.windowWidth = sys.windowWidth
this.windowHeight = sys.windowHeight
},
methods: {
onReady() {
this.isReady = true
},
onOpen(res) {
this.isOpen = !!(res.detail && res.detail.success)
},
onClose() {
this.isOpen = false
},
onSwitch(res) {
console.log('onSwitch', res)
},
onFlash(res) {
console.log('onFlash', res)
},
onTakePhoto(res) {
console.log('onTakePhoto', res)
},
onStartRecord(res) {
console.log('onStartRecord', res)
},
onPauseRecord(res) {
console.log('onPauseRecord', res)
},
Record(res) {
console.log('Record', res)
},
onStopRecord(res) {
console.log('onStopRecord', res)
},
openCamera() {
if (!this.isReady) return
this.$refs.camera.openCamera()
},
closeCamera() {
if (!this.isOpen) return
this.$refs.camera.closeCamera()
},
switchCamera() {
if (!this.isOpen) return
this.$refs.camera.switchCamera()
},
flashOpen() {
if (!this.isOpen) return
this.$refs.camera.flashOpen()
},
flashClose() {
if (!this.isOpen) return
this.$refs.camera.flashClose()
},
takePhoto() {
if (!this.isOpen) return
this.$refs.camera.takePhoto({ needBase64: false, quality: 100 })
},
startRecord() {
if (!this.isOpen) return
this.$refs.camera.startRecord({
videoEncodingBitRate: 1920 * 1080,
videoWidth: 1920,
videoHeight: 1080,
orientation: -1,
videoFrameRate: 30,
audioSource: 1,
outputFormat: 2,
audioEncoder: 3,
videoEncoder: 2
})
},
pauseRecord() {
this.$refs.camera.pauseRecord()
},
resumeRecord() {
this.$refs.camera.resumeRecord()
},
stopRecord() {
this.$refs.camera.stopRecord()
}
}
}
</script>
返回字段说明
通用结果对象
{
success: boolean,
errMsg?: string
}
拍照结果对象
{
success: boolean,
tempImagePath?: string,
base64Str?: string,
errMsg?: string
}
停止录像结果对象
{
success: boolean,
path?: string,
tempVideoPath?: string,
duration?: number,
errMsg?: string
}
注意事项
- 建议在
onReady之后再调用组件方法 - 建议在收到
onOpen成功回调后再调用拍照、切换摄像头、闪光灯相关方法 - 如仅用于页面预览,建议调用
takePhoto({ needBase64: false, quality: 75 }) quality越高,图片体积和处理耗时也会更高,请按实际场景调整- Android 录像参数中的
videoFrameRate、audioSource、outputFormat、audioEncoder、videoEncoder为 Android 专属参数 - iOS 当前仅支持开始录像和停止录像;暂停与继续会通过回调提示当前版本暂不支持
- 前置摄像头或部分设备可能不支持闪光灯,失败时请根据
onFlash.detail.errMsg提示用户 - Android 真机运行时,如插件依赖原生配置或三方 SDK,建议使用自定义基座验证完整能力
- Android 当前录像水印参数
enableWatermark不会对最终输出视频生效,停止录像后返回的是原始视频文件
水印说明
- 拍照水印在 Android、iOS 均可生效
- 录像水印当前仅 iOS 支持输出到最终视频;Android 会回退为原始录像文件
- 水印内容来自与
jl-camera位于同一父容器内、覆盖在预览区域上的可见视图 - 建议将
jl-camera和水印层放在同一个相对定位容器中,并确保水印层在视觉上覆盖于相机区域 - 水印层建议使用固定文案、时间、地点、Logo 等静态或低频更新内容,避免录制过程中频繁重排
- 如果未检测到同级可见叠加视图,则不会添加水印,拍照和录像将直接返回原始文件

收藏人数:
购买源码授权版(
试用
使用 HBuilderX 导入示例项目
赞赏(0)
下载 3
赞赏 0
下载 11803588
赞赏 1911
赞赏
京公网安备:11010802035340号