JS_0030:JS class 类的定义 调用

1,class类的定义 


class WebAR {
    /**
     * 初始化Web AR
     * @param interval 识别间隔(毫秒)
     * @param recognizeUrl 识别服务地址
     * @param isDebug 是否输入调试信息
     * @param token 非必需,使用token认证识别
     */
    constructor(interval, recognizeUrl, token) {
        this.isRecognizing = false;
        // 前/后置摄像头
        this.cameras = ["user", "environment"];
        this.interval = interval;
        this.recognizeUrl = recognizeUrl;
        this.token = token;
    }
    /**
     * 列表设备上的所有摄像头
     * @param videoDevice
     * @returns {Promise<T>}
     */
    listCamera(videoDevice) {
        return new Promise((resolve, reject) => {
            navigator.mediaDevices.enumerateDevices()
                .then((devices) => {
                let index = 1;
                devices.find((device) => {
                    if (device.kind === 'videoinput') {
                        const option = document.createElement('option');
                        // 在iOS12.2上deviceId为空
                        if (device.deviceId == '') {
                            option.text = device.label || 'camera ' + this.cameras[index];
                            option.value = JSON.stringify({ audio: false, video: { facingMode: { exact: this.cameras[index] } } });
                            index++;
                        }
                        else {
                            option.text = device.label || 'camera ' + (videoDevice.length + 1).toString();
                            option.value = JSON.stringify({ audio: false, video: { deviceId: { exact: device.deviceId } } });
                        }
                        // 将摄像头信息存储在select元素中,方便切换前、后置摄像头
                        videoDevice.appendChild(option);
                    }
                    return false;
                });
                if (videoDevice.length === 0) {
                    reject('没有可使用的视频设备');
                }
                else {
                    this.initVideo();
                    this.initCanvas();
                    resolve(true);
                }
            }).catch(err => {
                reject(err);
            });
        });
    }
    /**
     * 打开摄像头
     * 摄像头设置参数请查看: https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints
     * @param videoDeviceIndex
     * @returns {Promise<T>}
     */
    openCamera(constraints) {
        // 如果是切换摄像头,则需要先关闭。
        if (this.videoElement && this.videoElement.srcObject) {
            this.videoElement.srcObject.getTracks().forEach(track => {
                track.stop();
            });
        }
        return new Promise((resolve, reject) => {
            navigator.mediaDevices.getUserMedia(constraints)
                .then(stream => {
                    this.videoElement.srcObject = stream;
                    this.videoElement.style.display = 'block';
                    this.videoElement.play();
                    this.videoElement.onloadedmetadata = () => {
                        const cameraSize = {
                             this.videoElement.offsetWidth,
                            height: this.videoElement.offsetHeight
                        };
                        console.info(JSON.stringify(cameraSize));
                        if (window.innerWidth < window.innerHeight) {
                            // 竖屏
                            if (cameraSize.height < window.innerHeight) {
                                this.videoElement.setAttribute('height', window.innerHeight.toString() + 'px');
                            }
                        }
                        else {
                            // 横屏
                            if (cameraSize.width < window.innerWidth) {
                                this.videoElement.setAttribute('width', window.innerWidth.toString() + 'px');
                            }
                        }
                        resolve(true);
                    };
                })
                .catch(err => {
                    reject(err);
                });
        });
    }
    /**
     * 截取摄像头图片
     * @returns {string}
     */
    captureVideo() {
        this.canvasContext.drawImage(this.videoElement, 0, 0, this.videoElement.offsetWidth, this.videoElement.offsetHeight);
        // console.log(this.canvasElement.toDataURL('image/jpeg', 0.5).split('base64,')[1]);
        return this.canvasElement.toDataURL('image/jpeg', 0.5).split('base64,')[1];
    }
    /**
     * 创建视频详情元素,播放摄像头视频流
     */
    initVideo() {
        this.videoElement = document.createElement('video');
        this.videoElement.setAttribute('playsinline', 'playsinline');
        document.body.appendChild(this.videoElement);
    }
    /**
     * 创建canvas,截取摄像头图片时使用
     */
    initCanvas() {
        this.canvasElement = document.createElement('canvas');
        this.canvasElement.setAttribute('width', window.innerWidth.toString() + 'px');
        this.canvasElement.setAttribute('height', window.innerHeight.toString() + 'px');
        this.canvasContext = this.canvasElement.getContext('2d');
        // document.body.appendChild(this.canvasElement);
    }
    /**
     * 识别
     * @param callback
     */
    startRecognize(callback) {
        this.timer = window.setInterval(() => {
            // 等待上一次识别结果
            if (this.isRecognizing) {
                return;
            }
            this.isRecognizing = true;
            // 从摄像头中抓取一张图片
            const image = { image: this.captureVideo() };
            // 发送到服务器识别
            this.httpPost(image)
                .then((msg) => {
                    this.stopRecognize();
                    callback(msg);
                })
                .catch((err) => {
                    this.isRecognizing = false;
                    console.info(err);
                });
        }, this.interval);
    }
    /**
     * 停止识别
     */
    stopRecognize() {
        if (this.timer) {
            window.clearInterval(this.timer);
            this.isRecognizing = false;
        }
    }
    httpPost(image) {
        return new Promise((resolve, reject) => {
            const http = new XMLHttpRequest();
            http.onload = () => {
                try {
                    const msg = JSON.parse(http.responseText);
                    if (http.status === 200) {
                        if (msg.statusCode === 0) {
                            resolve(msg.result);
                        }
                        else {
                            reject(msg);
                        }
                    }
                    else {
                        reject(msg);
                    }
                }
                catch (err) {
                    reject(err);
                }
            };
            http.onerror = (err) => {
                reject(err);
            };
            http.open('POST', this.recognizeUrl);
            http.setRequestHeader('Content-Type', 'application/json;Charset=UTF-8');
            if (this.token) {
                // 将云识别认证token写在请求头中
                http.setRequestHeader('Authorization', this.token);
            }
            http.send(JSON.stringify(image));
        });
    }
}
//# sourceMappingURL=webar.js.map

2,类的创建和调用

// 别间隔时间(毫秒), 识别服务地址
// const webAR = new WebAR(1000, '/webar/recognize');
const webAR = new WebAR(1000, url, token);
// 列出并打开设备上的摄像头
document.querySelector('#openCamera').addEventListener('click', function () {
    const videoSelect = document.querySelector('#videoDevice');
    webAR.listCamera(videoSelect)
        .then(msg => {
            // 隐藏"打开摄像头"按钮
            this.style.display = 'none';
            videoSelect.style.display = 'inline-block';
            document.querySelector('#start').style.display = 'inline-block';
            document.querySelector('#stop').style.display = 'inline-block';
            videoSelect.onchange = () => {
                webAR.openCamera(JSON.parse(videoSelect.value));
            };
            // 打开摄像头
            // 打开后置摄像头参数: {audio: false, video: {facingMode: {exact: 'environment'}}}
            webAR.openCamera(JSON.parse(videoSelect.value))
                .then(msg => {
                console.info(msg);
            }).catch(err => {
                console.info(err);
            });
        })
        .catch(err => {
            // 没有找到摄像头
            console.info(err);
        });

        console.log("list0");
});
// 开启识别
document.querySelector('#start').addEventListener('click', () => {
    webAR.startRecognize((msg) => {
        console.info(msg);
        alert('识别成功');
    });
}, false);
// 暂停识别
document.querySelector('#stop').addEventListener('click', () => {
    webAR.stopRecognize();
}, false);
//# sourceMappingURL=app.js.map
琥珀君的博客
原文地址:https://www.cnblogs.com/eliteboy/p/13532324.html