浏览器中打开摄像头

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

  首先对于html,我们需要一个video标签来播放视频(JS中添加也可以),当然画布也是能够实现的。使用video有些属性必须要配置。

<video id="video" autoplay playsinline></video>

  上面两个属性必须要添加,autoplay设置video自动播放,否则通信成功后页面将会保留第一张静止的画面。playsinline是由于有些浏览器默认会开启全屏播放,而全屏可能是画面变成黑屏。

  webRTC大部分浏览器支持,IE(Edge)15+, Safari 11+, IOS Safari 11.2+, Android 64+,  QQ、百度部分支持,对于IOS必须系统在11以上,并且只有Safari支持,UC 浏览器不支持。

  对于webRTC支持情况,可以采用以下代码判断。

if (navigator.mediaDevices === undefined ||
  navigator.mediaDevices.enumerateDevices === undefined ||
  navigator.mediaDevices.getUserMedia === undefined) {
  if (navigator.mediaDevices === undefined) {
    var fctName = ‘navigator.mediaDevices‘
  } else if (navigator.mediaDevices.enumerateDevices === undefined) {
    var fctName = ‘navigator.mediaDevices.enumerateDevices‘
  } else if (navigator.mediaDevices.getUserMedia === undefined) {
    var fctName = ‘navigator.mediaDevices.getUserMedia‘
  } else {
    console.assert(false)
  }
  alert(‘WebRTC issue-! ‘ + fctName + ‘ not present in your browser‘)
}

  获取video元素。

let video = document.querySelector(‘#video‘);

  如果支持webRTC,那么就调用mediaDevice的方法来遍历媒体对象,该方法返回一个promise对象,在第一个then方法的回调函数里面默认接收返回的媒体信息。

navigator.mediaDevices.enumerateDevices().then(function (sourceInfos) {
})

  获取sourceInfos,要拿到后置摄像头的信息并不是通用的,PC、IOS、Android以及不同浏览器,处理方法都不同,这里只做IOS和Android区分。

if(!navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/)) {
}

  如果不是IOS,那么就需要遍历sourceinfos,获取后置摄像头再获取视频流。声明一个exArray用来存放不同媒体设备的id,再通过id获取摄像头信息。

let exArray = [];
for (var i = 0; i < sourceInfos.length; ++i) {
  if (sourceInfos[i].kind == ‘videoinput‘) {
    exArray.push(sourceInfos[i].deviceId);
  }
}

  这样数组里面存放的都是摄像头的id,而我们需要的是后置摄像头,再调用获取媒体信息的方法。

if (navigator.getUserMedia) {
  // 该方法可以传递3个参数,分别为获取媒体信息的配置,成功的回调函数和失败的回调函数
  navigator.getUserMedia({
    audio: false, // 表明是否获取音频
    video: {  // 对视频信息进行配置
      optional: [{
        ‘sourceId‘: exArray[1] // 下标为0是前置摄像头,1为后置摄像头,所以PC不能进入该判断,否则画面会保持在第一帧不动
      }]
    },
  }, function successFunc(stream) {
    // 对FireFox进行兼容,这里对返回流数据的处理不同
    if (video.mozSrcObject !== undefined) {
      //Firefox中,video.mozSrcObject最初为null,而不是未定义的,我们可以靠这个来检测Firefox的支持
      video.mozSrcObject = stream;
    } else {
      // 一般的浏览器需要使用createObjectURL对流数据进行处理,再交给video元素的src
      video.src = window.URL && window.URL.createObjectURL(stream) || stream;
    }
  }, function errorFunc(e) {
    alert(‘Error!‘ + e);
  }); //success是获取成功的回调函数
} else {
  alert(‘Native device media streaming (getUserMedia) not supported in this browser.‘);
}

  在成功的回调函数中,将返回的视频流交给html中的video元素,这里src的方式实际是通过blob64的格式来传输的。

  // =============================  IOS

  在IOS中获取视频流现实的方式又不一样了,我们需要调用mediaDevice的获取媒体的方法,这也是最新的标准。首先需要些小小的配置:

// 这里对生成视频进行配置
var userMediaConstraints = {
  audio: false, // 是否获取音频
  video: {
    facingMode: ‘environment‘,  // 环境表示后置摄像头,使用user表示采用前置
    // 宽高的配置比较灵活,由于video一般都会显示固定宽高比,所以使用ideal理想值即可
    width: {
      ideal: 1024,
      // min: 1024,
      // max: 1920
    },
    height: {
      ideal: 768,
      // min: 776,
      // max: 1080
    }
  }
}

  再调用方法获取视频就很简单了,如下:

navigator.mediaDevices.getUserMedia(userMediaConstraints).then(function success(stream) {
  video.srcObject = stream;
}).catch(function (error) {
  alert(error.name + error.message)
});

  整体如下:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>web RTC</title>

</head>

<body>
  <!-- 这里必须设置autoplay,否则视频画面静止为第一张 -->
  <!-- 必须设置为playsinline,默认全屏播放可能会导致黑屏 -->
  <video id="video" autoplay playsinline></video>
  <script>
    // 习惯性写在函数中,控制变量
   ;(function(){
    //  由于IOS必须在版本11以上才能使用webrtc,并且只有Safari支持,所以做一个小小的判断,限定在
    if(/(iPhone|iPad|iPod|iOS)/i.test(window.navigator.userAgent) && navigator.vender.indexOf("apple") > -1) {
    return;
    }
    /**
     * =============实现在浏览器中打开摄像头,并且将摄像头内容显示在页面中
     * 想要实现这一功能,需要了解webRTC(Web Real-Time Communication)网络实时通话技术,它允许浏览器实现视频、音频、P2P文件分享等功能。
     */
    // 开启视频功能,依赖window的navigator对象,采用getUserMedia方法,有版本差异,所以需要判断区分
    // 需要IE(Edge)15+, Safari 11+, IOS Safari 11.2+, Android 64+, UC 不支持, QQ、百度部分支持

    // 所以首先需要对浏览器支持情况进行判断
    // 先判断浏览器是否支持
    if (navigator.mediaDevices === undefined ||
      navigator.mediaDevices.enumerateDevices === undefined ||
      navigator.mediaDevices.getUserMedia === undefined) {
      // 再判断具体是那个方法不支持,并向用户显示
      if (navigator.mediaDevices === undefined) {
        var fctName = ‘navigator.mediaDevices‘
      } else if (navigator.mediaDevices.enumerateDevices === undefined) {
        var fctName = ‘navigator.mediaDevices.enumerateDevices‘
      } else if (navigator.mediaDevices.getUserMedia === undefined) {
        var fctName = ‘navigator.mediaDevices.getUserMedia‘
      } else {
        console.assert(false)
      }
      alert(‘WebRTC issue-! ‘ + fctName + ‘ not present in your browser‘)
    }
    const video = document.querySelector(‘#video‘)

    // 如果浏览器支持,该方法的更新是向后兼容,新版将所有功能都使用navigator.mediaDevices进行了封装
    navigator.mediaDevices.enumerateDevices().then(function (sourceInfos) {
      // 如果支持新的方法,那么就使用新的方法来获取,当然这是一种比较主流的判断方法
      // 如果是想旧的方法兼容,可以使用下面作为判断条件,除IOS和PC以外,均使用旧的获取方式
      // !(navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/) || !/(iPhone|iPad|iPod|iOS|Android)/i.test(navigator.userAgent))

      /**
       * 无论是旧的写法还是新的标准,思路都是通过设备信息,获取摄像头的视频流,通过转换变成blob的格式交给video的src
       */
      if (!navigator.mediaDevices.getUserMedia) {
        // 声明一个数组,用于装载设备媒体设备的相关信息,由于回调中sourceInfos对象中携带有所有媒体对象的相关信息
        // 这里对信息进行遍历筛选,只选出摄像头的Id并保存在数组中
        var exArray = [];
        for (var i = 0; i < sourceInfos.length; ++i) {
          if (sourceInfos[i].kind == ‘videoinput‘) {
            exArray.push(sourceInfos[i].deviceId);
          }
        }
        // 通过navigator的getUserMedia获取摄像头的视频流,并在成功的回调中将视频流交给video
        getMedia();

        function getMedia() {
          if (navigator.getUserMedia) {
            // 该方法可以传递3个参数,分别为获取媒体信息的配置,成功的回调函数和失败的回调函数
            navigator.getUserMedia({
              audio: false, // 表明是否获取音频
              video: {  // 对视频信息进行配置
                optional: [{
                  ‘sourceId‘: exArray[1] // 下标为0是前置摄像头,1为后置摄像头,所以PC不能进入该判断,否则画面会保持在第一帧不动
                }]
              },
            }, successFunc, errorFunc); //success是获取成功的回调函数
          } else {
            alert(‘Native device media streaming (getUserMedia) not supported in this browser.‘);
          }
        }
        // 这里是获取媒体信息成功的回调函数
        function successFunc(stream) {
          // 对FireFox进行兼容,这里对返回流数据的处理不同
          if (video.mozSrcObject !== undefined) {
            //Firefox中,video.mozSrcObject最初为null,而不是未定义的,我们可以靠这个来检测Firefox的支持
            video.mozSrcObject = stream;
          } else {
            // 一般的浏览器需要使用createObjectURL对流数据进行处理,再交给video元素的src
            video.src = window.URL && window.URL.createObjectURL(stream) || stream;
          }
        }
        // 获取媒体信息失败的回调
        function errorFunc(e) {
          alert(‘Error!‘ + e);
        }
      } else {  // 当采用最新的标准方式获取视频时
        // 这里对生成视频进行配置
        var userMediaConstraints = {
          audio: false, // 是否获取音频
          video: {
            facingMode: ‘environment‘  // 环境表示后置摄像头,使用user表示采用前置
          }
        }
        // 这里就采用新的方法来获取视频
        navigator.mediaDevices.getUserMedia(userMediaConstraints).then(function success(stream) {
          video.srcObject = stream;

        }).catch(function (error) {
          alert(error.name + error.message)
        });
      }
    }).catch(function(error) {
      alert(error.name + error.message)
    })
   })();
  </script>
</body>

</html>

  最后提供一个将视频全屏显示的方法,对于PC和要求不高的手机已经可以实现全屏

* {
    margin: 0;
}
body {
   overflow: hidden;
}
#video {
    min-width: 100%;
    min-height: 100%;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

  在手机上,这个还有一点点横向滚动条,要想完全去掉,需要改动html,让video自动适用全屏的div

  html

<div id="wrapper">
  <video id="video" autoplay playsinline></video>
</div>

  css

* {
  margin: 0;
}

#wrapper {
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
  overflow: hidden;
}

原文地址:https://www.cnblogs.com/zzmiaow/p/9033894.html

时间: 2024-08-13 07:36:34

浏览器中打开摄像头的相关文章

微信打开网址添加在浏览器中打开提示

今天要加的是一个终极解决方法:弹出一个遮罩提示用户在新的浏览器窗口打开. 再也不用管微信如何的更新,直接判断微信的ua,然后弹出一个遮罩提示用户在浏览器中打开下载.并且不加关闭的按钮.类似于下面这样子: 这样子用户就只能在浏览器中打开,并且可以直接下载应用了.欢迎打开微信扫描查看(其他扫描没有效果). 演示二维码: 源码: <!DOCTYPE html> <html lang="zh_CN"> <head> <meta http-equiv=&

微信打开网址添加在浏览器中打开提示 http://caibaojian.com/weixin-tip.html

原文链接:http://caibaojian.com/weixin-tip.html#t2 使用微信打开网址时,无法在微信内打开常用下载软件,手机APP等.网上流传的各种微信打开下载链接,微信已更新基本失效,最新的一个是使用链接跳转方式: http://mp.weixin.qq.com/mp/redirect?url=http://caibaojian.com/test.apk#weixin.qq.com#wechat_redirect. 将链接文本中的http://caibaojian.com

报表XML导出rtf格式,结果在浏览器中打开XML文件。用360浏览器下载rtf文件打开后出现Authentication failed 问题

报表XML导出rtf格式,结果在浏览器中打开XML文件.用360浏览器下载rtf文件打开后出现Authentication failed 问题 直接上问题图: 问题描述:在Oracle EBS中执行"资源事务处理 XML"请求,选择输出rtf格式,完成后查看输出,却在浏览器中打开了XML文件.        提示:需要检查一下是否有对应的模板文件和模板定义有效时间.        解决方案:1. 查看日志. 从中可以看出出错原因,以及模板代码.2. 添加Oracle XML Publi

jsWindow 对象 Window 对象 Window 对象表示浏览器中打开的窗口。 如果文档包含框架(frame 或 iframe 标签),浏览器会为 HTML 文档创建一个 window 对象,并为每个框架创建一个额外的 window 对象。 注释:没有应用于 window 对象的公开标准,不过所有浏览器都支持该对象。 Window 对象集合 集合 描述 frames[] 返回窗口中所有命

一.JSX简介 JSX就是Javascript和XML结合的一种格式.React发明了JSX,利用HTML语法来创建虚拟DOM.当遇到<,JSX就当HTML解析,遇到{就当JavaScript解析. 如下(JS写法) var child1 = React.createElement('li', null, 'First Text Content'); var child2 = React.createElement('li', null, 'Second Text Content'); var

[JavaScript] js判断是否在微信浏览器中打开

用JS来判断了,经过查找资料终于实现了效果, function is_weixn(){     var ua = navigator.userAgent.toLowerCase();     if(ua.match(/MicroMessenger/i)=="micromessenger") {         return true;     } else {         return false;     } } 通过测试完全通过,无论是android 还是iphone,ipad

如何下载微信图文消息里的视频?在浏览器中打开保存到手机

刚刚看到别人分享在朋友圈里的文章里面有个视频,是微信公众平台内嵌视频,挺有意思的,想把它下载下来,那么,怎么提取微信图文消息里的视频呢? 研究了好一会,采用迂回术总算把微信图文里的视频保存到手机了 打开那个含有视频的图文消息,点击右上角的菜单,选“在浏览器中打开”,下图红色箭头所示 一般默认的浏览器都可以播放视频,播放的过程中会有一个下载的菜单,如下图箭头所示 点击下载就能把图文消息里的视频保存到手机中.当然有特殊情况,在苹果Safari浏览器中,视频右侧没有出现下载按钮,建议换用其他的

设置EBS 报表输出默认类型HTML并在浏览器中打开

设置EBS 报表输出默认类型HTML并在浏览器中打开 这里我们设置"资源事务处理报表"查看输出直接在浏览器中打开. 与"资源事务处理报表"有联系的博文:http://blog.csdn.net/crazygolf/article/details/48448525. 我们从上面博文中找到模板代码:WIPTRTXN_XML. 1. 进入相关职责. 2. 找到对应报表. 3. 点击Update. 4. Default Output type选择HTML. 5. 保存应用即

Servlet流操作——在浏览器中打开或者下载PDF文件

在Servlet与客户的请求应答的过程中,底层是通过输入/输出流来实现的.Servlet支持两种格式的输入/输出流.一个是字符输入/输出流.ServletResponse的getWriter()方法返回一个PrintWriter对象,Servlet可以利用PrintWriter来输出字符流形式的正文数据.另一种是字节输入/输出流.ServletResponse的getOutputStream()方法返回一个ServletOutputStream对象,Servlet可以利用ServletOutpu

微信打开网址添加在浏览器中打开提示遮罩

微信打开网址添加在浏览器中打开提示遮罩 网传方案(已失效): 使用微信打开网址时,无法在微信内打开常用下载软件,手机APP等.网上流传的各种微信打开下载链接,微信已更新基本失效,最新的一个是使用链接跳转方式:· http://mp.weixin.qq.com/mp/redirect?url=http://baidu.com#weixin.qq.com#wechat_redirect. 将链接文本中的http://baidu.com换成你的下载链接地址.本人已经测试可行.欢迎打开微信扫码测试.已经