浏览器调起摄像头(jquery+layui)

/*
实例化camvas配置参数
config = {
                video:{width:Number(scale*4),height:Number(scale*3)},//视频比例4:3
                canvasId:‘canvas‘,//画布canvas节点ID
                videoId:‘v‘,//video节点ID
                imgType:‘png‘,//图片类型,/png|jpeg|bmp|gif/
                quality:‘1‘ //图片质量0-1之间
            }
*/

window.URL = window.URL || window.webkitURL||window.mozURL || window.msURL;

navigator.getUserMedia  = navigator.getUserMedia ||
                          navigator.webkitGetUserMedia ||
                          navigator.mozGetUserMedia ||
                          navigator.msGetUserMedia

window.requestAnimationFrame = window.requestAnimationFrame ||
                               window.webkitRequestAnimationFrame ||
                               window.mozRequestAnimationFrame ||
                               window.msRequestAnimationFrame ||
                               window.oRequestAnimationFrame

// Integrate navigator.getUserMedia & navigator.mediaDevices.getUserMedia
function getUserMedia (constraints, successCallback, errorCallback) {
  if (!constraints || !successCallback || !errorCallback) {return}

  if (navigator.mediaDevices) {
    navigator.mediaDevices.getUserMedia(constraints).then(successCallback, errorCallback)
  } else {
    navigator.getUserMedia(constraints, successCallback, errorCallback)
  }
}

//获取摄像头设备源
function getMediaStream() {
  var exArray = []; //存储设备源ID
  MediaStreamTrack.getSources(function (sourceInfos) {
    for (var i = 0; i != sourceInfos.length; ++i) {
      var sourceInfo = sourceInfos[i];
      //这里会遍历audio,video,所以要加以区分
      if (sourceInfo.kind === ‘video‘) {
        exArray.push(sourceInfo.id);
      }
    }
  });
  return exArray;
}

//用户手机端使用后置摄像头
function getMediaConfig() {
  if (navigator.getUserMedia) {
    if(/Android|webOS|iPhone|iPod|BlackBerry/i.test(navigator.userAgent)){
      //手机端
      return {
        ‘video‘:
            {‘optional‘: [
                {‘sourceId‘: getMediaStream()[1] //0为前置摄像头,1为后置
                }]
            },
        ‘audio‘:false
      }
    }else{
      return {‘video‘:true,‘audio‘:false}
    }
  }
  else {
    alert(‘Native device media streaming (getUserMedia) not supported in this browser.‘);
  }
}

// The function takes a canvas context and a `drawFunc` function.
// `drawFunc` receives two parameters, the video and the time since
// the last time it was called.
function camvas(config) {
  var self = this
  self.convas = document.getElementById(config.canvasId)
  self.ctx = self.convas.getContext(‘2d‘);
  self.config = config
  self.isStop = false;

  //video节点ID
  self.video = document.getElementById(self.config.videoId)

  //video 显示尺寸
  self.video.setAttribute(‘width‘, this.config.video.width)
  self.video.setAttribute(‘height‘, this.config.video.height)

  //视频流控制句柄
  var mediaStreamTrack;
  //对外开启视频方法
  this.startCamera = function () {
    // The callback happens when we are starting to stream the video.
    getUserMedia(getMediaConfig(), function(stream) {
      // Yay, now our webcam input is treated as a normal video and
      // we can start having fun
      try {
        mediaStreamTrack = typeof stream.stop === ‘function‘ ? stream : stream.getTracks().length==1 ?
            stream.getTracks()[0]:stream.getTracks()[1];
        if(self.video.mozSrcObject !== undefined){
          //Firefox中,video.mozSrcObject最初为null,而不是未定义的,我们可以靠这个来检测Firefox的支持
          self.video.mozSrcObject = stream;
        }else{
          self.video.srcObject = stream;
        }
      } catch (error) {
        self.video.src = window.URL && window.URL.createObjectURL(stream) || stream;
      }
      self.isStop = false;
      self.video.play();
      // Let‘s start drawing the canvas!
      // self.recordVideo()
    }, function(err){
      alert(err);
    })
  }

  //录像方法
  this.recordVideo = function() {
    var self = this
    var last = Date.now()
    var loop = function() {
      // For some effects, you might want to know how much time is passed
      // since the last frame; that‘s why we pass along a Delta time `dt`
      // variable (expressed in milliseconds)
      var dt = Date.now() - last
      self.draw(self.video, dt)
      last = Date.now()
      requestAnimationFrame(loop)
    }
    requestAnimationFrame(loop)
  }
  //停止视频
  this.stop = function () {
    self.ctx.clearRect(0, 0, self.config.video.width,self.config.video.height);
    mediaStreamTrack && mediaStreamTrack.stop();
    self.isStop = true;
  }
  //拍照,base64/image/png
  this.drawImage=function (callback) {
    if(!self.isStop){
      self.ctx.drawImage(self.video,0,0,self.config.video.width,self.config.video.height);
      var base64URL = self.convas.toDataURL(‘image/‘+self.config.imgType,self.config.quality);
      callback&&callback(base64URL);
    }
  }

  //录像数据帧
  this.draw = function(video, dt) {
    self.ctx.drawImage(video, 0, 0)
  }
}
<style>
    .camera-control {
        position: absolute;
        z-index: 10;
        left: 0;
        right: 0;
        bottom: 0;
        text-align: center;
        padding: 10px;
        min-height: 40px;
    }
    .camera-btn {
        cursor: pointer;
        border: none;
        color: #fff;
        padding: 8px 12px;
        font-size: 14px;
        outline: none;
        background-color: rgba(255, 255, 255, 0.3);
        transition: all 0.3s;
        box-shadow: 0 2px 0 0 rgba(45, 140, 240, 0.8);
        margin: 0 5px;
    }
    .camera-canvas-group {
        display: flex;
        left: 0;
        right: 0;
        height: 80px;
    }
    .camera-canvas-item {
        opacity: 0.8;
        flex: 1;
        max-width: 100px;
        height: 100%;
        overflow: hidden;
        clear: both;
        margin-bottom: -1px;
        transition: all 0.2s;
        position: relative;
    }
    .camera-canvas-item img {
        float: left;
        width: 100%;
        background-color: #000;
        border: 1px solid #fff;
    }

    .camera-canvas-item:hover {
        position: relative;
        opacity: 1;
        box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.8);
    }

    .camera-canvas-item:hover {}
    .camera-btn:hover {
        background-color: rgba(45, 140, 240, 0.6);
        box-shadow: 0 2px 0 0 rgba(45, 140, 240, 1);
    }

    .camera-btn:active {
        background-color: rgba(45, 140, 240, 0.2);
    }
    .canvas-item-del{
        position: absolute;
        right: 0px;
        font-size: 22px;
        color: #ef475d;
        cursor: pointer;
    }
    .camera-show-pc{
        background-color:#FFFFFF;margin:0px auto;
    }
</style>
<div class="layui-fluid layui-anim" id="camera" lay-title="摄像头测试">
    <div class="layui-row">
        <div class="layui-card" style="background-color:#1E8AE8;margin: auto auto;">
            <div class="layui-card-body">
                <div class="layui-row camera-show-pc">
                    <h1 style="padding: 23px 0px;;font-size: 2.4rem;color: #1E8AE8;font-weight: bold;text-align: center">camera</h1>
                    <div class="bag_display_flex" style="justify-content: center;">
                        <div style="position: relative;">
                            <video id="v" style="background-color: #000000"></video>
                            <div class="camera-control">
                                <button type="button" id="stop" class="layui-icon layui-icon-stop camera-btn">关闭</button>
                                <button type="button" id="start" class="layui-icon layui-icon-triangle-r camera-btn">开始</button>
                                <button type="button" id="snap" class="layui-icon layui-icon-camera-fill camera-btn">拍照</button>
                                <button type="button" id="save" class="layui-icon layui-icon-save camera-btn">保存</button>
                                <button type="button" id="clear" class="layui-icon layui-icon-fonts-clear camera-btn">清空</button>
                            </div>
                        </div>
                        <div>
                            <canvas id="canvas" style="margin-left: 2px;background-color: #000000"></canvas>
                        </div>
                    </div>
                    <div class="layui-row" style="position: relative">
                        <div class="camera-canvas-group"></div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
<script type="text/javascript" src="js/camera/camvas.js"></script>
<script data-th-inline="javascript" type="text/javascript">
    layui.use([‘jquery‘], function () {
        var $ = layui.jquery,
            $view = $(‘#camera‘),
            config={},
            myCamvas;
        init();
        onClick();

        function init() {
            let scale = 120;//宽高比例倍数
            config = {
                video:{width:Number(scale*4),height:Number(scale*3)},//4:3
                canvasId:‘canvas‘,
                videoId:‘v‘,
                imgType:‘png‘,
                quality:‘1‘ //图片质量0-1之间
            };
            $(‘.camera-show-pc‘).css(‘width‘,config.video.width*2+20);
            $view.find(‘#canvas‘).attr(‘width‘,config.video.width);
            $view.find(‘#canvas‘).attr(‘height‘,config.video.height);
            //拍照实例化
            myCamvas = new camvas(config);
            myCamvas.startCamera();
            $view.find(‘#start‘).hide();
        }
        function onClick() {
            //停止拍照
            $view.find(‘#stop‘).click(function () {
                myCamvas.stop()
                $view.find(‘#stop‘).hide()
                $view.find(‘#start‘).show()
            })
            //启动摄像头
            $view.find(‘#start‘).click(function () {
                myCamvas.startCamera();
                $view.find(‘#stop‘).show()
                $view.find(‘#start‘).hide()
            })
            //拍照
            $view.find(‘#snap‘).click(function () {
                myCamvas.drawImage(function drawImage(base64URL) {
                    let xsCamera = $(‘<div></div>‘).addClass(‘camera-canvas-item‘);
                    xsCamera.append($(‘<img>‘).attr(‘src‘,base64URL)).append($(‘<span></span>‘).addClass(‘layui-icon layui-icon-close-circle-fill canvas-item-del‘));
                    $(‘.camera-canvas-group‘).prepend(xsCamera);
                });
            })
            //清空
            $view.find(‘#clear‘).click(function () {
                $view.find(‘.camera-canvas-group‘).empty()
            })

            //append方式添加节点直接click无效,点击显示大图
            $view.find(‘.camera-canvas-group‘).on(‘click‘,‘.camera-canvas-item img‘,function () {
                myCamvas.ctx.drawImage(this,0,0,config.video.width,config.video.height)
            })
            //删除图片
            $view.find(‘.camera-canvas-group‘).on(‘click‘,‘.camera-canvas-item .canvas-item-del‘,function () {
                //删除父节点元素
                $(this).closest(‘.camera-canvas-item‘).remove()
            })
            //保存所有图片到本地
            $view.find(‘#save‘).click(function () {
                let fileName = getFileName();
                let el_a = $(‘<a>‘);
                layui.each($view.find(‘.camera-canvas-group .camera-canvas-item‘),function (k,item) {
                    let t_filename = fileName+‘_‘+k+‘.‘+config.imgType;
                    downLoad($(this).find(‘img‘).attr(‘src‘),t_filename,config.imgType);
                })
            })
            //空格按下拍照
            $(document).keypress(function (e) {
                e.keyCode===32&&$(‘#snap‘).trigger(‘click‘);
            })
        };
        //tode
        function getFileName() {
            let date = new Date();
            let fileName = ‘‘+date.getFullYear()+(date.getMonth()<9?+‘0‘:‘‘)
                +(date.getMonth()+1) +(date.getDate()<10?+‘0‘:‘‘)+date.getDate()
                +date.getHours() +date.getMinutes()+(date.getSeconds()<10?‘0‘:‘‘)+date.getSeconds();
            return fileName;
        }
        function downLoad(dataURL,fileName,fileType) {
            var reader = new FileReader();
            reader.readAsDataURL(createFile(dataURL));
            reader.onload = function (e) {
                if (‘msSaveOrOpenBlob‘ in navigator) { // IE,Edge
                    var base64file = e.target.result + ‘‘;
                    window.navigator.msSaveOrOpenBlob(createFile(base64file.replace(‘data:‘ + fileType + ‘;base64,‘, ‘‘), fileType), fileName);
                } else { // chrome,firefox
                    var link = document.createElement(‘a‘);
                    link.style.display = ‘none‘;
                    link.href = e.target.result;
                    link.setAttribute(‘download‘, fileName);
                    // document.body.appendChild(link);
                    link.click();
                    $(link).remove();
                }
            }

            /*dataURL = dataURL.replace(‘image/‘+fileType,‘image/octet-stream‘);
            var save_link = document.createElementNS(‘http://www.w3.org/1999/xhtml‘, ‘a‘);
            save_link.href = dataURL;
            save_link.download = fileName;
            $(save_link).click()
            var event = document.createEvent(‘MouseEvents‘);
            event.initMouseEvent(‘click‘, true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
            save_link.dispatchEvent(event);*/
        };

        // 解析 BASE64文件内容 for IE,Edge
        function createFile(urlData) {
            var arr = urlData.split(‘,‘),
                mime = arr[0].match(/:(.*?);/)[1],
                bstr = window.atob(arr[1]),
                n = bstr.length,
                u8arr = new Uint8Array(n);
            while (n--) {
                u8arr[n] = bstr.charCodeAt(n);
            }
            return new Blob([u8arr], { type: mime });
        }

    });
</script>

原文地址:https://www.cnblogs.com/fushou/p/11442952.html

时间: 2024-10-30 14:46:21

浏览器调起摄像头(jquery+layui)的相关文章

浏览器调起Hbuilder的APP

最近用Hbuilder来开发APP,测试各种功能,其中,最近测试到,要用这个浏览器调起APP的功能,我看官网有教程,但是有些可能刚工作没多久,所以,有些地方看不大明白,官方也没细说,所以,特地写一个小文章,权当做官方的拓展版吧,尽量通俗异动一些,再配上一些文字解说和图片,希望可以帮到大家,好了,废话少说,直接来干活了. 看这篇文章,需要先看这两个: http://ask.dcloud.net.cn/article/64 http://ask.dcloud.net.cn/article/409 H

浏览器中打开摄像头

本文是讲述如何在浏览器中打开摄像头,并且实时显示在页面上.想要实现这一功能,需要依赖WebRTC (Web Real-Time Communications) 这一实时通讯技术,它允许浏览器之间视频流和音频流或者其他任意数据的传输,当然其中包含了大量的API和协议,这些在这里都不做介绍,具体的标准还在完善之中,所以使用的方法有时候也需要考虑到兼容问题,那么回到主题,怎样使用webRTC获取视频流. 首先对于html,我们需要一个video标签来播放视频(JS中添加也可以),当然画布也是能够实现的

调起摄像头、上传下载图片、本地展示图片

之前那偏微信JS-SDK授权的文章实现了分享接口,那么这里总结一下如何在微信里面通过js调起原生摄像头,以及上传下载图片. 1.配置 页面引入通过jssdk授权后,传入wx对象,首先配置需要的接口 wx.config({ /* debug: true, */ appId: appid, timestamp: timestamp, nonceStr: nonceStr, signature: signature, jsApiList: [ 'chooseImage',//拍照或从手机相册中选图接口

能跨域和跨浏览器的flashcookie for jquery插件

对于写网站时需要跨域和跨浏览器的可以看看这个. 引入jquery  和 swfstore.min.js 就可以了,蛮简单好用的,会jquery基础就可以咯. mySwfStore.set('myKey', '值'); //设置flashcookie mySwfStore.get('myKey'); //读取flashcookie 还有清除等命令在例子里,大家可以自己看哦. 跨域只需要把 js代码里的 swf_url 地址设置成绝对地址就可以了. 比如 swf_url=http://www.a.c

微信开发之调起摄像头、本地展示图片、上传下载图片

之前那篇微信JS-SDK授权的文章实现了分享接口,那么这里总结一下如何在微信里面通过js调起原生摄像头,以及上传下载图片. 1.配置 页面引入通过jssdk授权后,传入wx对象,首先配置需要的接口 wx.config({ /* debug: true, */ appId: appid, timestamp: timestamp, nonceStr: nonceStr, signature: signature, jsApiList: [ 'chooseImage',//拍照或从手机相册中选图接口

web开发之浏览器(二)----JQuery或JS判断浏览器内核版本号以及是否支持W3C盒子模型

1,JQuery或JS判断浏览器内核版本号以及是否支持W3C盒子模型 jQuery 从 1.9 版开始,移除了 $.browser 和 $.browser.version , 取而代之的是 $.support .在更新的 2.0 版本中,将不再支持 IE 6/7/8. 以后,如果用户需要支持 IE 6/7/8,只能使用 jQuery 1.9.  以后,如果用户需要支持 IE 6/7/8,只能使用 jQuery 1.9及以下的版本. 如果要全面支持 IE,并混合使用 jQuery 1.9及以下 和

pasteimg浏览器中粘贴图片jQuery插件

pasteimg是一款可以在浏览器中实现图片粘贴的jQuery插件,兼容Chrome.Firefox.IE11以及其他使用这些内核的浏览器,比如,国内著名的360浏览器. pasteimg可以识别浏览器中直接复制的图片,也可以识别复制的富文本中的图片.仅仅可以识别在浏览器中复制的内容,操作系统中复制的图片是不能识别的. pasteimg依赖jQuery,简单易用,引入jQuery和paste.image.js后,调用方式如下: 1 //在需要监听粘贴事件的dom元素上调用pasteImage方法

在浏览器调起本地应用的方法

最近公司有个需求,要求在浏览器中点击某个按钮,自动调起电脑中的一个应用. 首先,将以下代码复制到一个 reg 文件,例如 test.reg. Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\ptl] @="URL:ptl Protocol Handler" "URL Protocol"="" [HKEY_CLASSES_ROOT\ptl\shell] [HKEY_CLASSES_RO

浏览器console中加入jquery,测试选择元素

一.chrome浏览器F12打开调试界面,在console中输入(firefox同样可以): var jquery = document.createElement('script'); jquery.src = "http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js";//若调试页面是https的这里也修改为https. document.getElementsByTagName('head')[0].appendChild(jq