1. Background
In general business, cameras are rarely used, and there are ready-made tools to scan the QR code. Use it once rarely to record the pitfalls.
2. How to call the camera
2.1. input
html
Copy code
<!-- 调用相机 --> <input type="file" accept="image/*" capture="camera"> <!-- 调用摄像机 --> <input type="file" accept="video/*" capture="camcorder"> <!-- 调用录音机 --> <input type="file" accept="audio/*" capture="microphone">
Needless to say, the disadvantage is that there is no way to customize the interface. It is the native camera interface of the called system.
2.2. mediaDevices
Since I need a custom interface, like this:
So I chose this solution, whichapi
is actually very simple to use:
html
Copy code
<!-- 创建一个video标签用来播放摄像头的视屏流 --> <video id="video" autoplay="autoplay" muted width="200px" height="200px"></video> <button onclick="getMedia()">开启摄像头</button>
js
Copy code
async getMedia() { // 获取设备媒体的设置,通常就video和audio const constraints = { // video配置,具体配置可以看看mdn video: { height: 200, wdith: 200, }, // 关闭音频 audio: false }; this.video = document.getElementById("video"); // 使用getUserMedia获取媒体流 // 媒体流赋值给srcObject this.video.srcObject = await window.navigator.mediaDevices.getUserMedia(constraints); // 直接播放就行了 this.video.play(); }
You can see this effect.
For the configuration of this API, please refer to MDN
js
Copy code
// 截图拍照 takePhoto() { const video = document.getElementById("video"); // 借助canvas绘制视频的一帧 const canvas = document.getElementById("canvas"); const ctx = canvas.getContext('2d'); ctx.drawImage(this.video, 0, 0, 300, 300); }, // 停止 stopMedia() { // 获取媒体流 const stream = this.video.srcObject; const tracks = stream.getTracks(); // 停止所有轨道 tracks.forEach(function (track) { track.stop(); }) this.video.srcObject = null; }
3. Pit
If you copy my code, it will definitely run onlocalhost
, but you will find many problems when you try it on a mobile phone.
3.1. Needhttps
Due to the browser's security settings, you cannot obtain except for localhost
and https
connections. The printout is. If you want to test on a mobile phone, you can either use an intranet penetration proxy , or deploy it on a server with a domain name for testing. navigator.mediaDevices
undefined
https
https
3.2. Set up front and rear cameras
The default is to useuser
device, which is the front camera. If you want to use the rear camera, it is also configured.
js
Copy code
async getMedia() { // ... let constraints = { video: { height: 200, wdith: 200, // environment设备就是后置 facingMode: { exact: "environment" }, }, audio: false }; // ... }
3.3. Set the display area size
My requirement is to cover the entire device, so I take it for granted and directly set the video
style width and height to the container size:
css
Copy code
#video { width: 100%; height: 100%; }
js
Copy code
async getMedia() { // .... // 将宽高设置成容器大小 const pageSize = document.querySelector('.page').getBoundingClientRect() let constraints = { video: { height: pageSize.height, width: pageSize.width, facingMode: { exact: "environment" }, }, audio: false }; //.... }
I found that the video was horizontal and did not fill the screen.
You can see from the information outputvideo
that the width and height of the video stream returned by the device are reversed:
So just change the configuration:
js
Copy code
let constraints = { video: { height: pageSize.width, width: pageSize.height, }, };