前言
废话不多说,使用uniapp时scan方法不支持h5端,因此h5端需要自己引入三方库,我这里用的是zxing
完整代码在最后
一、引入zxing
这里有两种方法,npm和直接使用js文件,按需使用
npm
1
| import { BrowserMultiFormatReader } from '@zxing/library'
|
直接使用js文件
js地址:https://unpkg.com/@zxing/library@latest/umd/index.min.js
1
| import { BrowserMultiFormatReader } from '@/utils/zxing.js'
|
二、功能实现
直接使用zxing提供的方法就行,默认参数就够用,如果需要自定义,比如修改视频流清晰度之类的可以看看文档
1. 获取摄像头
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| var video = document.getElementById('video_nav_id').getElementsByTagName('video')[0] video.setAttribute('id', 'video_id') video.setAttribute('class', 'video_calss') codeReader.value = new BrowserMultiFormatReader(); codeReader.value.listVideoInputDevices().then(res => { if (res.length > 0) { videoInputDevices.value = res deviceId.value = res[res.length - 1].deviceId } else { } }).catch(err => { console.error(err) })
|
2.开始扫描
1 2 3 4 5 6 7
| try { codeReader.value.decodeFromVideoDevice(deviceId.value, 'video_id', (res, err) => { if (res) handleScanningResult(res) }) } catch (err) { uni.showToast({ title: `初始化失败${err}`, icon: 'none' }); }
|
完整代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
| <template> <view class="camera_page"> <view class="camera_content"> <view class="code_close" @click="closeClick()"> </view> <view class="loop_line"></view> <view class="video_nav"> <video id="video_nav_id" autoplay :controls="false"></video> </view> </view> </view> </template> <script setup> import { onLoad } from "@dcloudio/uni-app"; import { ref } from "vue"; import { BrowserMultiFormatReader } from '@zxing/library'
const codeReader = ref(null) const deviceId = ref(null) const videoInputDevices = ref([]) const initEvent = () => { var video = document.getElementById('video_nav_id').getElementsByTagName('video')[0] video.setAttribute('id', 'video_id') video.setAttribute('class', 'video_calss') codeReader.value = new BrowserMultiFormatReader(); codeReader.value.listVideoInputDevices().then(res => { if (res.length > 0) { videoInputDevices.value = res deviceId.value = res[res.length - 1].deviceId } else { } }).catch(err => { console.error(err) }) startScanning() } onLoad(() => { setTimeout(() => { initEvent(); }, 3000); }); const startScanning = () => { try { codeReader.value.decodeFromVideoDevice(deviceId.value, 'video_id', (res, err) => { if (res) handleScanningResult(res) }) } catch (err) { uni.showToast({ title: `初始化失败${err}`, icon: 'none' }); } } let startTime = null const handleScanningResult = (res) => { if (!startTime) startTime = new Date().getTime() const time = 500 if (new Date().getTime() - startTime >= time) { startTime = null console.log(res.text) } }
const stopScanning = () => { codeReader.value.reset() } const closeClick = () => { } </script> <style scoped lang="scss"> .camera_page { height: 100vh; width: 100vw; }
.camera_content { height: 100%; width: 100%; position: relative; }
.code_close { height: 50rpx; width: 50rpx; position: absolute; left: 30rpx; top: 30rpx; z-index: 999999; }
.code_close>img { height: 100%; width: 100%; display: block; }
.loop_line { height: 3px; width: 80%; background-color: aliceblue; border-radius: 50%; box-shadow: 1px -4px 25px 7px rgba(255, 255, 255, 0.5); position: absolute; left: 50%; top: 20%; transform: translateX(-50%); animation: myfirst 3s infinite; z-index: 999999; }
@keyframes myfirst { from { top: 20%; }
to { top: 80%; } }
.video_nav { height: 100%; width: 100%; }
#video_nav_id { height: 100%; width: 100%; }
:deep(.uni-video-cover) { display: none; } </style>
|
注意事项:
摄像头权限需要https协议才能调用,也即
- 部署到服务器时,域名需要SSL证书,也就是域名以https开头
- 本地开发调试时,需要开启https并加载本地证书,这里可以看看我的另一篇笔记vue项目,uniapp项目开启https,加载本地证书