8***@qq.com
8***@qq.com
  • 发布:2022-06-18 16:42
  • 更新:2022-06-18 16:42
  • 阅读:247

live-pusher snapshot

分类:uni-app

产品分类: uniapp/App

PC开发环境操作系统: Windows

PC开发环境操作系统版本号: window10

HBuilderX类型: 正式

HBuilderX版本号: 3.3.11

手机系统: Android

手机系统版本号: Android 11

手机厂商: 华为

手机机型: HUAWEI Mate20

页面类型: nvue

vue版本: vue2

打包方式: 云端

项目创建方式: HBuilderX

示例代码:

<template>
<!--
照片OCR取景框页面,实现两个功能: 1. 实现相机 + 取景框的拍照组合; 2. 裁剪取景框内的元素
拍照:

  1. APP端使用 <live-pusher> 直播流模拟相机窗口。需要在manifest.json -> APP模块配置 里勾选 LivePusher 直播流
  2. 小程序只用 <camera> 组件模拟相机窗口
    裁剪:
  3. APP端无法使用 canvas 的API,因为使用的是nvue文件,目前不支持官方canvase的API,可以使用官方提供的gcanvas的API。(gcanvas的drawImage不允许临时路径)
  4. 小程序端通过canvas提供的API可以实现 --> <view class="live-camera" :style="{ width: ${windowWidth}px, height: ${windowHeight}px }"> <view class="preview" :style="{ width: ${windowWidth}px, height:${windowHeight - 90 }px }"> <!-- #ifdef APP-PLUS --> <live-pusher v-if="showLive" id="livePusher" ref="livePusher" class="livePusher" mode="FHD" beauty="0" whiteness="0" :aspect="aspect" min-bitrate="1000" audio-quality="16KHz" device-position="back" orientation="vertical" :auto-focus="true" :muted="true" :enable-camera="true" :enable-mic="false" zoom="true" @statechange="statechange" @error="error" max-bitrate="1000" style="{ width: ${cameraWidth }px, height: ${windowHeight - 90}px }"> </live-pusher>
    <!-- #endif -->
    <!-- #ifdef MP -->
    <!-- #endif -->
    </view>
    <!-- 取景框辅助线 -->
    <cover-view class="outline-box" <!-- style="{ width: ${cameraWidth }px, height: ${windowHeight - 180 }px }"> --> <!-- <p>覆盖的文字,很长的文字</p> -->
    <cover-image class="outline-img" :src=frame style="transform:rotate(90deg)"></cover-image>
    </cover-view>
    <view class="menu">
    <view class="photo" v-for="(image, index) in imagelist" :key="index" @click='magnify'>
    <image class="imglist" :src="image" mode="aspectFill"></image>
    </view>
    <cover-image class="phone" :src="takingPictures" mode="" @click="snapshot()">
    </cover-image>
    </view>
    </view>
    </template>

<script>
const n = uni.requireNativePlugin("FH-PatternRecognition");
import {
judgeIosPermission,
requestAndroidPermission,
gotoAppPermissionSetting
} from "@/js_sdk/wa-permission/permission.js"
export default {
data() {
return {
// 前置或后置摄像头,值为 front,back
devicePosition: "back",
// 打开相机的轮询
openCameraInterval: null,
// 操作类型
dotype: "idcardface",
// 提示
message: "",
// 比例
aspect: "4:3",
// 相机画面宽度
cameraWidth: "",
// 相机画面高度
cameraHeight: "",
// 屏幕可用宽度
windowWidth: "",
// 屏幕可用高度
windowHeight: "",
// 相机是否准备好了
cameraState: false,
// 流视频对象
livePusher: null,
// 快照
snapshotsrc: null,
type: null,
// 安卓机需要先判断有没有授权对应权限
showLive: false,
// 取景框内的图片
imageInfo: {},
// canvas 实例对象
context: {},
rpx2px: "",
// 取景框尺寸,可以根据需要进行调整
finder: {
width: 640,
height: 980
},
//存放拍摄的照片
// imagelist: [],
//ai拍摄的照片
imagelist: [],
takingPictures: "../../static/logininteraction/phone.png", //拍照按钮
number: 0, //AI拍照的张数
frame: null,
}
},
onLoad(e) {
const equipment = this.$store.state.buildinfo.odnPortInfos.length
if (equipment == 13) {
this.frame = "../../static/logininteraction/frame11.png"
}else if(equipment == 16){
this.frame = "../../static/logininteraction/frame4one.png"
}
//
console.log(n, '调用插件')
// uni.showToast({
// title:"请横屏拍摄!",
// icon:'none'
// })
this.type = e.type;
// 可能需要根据不同类型调整取景框大小
// plus.screen.lockOrientation('landscape-primary')
this.infoData = this.$store.state.infoData;
this.fiberNumber = this.$store.state.fiberNumber;
console.log(this.infoData, '传给SDK的模板数据')
console.log(this.fiberNumber, '拿到fiberNumber传给SDK')
this.path = uni.getStorageSync('path')
console.log(this.path, '存在本地的路径')
// var url=this.path.slice(7)
// this.scrpath.push(url)

        // console.log(this.scrpath,'显示本机路径')  
        // this.requestAndroidPermission()  
        this.initSDK();  
        // this.portRecognition(url)  
    },  
    onUnload() {  
        // plus.screen.lockOrientation('portrait-primary');  
    },  
    async onReady() {  
        console.log(this.initCamera(), '////////////')  
        this.initCamera();  

        // #ifdef APP-NVUE  
        if (plus.os.name === "Android") {  
            console.log("进入安卓")  
            await this.checkAndroidCamera();  
        } else {  
            this.showLive = true;  
        }  
        // #endif  
        // #ifdef MP  
        this.showLive = true;  
        if (await !this.checkCamera()) {  
            return  
        }  
        // #endif  

        // #ifdef APP-PLUS  
        if (this.showLive) {  
            this.$nextTick(() => {  
                this.livePusher = uni.createLivePusherContext("livePusher", this);  
                console.log("this.livePusher", this.livePusher);  
            })  
        }  
        // #endif  
    },  
    methods: {  
        // 初始化相机  
        initCamera() {  
            // 处理安卓手机异步授权问题  
            uni.getSystemInfo({  
                success: (res) => {  
                    console.log("手机信息", res)  
                    this.windowWidth = res.windowWidth;  
                    this.windowHeight = res.windowHeight;  
                    this.cameraWidth = res.windowWidth;  
                    this.cameraHeight = res.windowWidth * 1.5;  
                    this.rpx2px = 1 / 750 * res.windowWidth;  
                    let imgW = parseInt(this.finder.width * this.rpx2px),  
                        imgH = parseInt(this.finder.height * this.rpx2px) // 640和980是css里定义取景框的rpx宽度  
                    this.imageInfo = {  
                        width: imgW,  
                        height: imgH  
                    }  
                }  
            });  
        },  

        // 检查安卓相机权限  
        async checkAndroidCamera() {  
            let androidPermisson = await requestAndroidPermission("android.permission.CAMERA")  
            console.log("androidPermisson", androidPermisson);  
            if (androidPermisson === 1) {  
                this.showLive = true  
                // this.$nextTick(() => {  
                //  this.livePusher = uni.createLivePusherContext('livePusher', this);  
                //  console.log("this.livePusher", this.livePusher, this.$refs.LivePusher)  
                // })  
                setTimeout(() => {  
                    //开启预览并设置摄像头  
                    this.startPreview();  
                    this.poenCarme()  
                }, 100)  
            } else {  
                uni.showModal({  
                    content: "请打开摄像头授权功能!",  
                    showCancel: false,  
                    success: (res) => {  
                        if (res.confirm) gotoAppPermissionSetting()  
                    }  
                })  
            }  
            console.log("checkAndriodCamera", androidPermisson)  
        },  

        // 检查照相机权限  
        checkCamera() {  
            return new Promise(async (resolve) => {  
                // #ifdef APP-PLUS  
                if ((plus.os.name === "iOS" && !judgeIosPermission("camera"))) {  
                    uni.showModal({  
                        content: "请打开摄像头授权功能!",  
                        showCancel: false,  
                        success: (res) => {  
                            if (res.confirm) gotoAppPermissionSetting()  
                        }  
                    })  
                    resolve(false)  
                } else if (plus.os.name === "Android") {  
                    let androidPermisson = await requestAndroidPermission("android.permission.CAMERA")  
                    console.log(androidPermisson)  
                    if (androidPermisson < 1) {  
                        uni.showModal({  
                            content: "请打开摄像头授权功能!",  
                            showCancel: false  
                        })  
                        resolve(false)  
                    } else {  
                        resolve(true)  
                    }  
                } else {  
                    resolve(true)  
                }  
                // #endif  
                // #ifdef MP  
                uni.getSetting({  
                    success: (sRes) => {  
                        console.log(sRes)  
                        if (sRes.authSetting["scope.camera"] === false) {  
                            uni.showModal({  
                                content: "请打开摄像头授权功能!",  
                                showCancel: false  
                            })  
                            resolve(false)  
                        } else {  
                            resolve(true)  
                        }  
                    },  
                    fail: (err) => {  
                        console.log(err)  
                    }  
                })  
                // #endif  
            })  
        },  

        // 轮询打开  
        async poenCarme() {  
            //#ifdef APP-PLUS  
            if (plus.os.name == 'Android') {  
                this.poenCarmeInterval = setInterval(() => {  
                    if (!this.camerastate) this.startPreview();  
                }, 1000);  
            }  
            //#endif  
        },  

        // 开始预览  
        startPreview() {  
            console.log('开始预览')  
            console.log('this.livePusher', this.livePusher);  
            console.log('this.livePusher', this.livePusher.startPreview());  
            this.livePusher.startPreview({  
                success: async (a) => {  
                    //直播推流默认是前置摄像头,预览成功后给转成后置摄像头  
                    if (plus.os.name == "iOS") {  
                        this.livePusher.switchCamera();  
                        this.camerastate = true;  
                    }  
                }  
            });  
        },  

        error(e) {  
            clearInterval(this.poenCarmeInterval)  
            console.log("error:" + JSON.stringify(e));  
            if (e.detail.errCode === 10001) {  
                uni.showModal({  
                    content: "请打开摄像头授权功能!",  
                    showCancel: false,  
                    success: (res) => {  
                        if (res.confirm) gotoAppPermissionSetting()  
                    }  
                })  
            }  
        },  

        //停止预览  
        stopPreview() {  
            this.livePusher.stopPreview({  
                success: a => {  
                    this.camerastate = false; //标记相机未启动  
                }  
            });  
        },  

        //状态  
        statechange(e) {  
            //状态改变  
            console.log(e);  
            if (e.detail.code == 1003 || e.detail.code == 1007) { //1007  
                this.camerastate = true;  
            } else if (e.detail.code == -1301) {  
                this.checkCamera()  
                this.camerastate = false;  
            }  
        },  

        //返回  
        back() {  
            uni.navigateBack();  
        },  
        /**  
         * 抓拍,因为APP端用的gcanvas,gcanvas.drawImage不允许临时图片,所以要先传一次图片  
         * **/  
        snapshot() {  
            const that = this;  
            console.log("点击事件")  
            // uni.navigateTo({  
            //  url:"../facilityFlow/facilityFlow"  
            // })  
            if (!this.checkCamera()) {  
                return false  
            }  
            //震动  
            uni.vibrateShort();  
            // #ifdef APP-PLUS  
            console.log("进入上传")  
            console.log(this.livePusher, '抓拍创建livepush')  
            console.log(this.livePusher.snapshot, '抓拍事件')  
            this.livePusher.snapshot({  
                success: async e => {  
                    that.number++  
                    console.log("snapshot成功", e);  
                    console.log(JSON.stringify(e));  
                    // that.image = e.message.tempImagePath;  
                    console.log("拍照计数", that.number);  
                    if (that.number <= 4) {  
                        that.imagelist.push(e.message.tempImagePath)  
                    }  
                    uni.saveImageToPhotosAlbum({  
                        filePath: e.message.tempImagePath,  
                        success: function(t) {  
                            console.log(t, '保存本地图片')  
                            this.path = t.path;  
                            console.log(this.path, '路径')  
                            uni.compressImage({  
                                src: this.path,  
                                quality: 100,  
                                rotate: 270,  
                                success: res => {  
                                    console.log(res.tempFilePath)  
                                    uni.saveImageToPhotosAlbum({  
                                        filePath: res.tempFilePath,  
                                        success: function(t) {  
                                            console.log(t,  
                                                '保存本地图片')  
                                            that.path = t.path;  
                                            console.log(that.path,  
                                                '路径')  
                                            uni.setStorageSync(  
                                                'path',  
                                                that.path);  
                                            that.portRecognition(  
                                                that  
                                                .path)  
                                        }  
                                    });  
                                }  
                            })  
                        }  
                    });  
                    var res = JSON.stringify(e.message.tempImagePath);  
                    // console.log(res)  
                    // uni.navigateTo({  
                    //  // url:`../../sbz/sbz?data=${res}`  
                    //  url: 'imageRecognition/imageRecognition'  
                    // })  
                    this.uploadImage(`file://${e.message.tempImagePath}`);  
                },  
                fail: err => {  
                    console.log(err)  
                }  
            });  
            // #endif  
            // #ifdef MP  
            // const ctx = uni.createCameraContext();  
            // ctx.takePhoto({  
            //  quality: 'high',  
            //  success: (res) => {  
            //          this.uploadImage(res.tempImagePath)  
            //  }  
            // });  
            // #endif  
        },  

        /**  
         * 获取临时路径的图片宽高大小  
         * **/  
        magnify() {  
            let that = this  
            console.log("图片点击事件", 11111);  
            uni.previewImage({  
                urls: that.imagelist,  
                loop: true  
            });  
            console.log("图片点击事件预览照片", that.image);  
        },  
        getImageInfo(path) {  
            console.log(path)  
            return new Promise((resolve, reject) => {  
                uni.getImageInfo({  
                    src: path,  
                    success: (res) => {  
                        resolve(res)  
                    },  
                    fail: (err) => {  
                        reject(err)  
                        resolve(err)  
                    }  
                })  
            })  
        },  

        // async uploadImage(path){  
        //  let info = await this.getImageInfo(path) //获取临时路径的图片宽高大小  
        //  let width = Math.round( this.rpx2px*this.finder.width/this.cameraWidth*info.width),height = Math.round(this.rpx2px*this.finder.height/(this.windowHeight-90)*info.height)  
        //  let x = parseInt((info.width-width)/2),y = parseInt((info.height-height)/2)  
        //  console.log("path", path);  
        //  uni.uploadFile({  
        //      "url": "http://10.199.101.201:4200/picRelationInfo/uploadImageForLive",  
        //      "url": "http://10.99.20.131:9301/picRelationInfo/uploadImageForLive",  
        //      "url": "https://www.example.com/upload",  
        //      "filePath": path,  
        //      "name": "file",  
        //      "formData": {  
        //          "objectId": "",  
        //          "objectType": 3,  
        //          "resource": 2,  
        //          "pic": {}  
        //      },  
        //      "success": (res) => {  
        //          console.log("图片上传成功222",res);  
        //      },  
        //      "fail": (err) => {  
        //          console.log("err", err)  
        //      },  
        //      "complete": (complete) => {  
        //          console.log("complete", complete);  
        //      }  
        //  })  
        //  // uploadFileOSS(path).then( res => {  
        //  //  this.snapshotsrc = res.url + `?x-oss-process=image/crop,x_${x},y_${y},w_${width},h_${height}/rotate,270`  
        //  //  console.log(this.snapshotsrc)  
        //  //  this.setImage({x,y,width,height});  
        //  //  uni.navigateBack({  
        //  //      delta:2  
        //  //  })  
        //  // }).catch( err => {  
        //  //  console.log(err)  
        //  //  errorMsg(err)  
        //  // })  
        // },  

        //反转  
        flip() {  
            // #ifdef APP-PLUS  
            this.livePusher.switchCamera();  
            // #endif  
            // #ifdef MP  
            this.devicePosition = this.devicePosition === 'back' ? 'front' : 'back'  
            // #endif  
        },  

        //设置  
        setImage(x, y, width, height) {  
            let pages = getCurrentPages();  
            let prevPage = pages[pages.length - 3]; //上二个页面  
            //直接调用上二个页面的setImage()方法,把数据存到上二个页面中去  
            prevPage.$vm.setImage({  
                path: this.snapshotsrc,  
                type: this.type  
            });  
        },  
        initSDK() {  
            n.initSDK();  
            uni.setStorageSync('start', 0)  
        },  
        portRecognition(url) {  
            let _this = this;  
            const equipment = this.$store.state.buildinfo.odnPortInfos.length  
            console.log("equipment", equipment);  

            url = url.slice(7)  
            // console.log(this.infoData,'this.infoData,')  
            // console.log(this.fiberNumber,'this.fiberNumber,')  
            if (uni.getStorageSync('start') == 0) {  
                uni.setStorageSync('start', 1);  
                n.start(  
                    this.infoData,  
                    this.fiberNumber  
                )  
            }  
            // console.log (n.getDeviceType(),'11111111111111111')  
            // 识别方法  
            console.log(url)  
            n.portRecognition(  
                url,  
                (function(t) {  
                    console.log(url)  
                    console.log(t);  
                    if (t.code == '48') {  
                        _this.file_path = t.file_path  
                        console.log(_this.file_path, '///////////////////')  
                        _this.info = JSON.parse(t.msg);  
                        console.log(_this.info, '=====================')  
                        _this.info.portInfos.forEach(item => {  
                            if (item.iState === -1) {  
                                item.iState = 2;  
                            }  
                        })  
                        _this.$store.state.portServerList = _this.info.portInfos;  
                        // _this.$store.state.buildinfo.odnPortInfos=newbuildinfo  
                        console.log(_this.$store.state.portServerList, '预备修改端口默认值')  
                        //端口识别成功  
                        if (_this.info.bPortFinish == true) {  
                            if (equipment == 16) {  
                                 _this.frame ="../../static/logininteraction/barcode4.png"  
                            } else if (equipment == 13) {  
                                _this.frame ="../../static/logininteraction/barcode.png"  
                            }  
                            //防止sdk识别不了卡流程  
                            uni.showToast({  
                                title: '请识别条形码',  
                                icon: 'none'  
                            })  

                            //端口条码都识别成功可以直接跳转设施流程  
                            if (_this.info.bBarFinish == true) {  
                                //ai采集的到的数据赋值给odnPortInfos  
                                let b = JSON.parse(JSON.stringify(_this.$store.state  
                                    .portServerList))  
                                let a = JSON.parse(JSON.stringify(_this.$store.state.buildinfo  
                                    .odnPortInfos))  
                                console.log("a-----", a);  
                                console.log("b----", b);  
                                for (let i = 0; i < a.length; i++) {  
                                    for (let j = 0; j < b.length; j++) {  
                                        if (a[j].iState != b[j].iState) {  
                                            a[j].iState = b[j].iState  
                                            if (b[j].strBarCode) {  
                                                a[j].strBarcode = b[j].strBarCode  
                                            }  
                                        }  
                                    }  

                                }  
                                console.log("a-----", a);  
                                //buildinfo整合数据  
                                _this.$store.state.buildinfo.odnPortInfos = a  
                                console.log("_this.$store.state.buildinfo", _this.$store.state.buildinfo);  
                                _this.$store.state.currentStep = 2  
                                uni.navigateTo({  
                                    url: '../facilityFlow/facilityFlow'  
                                })  
                                uni.showToast({  
                                    title: '识别完成',  
                                    icon: 'none'  
                                })  
                            } else {  
                                if (equipment == 16) {  
                                    _this.frame ="../../static/logininteraction/barcode4.png"  
                                } else if (equipment == 13) {  
                                    console.log(11111111);  
                                    _this.frame ="../../static/logininteraction/barcode3.png"  
                                }  
                                uni.showToast({  
                                    title: '请补录一次条形码',  
                                    icon: 'none'  
                                })  
                            }  
                        } else {  
                            console.log("frame1", _this.frame1);  
                            if (equipment == 16) {  
                                _this.frame ="../../static/logininteraction/frame4.png"  
                            } else if (equipment == 13) {  
                                console.log(11111111);  
                                _this.frame ="../../static/logininteraction/frame1.png"  
                            }  
                            uni.showToast({  
                                title: '请补录一次端口',  
                                icon: 'none'  
                            })  
                        }  
                        // console.log("最后的值buildinfo",_this.$store.state.buildinfo);  
                        if (_this.number == 4) {  
                            //ai采集的到的数据赋值给odnPortInfos  
                            let b = JSON.parse(JSON.stringify(_this.$store.state  
                                .portServerList))  
                            let a = JSON.parse(JSON.stringify(_this.$store.state.buildinfo  
                                .odnPortInfos))  
                            console.log("a-----", a);  
                            console.log("b----", b);  
                            for (let i = 0; i < a.length; i++) {  
                                for (let j = 0; j < b.length; j++) {  
                                    if (a[j].iState != b[j].iState) {  
                                        a[j].iState = b[j].iState  
                                        if (b[j].strBarCode) {  
                                            a[j].strBarcode = b[j].strBarCode  
                                        }  
                                    }  
                                }  

                            }  
                            console.log("a-----", a);  
                            //buildinfo整合数据  
                            _this.$store.state.buildinfo.odnPortInfos = a  
                            console.log("_this.$store.state.buildinfo", _this.$store.state.buildinfo);  
                            _this.$store.state.currentStep = 2  
                            uni.navigateTo({  
                                url: '../facilityFlow/facilityFlow'  
                            })  
                        }  
                    } else {  
                        if (_this.number == 4) {  
                            //ai采集的到的数据赋值给odnPortInfos  
                            let b = JSON.parse(JSON.stringify(_this.$store.state  
                                .portServerList))  
                            let a = JSON.parse(JSON.stringify(_this.$store.state.buildinfo  
                                .odnPortInfos))  
                            console.log("a-----", a);  
                            console.log("b----", b);  
                            for (let i = 0; i < a.length; i++) {  
                                for (let j = 0; j < b.length; j++) {  
                                    if (a[j].iState != b[j].iState) {  
                                        a[j].iState = b[j].iState  
                                        if (b[j].strBarCode) {  
                                            console.log(b[j].strBarCode, "b[j].strBarCode");  
                                            a[j].strBarcode = b[j].strBarCode  
                                        }  
                                    }  
                                }  

                            }  
                            console.log("a-----", a);  
                            //buildinfo整合数据  
                            _this.$store.state.buildinfo.odnPortInfos = a  
                            console.log("_this.$store.state.buildinfo", _this.$store.state.buildinfo);  
                        }  
                        //sdk未识别照片  
                        uni.showToast({  
                            title: '识别失败请补录一次条形码',  
                            icon: 'none'  
                        })  
                        return  
                    }  

                })  
            )  

        },  

    }  
}  

</script>

<style>
.preview {
justify-content: center;
align-items: center;
position: relative;
z-index: 1;
}

.preview .canvas {  
    /* visibility: hidden; */  
    position: absolute;  
    top: 0;  
    z-index: -1;  
}  

.preview .gcanvas {  
    z-index: -1;  
    position: absolute;  
}  

.outline-box {  
    position: absolute;  
    top: 50%;  
    left: 50px;  
    bottom: 0;  
    z-index: 99;  
    transform: translateY(-50%);  
    align-items: center;  
    justify-content: center;  
    display: flex;  
}  

.outline-img {  
    position: absolute;  
    top: 300rpx;  
    left: 0rpx;  
    z-index: 999;  
    /* width: 640rpx;  
height: 320rpx; */  
    width: 800rpx;  
    height: 500rpx;  
}  

.outline-img1 {  
    position: absolute;  
    top: 400rpx;  
    left: 0rpx;  
    z-index: 999;  
    /* width: 640rpx;  
height: 320rpx; */  
    width: 800rpx;  
    height: 400rpx;  
}  

.phone {  
    position: fixed;  
    bottom: 50rpx;  
    left: 320rpx;  
    width: 128rpx;  
    height: 128rpx;  
}  

.photo {  
    z-index: 999;  
    position: fixed;  
    bottom: 50rpx;  
    left: 20rpx;  
    width: 180rpx;  
    height: 120rpx;  
    border: 1px solid #d8d8d8;  
    /* transform:rotate(-90deg) */  
}  

.photo-number {  
    position: fixed;  
    bottom: 125rpx;  
    left: 185rpx;  
}  

</style>

操作步骤:

调用自定义拍照界面进行拍照

预期结果:

正常拍照

实际结果:

白屏

bug描述:

[JS Framework] Failed to execute the callback function:
16:33:34.654 TypeError: e[t] is not a function
16:33:34.686 reportJSException >>>> exception function:WEEX_CALL_JAVASCRIPT, exception:JavaScript execute error!Uncaught TypeError: e[t] is not a function

2022-06-18 16:42 负责人:无 分享
已邀请:

该问题目前已经被锁定, 无法添加新回复