vue 框架 调用 zxing.js 插件调用摄像头扫码 DEMO

  1. 项目地址: https://github.com/ZhengXinquan/demo

  2. zxing-js 官网地址:GitHub - zxing-js/library: Multi-format 1D/2D barcode image processing library, usable in JavaScript ecosystem.

  3. 浏览器需要支持  WebRTC

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
140
141
142
143
144
<template>
<div class="v-body">
<video ref="video" id="video" poster="../../assets/loading.jpg">video>
<p v-if="videoInputDevicesArray.length==0">{{textContent}}p>
<a v-else :href="textContent">{{textContent}}a>
<van-button v-if="videoInputDevicesArray.length>0" @click="changeCamera" block type="info">切换摄像头van-button>
div>
template>

<script>
import Vue from "vue";
// eslint-disable-next-line no-unused-vars
import adapter from "webrtc-adapter";
// WebRTC适配器 只需要引入就ok
import { BrowserMultiFormatReader } from "@zxing/library";
/**
* zxing demo
*/
export default {
data: () => ({
codeReader: null,
videoInputDevicesArray: [],
selectedIndex: -1,
textContent: undefined,
}),
created() {
this.updateTitle(this.$route.meta.title);
this.codeReader = new BrowserMultiFormatReader();
console.log(this.codeReader);
setTimeout(() => {
this.init();
}, 500);
},
destroyed(){
this.codeReader.reset();
},
methods: {
changeCamera() {
this.selectedIndex = this.selectedIndex + 1;
if (this.selectedIndex >= this.videoInputDevicesArray.length) {
this.selectedIndex = 0;
}
this.decodeFromInputVideo();
},
init() {
this.codeReader
.listVideoInputDevices()
.then((videoInputDevices) => {
videoInputDevices.forEach((device) =>
console.log(`${device.label}, ${device.deviceId}`)
);
this.videoInputDevicesArray = videoInputDevices;
this.decodeFromInputVideo();
})
.catch((err) => console.error(err));
},
decodeFromInputVideo() {
if (this.videoInputDevicesArray.length == 0) {
this.textContent = "没有检测到可用的摄像头";
this.$toast(this.textContent);
document.getElementById("video").style.display="none"
return;
}
if (this.selectedIndex >= this.videoInputDevicesArray.length) {
this.selectedIndex = 0;
}
let selectedDeviceId;
if (this.selectedIndex == -1) {
selectedDeviceId = undefined;
} else {
selectedDeviceId = this.videoInputDevicesArray[this.selectedIndex]
.deviceId;

this.codeReader.reset();
}

console.log(
`Started continous decode from camera with id ${selectedDeviceId}`
);

this.codeReader.decodeFromInputVideoDeviceContinuously(
selectedDeviceId,
"video",
(result, err) => {
if (result) {
console.log(result);
this.textContent = result.text;
}
if (err && !err) {
console.error(err);
}
}
);
},
},
};
script>

<style lang="less" scoped>
video {
width: 100%;
height: calc(~"(100vh - 156px)");
background-color: black;
}
.v-body {
font-family: "Ropa Sans", sans-serif;
color: #333;
max-width: 640px;
margin: 0 auto;
position: relative;
padding: 8px 16px;
}
#githubLink {
position: absolute;
right: 0;
top: 12px;
color: #2d99ff;
}
h1 {
margin: 10px 0;
font-size: 40px;
}
#loadingMessage {
text-align: center;
padding: 40px;
background-color: #eee;
}
#canvas {
width: 100%;
}
#output {
margin-top: 20px;
background: #eee;
padding: 10px;
padding-bottom: 0;
}
#output div {
padding-bottom: 10px;
word-wrap: break-word;
}
#noQRFound {
text-align: center;
}
style>