h5调用摄像头拍照并获取陀螺仪数据

先上代码,后面给出兼容性测试结果:


<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    <title>后置摄像头+陀螺仪title>
head>

<style>
    body {
      
        margin: 0;
        padding: 0;
        width: 100%;
        height: 100%;
        overflow: hidden;
    }

    video {
      
        margin: 0;
        padding: 0;
        margin-top: -10px;
        width: 100%;
        height: 100%;
    }



    #capture {
      
        width: 50px;
        height: 50px;
        line-height: 50px;
        position: fixed;
        left: 40%;
        bottom: 20px;
        cursor: pointer;
        background: #ccc;
        border-radius: 50%;
        text-align: center;
    }

    #canvas {
      
        display: none;
    }

    #imu {
      
        position: fixed;
        top: 15px;
        left: 15px;
    }

    #photo {
      
        display: none;
    }

    .input-box {
      
        position: fixed;
        bottom: 20px;
        left: 40%;
        width: 50px;
        height: 50px;
        overflow: hidden;
        cursor: pointer;
    }

    .input-box>input {
      
        opacity: 0;
        z-index: 100;
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        cursor: pointer;
    }

    .input-box>div {
      
        position: absolute;
        top: 0;
        left: 0;
        text-align: center;
        line-height: 50px;
        width: 50px;
        height: 50px;
        border-radius: 50%;
        background: #ccc;
        z-index: -1000;
    }
style>

<body>
    <div id="imu">div>
    <div id="camera">
        <video id="video" autoplay="autoplay">video>
        
        <div>
            <div id="capture">拍照div>
        div>
        
        <canvas id="canvas">canvas>
    div>
    <div id="photo">
        <div class="input-box">
            <input type="file" name="file" accept="image/gif,image/jpeg,image/bmp" capture="camera" class="headerImg"
                multiple="multiple">
            <div>上传div>
        div>
    div>
    <script>

        let video = document.getElementById("video");
        let canvas = document.getElementById("canvas");
        let context = canvas.getContext("2d");

        // 设置高度宽度
        let screenHeight = window.innerHeight;
        let screenWidth = window.innerWidth;
        canvas.setAttribute("width", screenWidth);
        canvas.setAttribute("height", screenHeight);
        video.setAttribute("width", screenWidth);
        video.setAttribute("height", screenHeight);

        // 老的浏览器可能根本没有实现 mediaDevices,所以我们可以先设置一个空的对象
        if (navigator.mediaDevices === undefined) {
      
            navigator.mediaDevices = {
      };
        }

        // 一些浏览器部分支持 mediaDevices。我们不能直接给对象设置 getUserMedia
        // 因为这样可能会覆盖已有的属性。这里我们只会在没有getUserMedia属性的时候添加它。
        if (navigator.mediaDevices.getUserMedia === undefined) {
      
            navigator.mediaDevices.getUserMedia = function (constraints) {
      

                // 首先,如果有getUserMedia的话,就获得它
                var getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia;

                // 一些浏览器根本没实现它 - 那么就返回一个error到promise的reject来保持一个统一的接口
                if (!getUserMedia) {
      
                    return Promise.reject(new Error('getUserMedia is not implemented in this browser'));
                }

                // 否则,为老的navigator.getUserMedia方法包裹一个Promise
                return new Promise(function (resolve, reject) {
      
                    getUserMedia.call(navigator, constraints, resolve, reject);
                });
            }
        }

        // 默认使用前摄像头,强制使用后置摄像头如下设置
        let constraints = {
       video: {
       facingMode: {
       exact: "environment" } } };
        // let constraints = { video: true }; // 前置摄像头用这个
        navigator.mediaDevices.getUserMedia(constraints)
            .then(function (stream) {
      
                // 旧的浏览器可能没有srcObject
                if ("srcObject" in video) {
      
                    video.srcObject = stream;
                } else {
      
                    // 防止在新的浏览器里使用它,应为它已经不再支持了
                    video.src = window.URL.createObjectURL(stream);
                }
                video.onloadedmetadata = function (e) {
      
                    video.play();
                };
            })
            .catch(function (err) {
      
                console.log(err.name + ": " + err.message);
                document.getElementById("camera").style.display = "none";
                document.getElementById("photo").style.display = "block";
            });


        //注册拍照按钮的单击事件
        document.getElementById("capture").addEventListener("click", function () {
      
            //绘制画面
            console.log(screenHeight, screenWidth)
            context.drawImage(video, 0, 0, screenWidth, screenHeight);
            console.log('video', canvas.toDataURL("image/png"));// base64图像
        });

        // 陀螺仪数据
        if (window.DeviceOrientationEvent) {
      
            window.addEventListener("deviceorientation", handleOrientation, true);
        }
        function handleOrientation(orientData) {
      
            var absolute = orientData.absolute;
            var alpha = orientData.alpha;
            var beta = orientData.beta;
            var gamma = orientData.gamma;
            // Do stuff with the new orientation data
            console.log(absolute, alpha, beta, gamma);
            document.getElementById("imu").innerText = "absolute:" + absolute + "\nalpha:" + alpha + "\nbeta:" + beta + "\ngamma:" + gamma;
        }

    script>
body>

html>

在安卓手机上下载了多个浏览器测试后,结果如下——

夸克:自动转成前置摄像头
欧朋、360极速浏览器、x浏览器、搜狗浏览器、2345、久久:打不开摄像头
百度、火狐、UC、Edge、QQ、猎豹、360浏览器、搜狗搜索、:授权后正常打开后置浏览器

h5调用摄像头拍照还是有兼容性问题,限制也比较多,facingMode查了下文档只能选user/environment/left/right,貌似没办法选到具体的哪个摄像头,最后还是考虑用原生开发。

你可能感兴趣的:(web,h5)