js调用摄像头拍照并兼容ie浏览器

不会吧不会吧!现在都2023年了竟然还有人在用ie浏览器!

文章内容有点长 耐心看完,基本上能遇到的问题 都记录在这里了;

问题1: 调用摄像头并兼容ie浏览器

        用户调用摄像头一般使用navigator.mediaDevices,在ie浏览器这个对象获取为undefined,所以ie就不能使用navigator.mediaDevices;

       想在ie浏览器中正常调用摄像头并拍照,可以借用jquery-webcam-plugin插件。它是一个封装了摄像头功能的Jquery插件。

        jquery-webcam-plugin插件官方说是同时兼容谷歌、ie等浏览器,但是实际开发中我发现在谷歌浏览器并能用;最后只能写两套代码同时兼容多端浏览器,不知道是不是是我还没研究很明白的原因,如果有小伙伴开发能使用可以留言互相学习下。

        jquery-webcam-plugin官方网址

        下面是同时兼容谷歌和ie的代码,具体样式可以根据自己的项目需要进行自调;

        页面需要同时引入jquery和jquery.webcam.min.js

        关于这两个插件jquery.webcam-plugin官方demo中都有

<div class="main">
   <div style="display: flex">
       <div id="webcam"></div>
       <div style="margin-left: 20px;float: right">
           <div class="imgBox ieimgBox" style="background-image: url('{$photo.photo ?? ''}')"></div>
           <canvas id="canvas" height="240" width="320" style="display: none"></canvas>
       </div>
   </div>
</div>
<form id="add-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action="">
    <div class="video-box">
        <div>
            <video id="video" width="200" height="200" autoplay></video>
            <img class="imgBox" src="{$photo.photo}" style="vertical-align: top;" />
        </div>
        <input type="hidden" name="photo" id="photo">
    </div>

    <div class="form-group layer-footer noprint">
        <div class="col-xs-12 col-sm-8">
            <button type="button" class="btn btn-info" id="snap">拍照</button>
        </div>
    </div>
</form>
<script>
    var pos = 0;
    var ctx = null;
    var cam = null;
    var image = null;

    var filter_on = false;
    var filter_id = 0;

    function changeFilter() {
        if (filter_on) {
            filter_id = (filter_id + 1) & 7;
        }
    }
    // 兼容ie的核心方法
    function ieFn() {
        jQuery("#webcam").webcam({

            width: 320,
            height: 240,
            mode: "callback",
            swffile: "./jscam_canvas_only.swf",

            onTick: function(remain) {},
            onSave: function(data) {
                var col = data.split(";");
                var img = image;
                if (false == filter_on) {
                    for(var i = 0; i < 320; i++) {
                        var tmp = parseInt(col[i]);
                        img.data[pos + 0] = (tmp >> 16) & 0xff;
                        img.data[pos + 1] = (tmp >> 8) & 0xff;
                        img.data[pos + 2] = tmp & 0xff;
                        img.data[pos + 3] = 0xff;
                        pos+= 4;
                    }

                } else {
                    var id = filter_id;
                    var r,g,b;
                    var r1 = Math.floor(Math.random() * 255);
                    var r2 = Math.floor(Math.random() * 255);
                    var r3 = Math.floor(Math.random() * 255);

                    for(var i = 0; i < 320; i++) {
                        var tmp = parseInt(col[i]);
                        /* Copied some xcolor methods here to be faster than calling all methods inside of xcolor and to not serve complete library with every req */
                        if (id == 0) {
                            r = (tmp >> 16) & 0xff;
                            g = 0xff;
                            b = 0xff;
                        } else if (id == 1) {
                            r = 0xff;
                            g = (tmp >> 8) & 0xff;
                            b = 0xff;
                        } else if (id == 2) {
                            r = 0xff;
                            g = 0xff;
                            b = tmp & 0xff;
                        } else if (id == 3) {
                            r = 0xff ^ ((tmp >> 16) & 0xff);
                            g = 0xff ^ ((tmp >> 8) & 0xff);
                            b = 0xff ^ (tmp & 0xff);
                        } else if (id == 4) {

                            r = (tmp >> 16) & 0xff;
                            g = (tmp >> 8) & 0xff;
                            b = tmp & 0xff;
                            var v = Math.min(Math.floor(.35 + 13 * (r + g + b) / 60), 255);
                            r = v;
                            g = v;
                            b = v;
                        } else if (id == 5) {
                            r = (tmp >> 16) & 0xff;
                            g = (tmp >> 8) & 0xff;
                            b = tmp & 0xff;
                            if ((r+= 32) < 0) r = 0;
                            if ((g+= 32) < 0) g = 0;
                            if ((b+= 32) < 0) b = 0;
                        } else if (id == 6) {
                            r = (tmp >> 16) & 0xff;
                            g = (tmp >> 8) & 0xff;
                            b = tmp & 0xff;
                            if ((r-= 32) < 0) r = 0;
                            if ((g-= 32) < 0) g = 0;
                            if ((b-= 32) < 0) b = 0;
                        } else if (id == 7) {
                            r = (tmp >> 16) & 0xff;
                            g = (tmp >> 8) & 0xff;
                            b = tmp & 0xff;
                            r = Math.floor(r / 255 * r1);
                            g = Math.floor(g / 255 * r2);
                            b = Math.floor(b / 255 * r3);
                        }
                        img.data[pos + 0] = r;
                        img.data[pos + 1] = g;
                        img.data[pos + 2] = b;
                        img.data[pos + 3] = 0xff;
                        pos+= 4;
                    }
                }

                if (pos >= 0x4B000) {
                    ctx.putImageData(img, 0, 0);
                    pos = 0;
                }
            },
            onCapture: function () {
                webcam.save();
                jQuery("#flash").css("display", "block");
                jQuery("#flash").fadeOut(100, function () {
                    jQuery("#flash").css("opacity", 1);
                });
            },
            debug: function (type, string) {
            },
            onLoad: function () {
            }
        });
    }
    // 兼容谷歌的核心方法
    function chromeFn() {
        const video = document.getElementById('video');
        navigator.mediaDevices.getUserMedia({ video: true })
            .then(function (stream){
                video.srcObject = stream;
            })
            .catch(function (err){
                console.error('Error accessing camera', err);
            });
    }
    captureFn()
    // 初始加载判断兼容
    function captureFn() {
        if(navigator.mediaDevices === undefined){
            ieFn()
            var ieDom = document.getElementsByClassName('main')[0]
            var chromwDom = document.getElementsByClassName('video-box')[0]
            ieDom.setAttribute("style",'display: block')
            chromwDom.setAttribute("style",'display: none')

        }else{
            chromeFn()
            var ieDom = document.getElementsByClassName('main')[0]
            var chromwDom = document.getElementsByClassName('video-box')[0]
            ieDom.setAttribute("style",'display: none')
            chromwDom.setAttribute("style",'display: block')
        }
    }
    window.addEventListener("load", function() {
        jQuery("body").append("<div id=\"flash\"></div>");
        var canvas = document.getElementById("canvas");
        if (canvas.getContext) {
            ctx = document.getElementById("canvas").getContext("2d");
            ctx.clearRect(0, 0, 320, 240);

            var img = new Image();
            img.src = "/image/logo.gif";
            img.onload = function() {
                ctx.drawImage(img, 129, 89);
            }
            image = ctx.getImageData(0, 0, 320, 240);
        }
    }, false);

    const snap = document.getElementById('snap');
    snap.addEventListener('click', function(){
        if(navigator.mediaDevices === undefined){
            webcam.capture();
            changeFilter()
            var canvas = document.getElementById("canvas");
            const dateUrl = canvas.toDataURL('image/png')
            $('#photo').val(dateUrl);
            // ie用的背景展示拍照的图片 可以方便对拍照图片进行剪裁,解决图片变形问题
            $('.ieimgBox').css("background-image", "url(" + dateUrl +")");
        }else{
            const canvas = document.createElement('canvas');
            const context = canvas.getContext('2d');
            canvas.width = video.videoWidth;
            canvas.height = video.videoHeight;
            context.drawImage(video, 0, 0, canvas.width, canvas.height);
            const dataURL = canvas.toDataURL('image/png');
            $('.imgBox').attr('src', dataURL)
            $('#photo').val(dataURL);
        }
    });
</script>

        

问题2:ie浏览器借助flash调用摄像头,如何去掉每次进入都提示允许的弹窗

        咱们利用jquery-webcam-plugin插件兼容ie浏览器调用摄像头,每次进入页面都会提示让你 Adobe Flash Player设置 点击完允许 下次进来还弹

 解决步骤:

⚠️注意:前提是你的电脑上安装的有Adobe Flash Player插件,jquery-webcam-plugin插件也是借用flash进行调用摄像头的

1、打开控制面板 找到Flash Player,并双击打开(可以在控制面板右上方直接搜索就出来了)

2、存储一栏,选中“允许站点在此计算机上保存信息 ”

 

 3、在摄像头和麦克风一栏,点击进入“站点的摄像头和麦克风设置管理界面”,将需要访问摄像头的网站的https访问模式和其他模式都设置为允许

4、保存,重新打开页面就可以了。

 

 

 

问题3:  如何让Chrome浏览器允许http网站打开摄像头和麦克风

navigator.mediaDevices调用摄像头,在谷歌浏览器本地运行正常,发布到线上运行却提示Uncaught TypeError: Cannot read property 'getUserMedia' of undefined   这个错误,经过查阅资料才知道这和浏览器的安全策略有关,出于安全考虑,浏览器是不允许随便开启摄像头的,只有在https协议下方可开启。

解决办法,需要配置浏览器,允许访问才可以

谷歌浏览器打开 chrome://flags/#unsafely-treat-insecure-origin-as-secure

设置完浏览器底部会有Relaunch按钮,点击重新启动浏览器(一定要记得重新启动浏览器),就可以实现http协议下正常启动摄像头了(前提摄像头是允许模式下)

创作不易,且看且珍惜,有问题留言讨论 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值