更新记录

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

原生插件通用使用流程:

  1. 购买插件,选择该插件绑定的项目。
  2. 在HBuilderX里找到项目,在manifest的app原生插件配置中勾选模块,如需要填写参数则参考插件作者的文档添加。
  3. 根据插件作者的提供的文档开发代码,在代码中引用插件,调用插件功能。
  4. 打包自定义基座,选择插件,得到自定义基座,然后运行时选择自定义基座,进行log输出测试。
  5. 开发完毕后正式云打包

付费原生插件目前不支持离线打包。
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>

上海栾青网络科技有限公司

15921627041 (同微信)

隐私、权限声明

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

摄像头权限,录音权限,文件存储权限

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

插件不采集任何数据

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

使用中有什么不明白的地方,就向插件作者提问吧~ 我要提问