更新记录
1.2.8(2023-12-11)
优化插件性能,增加start和takePhoto方法可以指定保存的文件名
1.2.5(2023-12-06)
android + ios两端上线
平台兼容性
Android | Android CPU类型 | iOS |
---|---|---|
适用版本区间:7.0 - 14.0 | armeabi-v7a:未测试,arm64-v8a:未测试,x86:未测试 | 适用版本区间:11 - 17 |
原生插件通用使用流程:
- 购买插件,选择该插件绑定的项目。
- 在HBuilderX里找到项目,在manifest的app原生插件配置中勾选模块,如需要填写参数则参考插件作者的文档添加。
- 根据插件作者的提供的文档开发代码,在代码中引用插件,调用插件功能。
- 打包自定义基座,选择插件,得到自定义基座,然后运行时选择自定义基座,进行log输出测试。
- 开发完毕后正式云打包
付费原生插件目前不支持离线打包。
Android 离线打包原生插件另见文档 https://nativesupport.dcloud.net.cn/NativePlugin/offline_package/android
iOS 离线打包原生插件另见文档 https://nativesupport.dcloud.net.cn/NativePlugin/offline_package/ios
注意事项:使用HBuilderX2.7.14以下版本,如果同一插件且同一appid下购买并绑定了多个包名,提交云打包界面提示包名绑定不一致时,需要在HBuilderX项目中manifest.json->“App原生插件配置”->”云端插件“列表中删除该插件重新选择
luanqing-recording
相机自定义界面 横屏拍照录像 原生插件 横屏录像 横屏拍照 通过cover-view在界面上增加自己的UI
API 说明
start和takePhoto方法可以携带一个指定的string类型文件名(无需后缀),插件会分别以指定的名字来保存照片或视频,如takePhoto("img_2023"),则拍照后保存的文件全路径是: /storage/emulated/0/Android/data/net.luanqing.nativeplugin/files/Pictures/img_2023.jpg,开发者可以通过名字控制保存的文件数量,如果每次拍照或录像都传 相同的名字则始终只会存在一份照片/视频文件(以新换旧覆盖之前的文件),也可以用毫秒级时间戳做文件名,这样在毫秒级之间不会存在重复,相当于每次都会保存新文件,不会覆盖。
名称 | 说明 | 默认值 | 是否必须 |
---|---|---|---|
start | 开始录像,可携带一个string参数,指定文件名 | my_video | 是 |
stop | 停止录像 | 无 | 非 |
pause | 暂停录像 | 无 | 非 |
resume | 恢复录像 | 无 | 非 |
resume | 恢复录像 | 无 | 非 |
takePhoto | 拍照,可携带一个string参数,指定文件名 | my_image | 非 |
回调函数说明
可以通过status-change回调函数接收数据 返回的数据格式:
{
"code": 1103,
"message": "照片保存成功",
"imagePath": "/var/mobile/Containers/Data/Application/28AEC065-2EA3-4B0A-96EA-C8A1D7CEB629/Documents/1701754661642.jpg",
"videoPath": ""
}
code|说明
--|-- 1000|开始录像 1001|暂停录像 1002|恢复录像 1003|停止录像 1004|视频保存成功,监听status-change获取视频文件路径 1100|开始拍照 1101|拍照成功 1102|拍照失败 1103|照片文件保存成功 1104|照片文件保存失败 1009|已包含所需权限(安卓独特) 1010|已包含所需权限(安卓独特) 2000|其他调试日志输出
用法代码示例
<template>
<view class="container uni_flex_col_align_center" style="position: relative;">
<!-- 相机原生插件 START -->
<luanqing-recording
ref="cameraObj"
@status-change="onStatusChange"
:style="'width:'+(screenWidth)+'px;height:'+(screenHeight)+'px;'"
>
</luanqing-recording>
<!-- 相机原生插件 END -->
<cover-view class="fl">
<cover-view class="btn" @click="onStart">开始</cover-view>
<cover-view class="btn" @click="onStop">停止</cover-view>
<cover-view class="btn" @click="onPause">暂停</cover-view>
<cover-view class="btn" @click="">继续</cover-view>
<cover-view class="btn" @click="takePhoto">拍照</cover-view>
</cover-view>
</view>
</template>
<script>
export default {
data() {
return {
screenWidth: 0,
screenHeight: 0,
}
},
onLoad() {
// #ifdef APP-PLUS
plus.screen.lockOrientation('landscape-primary');
// 隐藏顶部电池,时间等信息
plus.navigator.setFullscreen(true);
// #endif
},
onShow() {
let that = this;
if (uni.getSystemInfoSync().platform == "ios") {
let screenWidth = uni.getSystemInfoSync().windowWidth;
let screenHeight = uni.getSystemInfoSync().windowHeight;
that.screenWidth = screenWidth > screenHeight ? screenWidth : screenHeight;
that.screenHeight = screenHeight < screenWidth ? screenHeight : screenWidth;
}else{
setTimeout(()=>{
let screenWidth = uni.getSystemInfoSync().windowWidth;
let screenHeight = uni.getSystemInfoSync().windowHeight;
that.screenWidth = screenWidth;
that.screenHeight = screenHeight;
},1000);
}
},
onUnload() {
// #ifdef APP-PLUS
plus.screen.unlockOrientation();
// 隐藏顶部电池,时间等信息
plus.navigator.setFullscreen(false);
// #endif
},
methods: {
takePhoto(){
this.$refs.cameraObj.takePhoto();
},
onStatusChange(status){
let detail = status.detail || {};
// 保存成功并返回视频文件路径
if(detail.code === 1004){
let path = detail.videoPath;
console.error("视频录制并保存成功,路径为:", path);
}else{
console.error("插件状态日志:", detail.message, detail);
}
},
onStart(){
this.$refs.cameraObj.start();
},
onStop(){
this.$refs.cameraObj.stop();
},
onPause(){
this.$refs.cameraObj.pause();
},
(){
this.$refs.cameraObj.resume();
},
}
}
</script>
<style>
.container {
display: flex;
flex: 1;
background-color: #111111;
}
.btn{
width: 125rpx;
padding: 10rpx 28rpx;
font-size: 30rpx;
color: #ffffff;
display: flex;
align-items: center;
justify-content: center;
background-color: rgba(150, 150, 150, 0.7);
}
.fl{
position: fixed;
left: 25;
bottom: 10;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
min-width: 550rpx;
}
.uni_flex_col_align_center {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
</style>