某些场景下,需要 H5 脱离应用来使用手机系统的摄像头用于照相或者拍摄。
一、方案
目前而言,移动端使用 H5 调用摄像头有两种方案:
getUserMedia Api
这种方法的兼容很差,基本不考虑
input type=file capture
这种方法是目前的主流,兼容 IOS 和 Android,但是 Android 无法调用前置摄像头
其实真正费时间的就是方案的抉择,了解的方案的坑以及市面的流行方案后就可以开始写代码了(代码很简单,百度一大推)
二、案例
PS:非常重要的一点,如果是在 APP 的 webview 下使用该 API,需要APP端在代码层面开通相关的权限(相机、相册、录音,缺一不可),否则会出现闪退或者点击 input 无效的情况
三、代码实现
3.1 拍照
3.2 视频
3.3 其他处理
调用摄像头之后,一般会进行处理
(1)拍照
获取基本信息:file 属性基本满足
压缩:
import lrz from 'lrz';
/**
* 压缩 file
* @param {[type]} file [文件]
* @param {Number} setWidth [压缩大小]
* @return {[type]} [压缩后的文件]
*/
compressFile(file, setWidth = 750) {
return lrz(file, {
width: setWidth,
quality: 1
})
.then(rst => {
// 超过限制大小
if (rst.file.size >= this.imageSizeLimitKB * 1000) {
return this.compressFile(file, setWidth - 50);
} else {
return rst.file;
}
});
},
const rstFile = await this.compressFile(file); // rstFile is blob
const newFile = new File([rstFile], fileName); // blob to file
(2)录像
获取视频大小: file.size
获取视频时长:使用 video.onloadedmetadata 方法来获取,但在 WKwebview 下无效,暂未找到通用方案
// 获取视频时长
handleGetVideoTime(file) {
const self = this;
return new Promise((resolve, reject) => {
window.URL = window.URL || window.webkitURL;
const video = document.createElement('video');
video.preload = 'metadata';
video.onloadedmetadata = function() {
window.URL.revokeObjectURL(video.src);
const duration = video.duration; // 视频时长 单位s
};
video.src = URL.createObjectURL(file);
});
},
压缩:暂未找到合适的方案
四、遇到的问题
4.1 iphoneX 上传图片直接唤起摄像头,没有本地图片的选择
解决方法:去掉 capture="camera"
4.2 input file width 无效,或者出现一个多余的 input
解决方法:input css overflow: hidden