HTML5 调用手机摄像头拍照
一、getUserMedia API简介
getUserMedia API为用户提供访问硬件设备媒体(摄像头、视频、音频、地理位置等)的接口,基于该接口,开发者可以在不依赖任何浏览器插件的条件下访问硬件媒体设备。
getUserMedia API最初是navigator.getUserMedia,目前已被最新Web标准废除,变更为navigator.mediaDevices.getUserMedia(),但浏览器支持情况不如旧版API普及。
MediaDevices.getUserMedia()方法提示用户允许使用一个视频和/或一个音频输入设备,例如相机或屏幕共享和/或麦克风。如果用户给予许可,就返回一个Promise对象,MediaStream对象作为此Promise对象的Resolved[成功]状态的回调函数参数,相应的,如果用户拒绝了许可,或者没有媒体可用的情况下PermissionDeniedError或者NotFoundError作为此Promise的Rejected[失败]状态的回调函数参数。注意,由于用户不会被要求必须作出允许或者拒绝的选择,所以返回的Promise对象可能既不会触发resolve也不会触发reject。
参考官方API:https://developer.mozilla.org/zh-CN/docs/Web/API/MediaDevices/getUserMedia
手机版本支持情况:
二、页面代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>拍照</title> </head> <body> <video id="video" width="640" height="480" autoplay="autoplay"></video> <!--拍照按钮--> <div> <button id="capture">拍照</button> </div> <!--描绘video截图--> <canvas id="canvas" width="640" height="480"></canvas> <script> let video = document.getElementById("video"); let canvas = document.getElementById("canvas"); let context = canvas.getContext("2d"); // 老的浏览器可能根本没有实现 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("capture").addEventListener("click", function () { //绘制画面 context.drawImage(video, 0, 0, 640, 480); }); </script> </body> </html>
上面代码完成后可以直接在浏览器里使用http://localhost:8080查看。或者使用127.0.0.1进行本地查看。但是若是想要设置其他的ip地址,例如:192.168.0.11 等IP地址则无法访问。
原因:getUserMedia除本地地址外,只支持安全的协议访问。也就是说需要用https才能访问,下面讲解如何配置https。
三、https配置
1、使用jdk提供的keytoo工具生成秘钥
打开命令行,输入下列代码:
keytool -genkey -alias tomcat -keyalg RSA -keystore ./server.keystore
进入命令后按下列输入内容:
运行完毕后会在当前路径下得到一个名为server.keystore的秘钥文件。
2、将秘钥加入springboot工程
将秘钥拷贝到项目根路径。注意:跟路径指的是工程的第一层路径,请注意位置。
3、配置springboot的配置文件application.properties,加入下列代码:
server.port=8443 server.ssl.key-store=server.keystore server.ssl.key-alias=tomcat server.ssl.enabled=true server.ssl.key-store-password=123456 server.ssl.key-store-type=JKS
4、启动项目,访问路径 https://localhost:8443/。
**注意协议和端口号**
会看到如下错误提示,这是因为我们自己配置的秘钥(证书)没有官方注册,无法被浏览器识别。可以点高级 -> 继续前往 。
这时能正常访问则说明我们的https配置完毕。可以替换成其他IP地址测试能正常使用摄像头了。