|
@@ -0,0 +1,284 @@
|
|
|
+<!DOCTYPE html>
|
|
|
+<html>
|
|
|
+ <head>
|
|
|
+ <meta charset="UTF-8">
|
|
|
+ <title>H5摄像头(新版浏览器https)(兼容老版浏览器)</title>
|
|
|
+ <script type="text/javascript" src="https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.2.js">
|
|
|
+ </script>
|
|
|
+ </head>
|
|
|
+ <body style="background-color: black;display: flex;flex-direction: column; margin: 0;">
|
|
|
+ <!-- 说明:将网页更改为https访问才行 否者报错:NotSupportedError Only secure origins are allowed (see: https://goo.gl/Y0ZkNV). -->
|
|
|
+ <!-- video用于显示媒体设备的视频流,自动播放;属性:https://zhuanlan.zhihu.com/p/535917105 -->
|
|
|
+ <video id="video" autoplay webkit-playsinline="true" playsinline="true"></video>
|
|
|
+ <!-- transform: rotateY(180deg); 镜像解决 -->
|
|
|
+ <!-- 可以通过画布canvas渲染,获取使用默认的video也行 -->
|
|
|
+ <!-- <canvas id="canvas" width="500" height="400" style="transform: rotateY(180deg);"></canvas> -->
|
|
|
+ <div class="box">
|
|
|
+ <canvas id="canvas"></canvas>
|
|
|
+ <span class="text">请将身份证完整置于取景框内</span>
|
|
|
+
|
|
|
+ <div class="buttonBox">
|
|
|
+ <!-- 拍照按钮 -->
|
|
|
+ <img class="buttonImg" id="back" src="../images/back.png" />
|
|
|
+ <img class="buttonImg" id="capture" src="../images/pai.png" />
|
|
|
+ <img class="buttonImg" id="fanzhuan" style="visibility: hidden" src="../images/fan.png" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div id="popup">
|
|
|
+ <img id="popupImg" src="" style="transform: rotateY(180deg);">
|
|
|
+ <div class="popupBox">
|
|
|
+ <button id="closeBtn">取消</button>
|
|
|
+ <button id="okBtn">确认</button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+
|
|
|
+ <script type="text/javascript">
|
|
|
+ // 获取弹窗元素
|
|
|
+ var popup = document.getElementById('popup');
|
|
|
+ var popupImg = document.getElementById('popupImg');
|
|
|
+ popup.style.display = 'none';
|
|
|
+ // 获取关闭按钮元素
|
|
|
+ var closeBtn = document.getElementById('closeBtn');
|
|
|
+ var okBtn = document.getElementById('okBtn');
|
|
|
+
|
|
|
+ var video = document.getElementById("video");
|
|
|
+ var canvas = document.getElementById("canvas");
|
|
|
+ var context = canvas.getContext("2d");
|
|
|
+ var ratio = 1;
|
|
|
+ var v_t_h = window.screen.height - 300,
|
|
|
+ v_t_w = window.screen.width;
|
|
|
+ var mode = 'environment';
|
|
|
+ var mediaStreamTrack;
|
|
|
+
|
|
|
+ canvas.width = v_t_w;
|
|
|
+ canvas.height = v_t_h;
|
|
|
+ video.height = v_t_h
|
|
|
+
|
|
|
+ document.addEventListener('UniAppJSBridgeReady', function() {
|
|
|
+ okBtn.addEventListener('click', function() {
|
|
|
+ uni.postMessage({
|
|
|
+ data: {
|
|
|
+ base64: popupImg.src
|
|
|
+ }
|
|
|
+ });
|
|
|
+ window.history.back(-1)
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+
|
|
|
+ // 弹出弹窗
|
|
|
+ function openPopup() {
|
|
|
+ popup.style.display = 'block';
|
|
|
+ }
|
|
|
+ // 关闭弹窗
|
|
|
+ function closePopup() {
|
|
|
+ takePhoto();
|
|
|
+ popup.style.display = 'none';
|
|
|
+ }
|
|
|
+ // 绑定关闭按钮的点击事件
|
|
|
+ closeBtn.addEventListener('click', closePopup);
|
|
|
+
|
|
|
+ // 访问用户媒体设备的兼容方法
|
|
|
+ function getUserMedia(constrains, successFun, errorFun) {
|
|
|
+ //like12 modified,20210628,bug,navigator.mediaDevices为空会导致后面卡死
|
|
|
+ if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
|
|
|
+ //最新标准API(新版浏览器https)
|
|
|
+ navigator.mediaDevices.getUserMedia(constrains).then(successFun).catch(errorFun);
|
|
|
+ } else if (navigator.webkitGetUserMedia) {
|
|
|
+ //like12 modified,20210628,不是这种调用方法 应该为后者
|
|
|
+ //webkit内核浏览器(老版浏览器)
|
|
|
+ //navigator.webkitGetUserMedia(constrains).then(successFun).catch(errorFun);
|
|
|
+ navigator.webkitGetUserMedia({
|
|
|
+ "video": true
|
|
|
+ }, successFun, errorFun);
|
|
|
+ } else if (navigator.mozGetUserMedia) {
|
|
|
+ //Firefox浏览器
|
|
|
+ navagator.mozGetUserMedia(constrains).then(successFun).catch(errorFun);
|
|
|
+ } else if (navigator.getUserMedia) {
|
|
|
+ //旧版API
|
|
|
+ navigator.getUserMedia(constrains).then(successFun).catch(errorFun);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 成功的回调函数
|
|
|
+ function successFun(stream) {
|
|
|
+ //like12 modifed,20210618,Chrome升级后,新版本不再支持该用法
|
|
|
+ //摄像头视频流显示报错Failed to execute 'createObjectURL' on 'URL'
|
|
|
+ //研究即时通信的过程中需要调用摄像头,发现报错,原来是谷歌弃用了这个方法,根据官方提示修改即可
|
|
|
+ //所以原先的代码:video.src = URL.createObjectURL(stream);
|
|
|
+ //需要被修改为:video.srcObject = stream;
|
|
|
+ //(新版浏览器https)
|
|
|
+
|
|
|
+ if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
|
|
|
+ video.srcObject = stream;
|
|
|
+ }
|
|
|
+ //(老版浏览器)
|
|
|
+ else {
|
|
|
+ //兼容webkit内核浏览器
|
|
|
+ var CompatibleURL = window.URL || window.webkitURL;
|
|
|
+ //将视频流设置为video元素的源
|
|
|
+ //此处的代码将会报错 解决的办法是将video的srcObject属性指向stream即可
|
|
|
+ video.src = CompatibleURL.createObjectURL(stream);
|
|
|
+ }
|
|
|
+ mediaStreamTrack = stream.getTracks()[0];
|
|
|
+ let settings = mediaStreamTrack.getSettings()
|
|
|
+ const { height, width } = settings
|
|
|
+ // ratio = width / height
|
|
|
+ // v_t_w = v_t_h * ratio
|
|
|
+ // canvas.width = v_t_w;
|
|
|
+ // canvas.height = v_t_h;
|
|
|
+
|
|
|
+ // 播放视频
|
|
|
+ video.play();
|
|
|
+ // 可以通过画布canvas渲染,获取使用默认的video也行
|
|
|
+ setInterval(function() {
|
|
|
+ context.drawImage(video, 0, 0, v_t_w, v_t_h);
|
|
|
+ // context.beginPath();
|
|
|
+ // context.arc(centerX, centerY, 70, 0, Math.PI * 2, false); // 绘制
|
|
|
+ // context.stroke();
|
|
|
+ }, 10);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 异常的回调函数
|
|
|
+ function errorFun(error) {
|
|
|
+ console.log("访问用户媒体设备失败:", error.name, error.message);
|
|
|
+ alert("访问用户媒体设备失败:" + error.name + " " + error.message);
|
|
|
+ }
|
|
|
+
|
|
|
+ document.getElementById('back').addEventListener('click', function() {
|
|
|
+ window.history.back(-1)
|
|
|
+ })
|
|
|
+ document.getElementById('fanzhuan').addEventListener('click', function() {
|
|
|
+ changeMode();
|
|
|
+ })
|
|
|
+ // 注册拍照按钮的单击事件-截图
|
|
|
+ document.getElementById("capture").addEventListener("click", function() {
|
|
|
+ mediaStreamTrack && mediaStreamTrack.stop();
|
|
|
+ var base64Img = canvas.toDataURL('image/jpg');
|
|
|
+ //var base64 = canvas.toDataURL('image/jpeg',0.5);// 图片质量0.5
|
|
|
+ popupImg.src = base64Img;
|
|
|
+ openPopup()
|
|
|
+ });
|
|
|
+
|
|
|
+ function takePhoto() {
|
|
|
+ // 开始调用摄像头
|
|
|
+ //like12 modified,20210628,bug,navigator.mediaDevices为空会导致后面卡死
|
|
|
+ if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia ||
|
|
|
+ navigator.getUserMedia ||
|
|
|
+ navigator.webkitGetUserMedia ||
|
|
|
+ navigator.mozGetUserMedia) {
|
|
|
+ // 调用用户媒体设备,访问摄像头
|
|
|
+ getUserMedia({
|
|
|
+ // video: {
|
|
|
+ // width: { min: 640 },
|
|
|
+ // height: { min: 480 },
|
|
|
+ // facingMode: mode //设置使用后置摄像头,user为前置摄像头
|
|
|
+ // },
|
|
|
+ video: true,
|
|
|
+ }, successFun, errorFun);
|
|
|
+ } else {
|
|
|
+ alert("你的浏览器不支持访问用户媒体设备");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ takePhoto();
|
|
|
+
|
|
|
+ function changeMode() {
|
|
|
+ console.log("翻转摄像头");
|
|
|
+ mode = mode === 'user' ? 'environment' : 'user';
|
|
|
+ mediaStreamTrack.stop();
|
|
|
+ takePhoto();
|
|
|
+ }
|
|
|
+ </script>
|
|
|
+ </body>
|
|
|
+ <style>
|
|
|
+ video {
|
|
|
+ transform: rotateY(180deg);
|
|
|
+ /* display: none; */
|
|
|
+ }
|
|
|
+
|
|
|
+ .box {
|
|
|
+ margin: 0 auto;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ text-align: center;
|
|
|
+ width: 100%;
|
|
|
+ }
|
|
|
+
|
|
|
+ canvas {
|
|
|
+ display: none;
|
|
|
+ position: fixed;
|
|
|
+ top: 10%;
|
|
|
+ left: 10%;
|
|
|
+ height: 200px;
|
|
|
+ width: 200px;
|
|
|
+ border: 1px solid blue;
|
|
|
+ transform: rotateY(180deg);
|
|
|
+ background: transparent;
|
|
|
+ /* margin-top: 5vh; */
|
|
|
+ /* border-radius: 50%; */
|
|
|
+ }
|
|
|
+
|
|
|
+ .text {
|
|
|
+ margin-top: 3vh;
|
|
|
+ color: #888;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ .buttonBox {
|
|
|
+ position: fixed;
|
|
|
+ bottom: 10%;
|
|
|
+ left: 0%;
|
|
|
+ width: 100%;
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-around;
|
|
|
+ margin-top: 15vh;
|
|
|
+
|
|
|
+ .buttonImg {
|
|
|
+ width: 15vw;
|
|
|
+ object-fit: contain;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .noneImg {
|
|
|
+ display: none;
|
|
|
+ }
|
|
|
+
|
|
|
+ #popup {
|
|
|
+ position: fixed;
|
|
|
+ top: 30%;
|
|
|
+ left: 50%;
|
|
|
+ transform: translate(-50%, -50%);
|
|
|
+ background: #fff;
|
|
|
+ padding: 20px;
|
|
|
+ border-radius: 5px;
|
|
|
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
|
|
|
+ z-index: 9999;
|
|
|
+ }
|
|
|
+
|
|
|
+ #popup h2 {
|
|
|
+ margin-top: 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ #closeBtn {
|
|
|
+ width: 30vw;
|
|
|
+ height: 4vh;
|
|
|
+ border-radius: 16px;
|
|
|
+ }
|
|
|
+
|
|
|
+ #okBtn {
|
|
|
+ width: 30vw;
|
|
|
+ height: 4vh;
|
|
|
+ border-radius: 16px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .popupBox {
|
|
|
+ margin-top: 2vh;
|
|
|
+ width: 100%;
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-around;
|
|
|
+ }
|
|
|
+ </style>
|
|
|
+</html>
|