h5 calls the mobile phone camera to avoid pitfalls

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:

image.png

So I chose this solution, whichapiis 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(); }

image.png

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.mediaDevicesundefinedhttpshttps

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 }; //.... }

image.png

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:

image.png

So just change the configuration:

 
 

js

Copy code

let constraints = { video: { height: pageSize.width, width: pageSize.height, }, };

Guess you like

Origin blog.csdn.net/m0_60961651/article/details/133771166