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

Posted fushou

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浏览器调起摄像头(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>

 

以上是关于浏览器调起摄像头(jquery+layui)的主要内容,如果未能解决你的问题,请参考以下文章

vue 调用浏览器摄像头

微信浏览器调取摄像头拍摄视频

layui中有类似jquery 的autocomplete这种控件吗

前端框架layui

Android开发:调起手机浏览器

webview调起浏览器