## H5 调用本地摄像头
目前来讲,H5 调用本地摄像头常见的有两种方案,一种是使用 HTML5 新提供的 `getUserMediaAPI` 方案,另外一种是使用传统的 `input:file` 方案。
## getUserMediaAPI
`getUserMediaAPI` 是 H5 为我们提供的新的 API。该 API 最早是直接挂在 `navigator` 对象上面的,但是目前做了调整,`navigator.getUserMediaAPI` 已经被废弃,取而代之的是 `navigator.mediaDevices.getUserMedia`。
MDN 上对此 API 的说明如下:
`MediaDevices.getUserMedia()` 会提示用户给予使用媒体输入的许可,媒体输入会产生一个`MediaStream`,里面包含了请求的媒体类型的轨道。此流可以包含一个视频轨道(来自硬件或者虚拟视频源,比如相机、视频采集设备和屏幕共享服务等等)、一个音频轨道(同样来自硬件或虚拟音频源,比如麦克风、A/D转换器等等),也可能是其它轨道类型。
它返回一个 `Promise` 对象,成功后会 `resolve` 回调一个 `MediaStream` 对象。若用户拒绝了使用权限,或者需要的媒体源不可用,`promise` 会 `reject` 回调一个 `PermissionDeniedError` 或者 `NotFoundError`。
详情:https://developer.mozilla.org/zh-CN/docs/Web/API/MediaDevices/getUserMedia
示例:
```html
<button id="btn1">开启摄像头</button>
<button id="btn2">关闭摄像头</button>
<video id="video" controls width="100%" height="700px"></video>
<style>
* {
margin: 0;
padding: 0;
}
button{
width: 200px;
height: 50px;
font-size: 32px;
margin: 20px;
}
</style>
<script>
var btn1 = document.getElementById("btn1");
var btn2 = document.getElementById("btn2");
var video = document.querySelector("#video");
var myConstraints = {
video: {
facingMode: "user", // 优先调用前置摄像头
},
};
// 开启摄像
btn1.onclick = function () {
navigator.mediaDevices.getUserMedia(myConstraints).then(
(stream) => {
video.srcObject = stream;
//播放视频
video.play();
// 关闭摄像
btn2.onclick = function () {
stream.getTracks().forEach((track) => track.stop());
};
},
(error) => {
console.error(error.name || error);
}
);
};
</script>
```
上面的示例中,虽然在开发环境时,各种访问媒体设备都没有问题,但是当部署到服务器上,手机和电脑浏览器都无法调起摄像头,这是由于浏览器的安全策略导致的。
有下面三种情况是可以调起设备的,也就是 `navigator.mediaDevices` 不为 undefined:
* 地址为 localhost://
* 地址为 https://
* 为文件访问 file:///
最后来看一下 getUserMediaAPI 的兼容性:

如果不考虑比较旧的浏览器的话,整体来讲也可以放心的去用。
## input:file
示例:
```html
<label>
<span>打开相册,可以选择一张图片</span>
<input type="file" accept="image/*" />
</label>
<label>
<span>打开相册,可以选择多张图片</span>
<input type="file" multiple accept='image/*'>
</label>
<label>
<span>打开照相机</span>
<input type="file" accept="image/*" capture="camera" />
</label>
<label>
<span>打开录像机</span>
<input type="file" accept="video/*" capture="camcorder" />
</label>
<label>
<span>打开录音机</span>
<input type="file" accept="audio/*" capture="microphone" />
</label>
<style>
html {
font-size: 36px;
}
input {
display: none;
}
label {
display: block;
}
span {
display: block;
text-align: center;
height: 50px;
font-size: 32px;
margin: 50px;
border: 1px solid #ccc;
padding: 10px;
line-height: 50px;
}
</style>
```
- Svg
- 01.svgIcon组件封装
- 02.clipPathSprites小图标
- html5
- 01.属性-input
- 02.属性-contenteditable
- 03.属性-draggable
- 04.标签-语义化标签
- 05.标签-canvas
- 06.标签-svg
- 07.标签-video
- 11.API-requestAnimationFrame
- 12.API-Storage
- css3
- 01.selector
- 02.border
- 03.background
- 04.color-gradient
- 05.text
- 06.box
- 07.flex
- 08.transition
- 09.cubic-bezier
- 10.animation
- 11.step
- 12.transform-rotate
- 13.transform-scale
- 14.transform-skew
- 15.transform
- 16.matrix
- 17.性能优化
- 18.css数据类型
- demo-animation
- demo-step
- demo-transform
- JavaScript
- 异步加载JS
- 函数
- 函数基础
- 函数名
- 理解参数
- 默认参数值
- 参数扩展与收集
- 函数内部
- 函数属性与方法
- 函数表达式
- 递归
- 闭包
- 立即调用的函数表达式
- 私有变量
- 函数的应用
- JS基础
- JS语言概述
- 数据与数据类型
- 操作符
- 变量声明
- 通过变量使用原始值与引用值
- 确定类型
- 标识符查找
- 执行上下文与作用域
- 垃圾回收
- Date
- 基本引用类型
- 包装类型-Boolean
- 包装类型-Number
- 包装类型-String
- 单例内置对象-Global
- 单例内置对象-Math
- 模版字符串
- try-catch与错误对象
- 对象
- 理解对象
- 创建对象
- 原型模式
- 继承
- 类
- 符号
- 普通符号
- 共享符号
- 知名符号
- 解构
- 对象解构
- 数组解构
- 数组
- 数组概述
- 数组方法
- 定型数组
- Map和Set
- Map
- Set
- WeakMap
- WeakSet
- 迭代器和生成器
- 迭代器
- 生成器
- 迭代与扩展操作
- 代理与反射
- 代理
- 反射
- 代理模式
- 异步处理
- 事件循环
- 事件和回调函数的缺陷
- 异步处理的通用模型
- Promise的基本使用
- Promise的API
- Promise的连锁与合成
- Promise扩展
- 异步函数
- 异步函数策略
- 其他案例
- 网络请求与远程资源
- 跨源资源共享
- XMLHttpRequest对象
- FetchAPI-基本用法
- FetchAPI-常见请求模式
- FetchAPI-Headers
- FetchAPI-Request
- FetchAPI-Response
- FetchAPI-body混入
- 安全
- BOM
- 窗口
- 视口
- 导航与打开新窗口
- location对象
- 操作地址
- navigator对象
- screen对象
- history对象
- DOM
- 节点层级
- 节点层级概述
- Node类型
- Document类型
- Element类型
- Text类型
- Comment类型
- DocumentType类型
- DocumentFragment类型
- CDATASection类型
- Attr类型
- DOM编程
- 动态脚本
- 动态样式
- 操作表格
- 使用NodeList
- MutationObserver
- MutationObserver接口
- MutationObserverInit与观察范围
- 异步回调与记录队列
- 性能和内存与垃圾回收
- DOM扩展
- SelectorsAPI
- 元素遍历
- CSS类扩展
- 焦点管理
- HTMLDocument扩展
- 插入标记
- 滚动
- 专有扩展
- DOM2和DOM3
- DOM的演进
- 样式
- 元素尺寸
- 事件
- 事件流
- 事件处理程序
- 事件对象
- 事件类型
- 事件委托
- 删除事件处理程序
- 模拟事件
- 用户界面事件
- load事件
- unload事件
- resize事件
- scroll事件
- 设备事件
- orientationchange事件
- deviceorientation事件
- devicemotion事件
- 焦点事件
- 鼠标和滚轮事件
- 键盘与输入事件
- HTML5事件
- contextmenu事件
- beforeunload事件
- DOMContentLoaded事件
- readystatechange事件
- pageshow与pagehide事件
- hashchange事件
- 触摸及手势事件
- 触摸事件
- 手势事件
- js常见工具
- git
- 01.基本概览
- 02.git命令
- 03.远程分支
- 04.source tree
- 05.git部署pages
- 06.git工作流
- vscode
- 插件推荐
- 快捷键
- 正则表达式
- 正则基础
- 包管理工具
- npm
- 01.概述
- 02.包的安装
- 03.包配置
- 04.包的使用
- 05.语义版本
- 06.npm脚本
- 07.运行环境配置
- 08.其他npm命令
- 09.发布包
- yarn
- 01.yarn简介
- 02.yarn的核心命令
- 03.yarn的其他命令
- 其他包管理器
- 01.cnpm
- 02.nvm
- 03.pnpm
- 模块化
- 01.模块化发展史
- 02.CommonJS
- 03.AMD和CMD
- 04.ES6模块化
- webpack
- 核心功能
- 01.如何在浏览器端实现模块化
- 02.webpack安装与使用
- 03.模块化兼容性
- 04.编译结果分析
- 05.配置文件
- 06.devtool配置
- 07.编译过程
- 08.入口和出口
- 09.入口和出口的最佳实践
- 10.loader
- 11.plugin
- 12.区分环境
- loader-处理图片
- loader-处理样式
- plugin-添加文件列表
- 13.其他细节配置
- 计算机组成原理
- 系统总线
- 存储器
- TypeScript
- 在node中搭建ts开发环境
- 基本类型检查
- 类型别名
- 枚举
- 模块化
- 接口
- 类
- 泛型
- 类型兼容性
- 面向对象
- 装饰器
- 类型演算
- 声明文件
- TS常用配置
- 数据结构与算法
- 线性数据结构
- 排序
- 栈和队列
- 树
- 图
- 动态规划
- webApp
- 移动端基础
- 移动端适配
- 移动端事件
- 移动端手势库
- 在本地配置https证书
- h5调用本地摄像头
- h5重力加速度
- h5横竖屏切换
- h5方向变化事件
- h5获取地理信息
- 移动端常见问题
- nodejs
- nodejs-概述.md
- nodejs-全局对象
- nodejs-模块化
- nodejs-内置模块
- nodejs-文件
- nodejs-生命周期
- nodejs-组成原理
- 进程和线程
- cookie
- JWT
- CORS
- CSRF攻击
- XSS攻击
- websocket
- 缓存的基本原理
- 常见案例
- 接口文件下载xlsx
- _设置
- image
- vue
- v2
- 01.核心概念
- 02.组件
- 03.插槽
- 04.动态组件
- 05.异步组件
- 06.计算属性
- 07.指令
- 08.事件处理
- 09.filter过滤器
- 10.组件生命周期
- 11.自定义指令
- 12.组件混入
- 13.$listeners
- 14.v-model
- 15.过渡和动画
- 16.keep-alive
- 17.插件
- 89.mini观察者
- 90.render
- 91.父子组件通信
- 92.虚拟dom详解
- 93.数据响应原理
- 94.diff
- 95.Vue项目优化
- 96.路由
- 97.数据共享
- 98.vuex案例
- 99.vue-cli
- v3
- 01.搭建工程
- 02.vue3的重大变化
- 03.vite原理
- 04.效率的提升
- 05.API和数据响应式的变化
- 06.模板中的变化
- 07.组件中的变化
- 08.ReactivityApi
- 09.CompositionApi
- 10.共享数据
- 11.slot透传
- mysite项目
- 01.搭建工程
- 02.Icon组件
- 03.Pager组件
- 04.测试组件
- 05.Empty组件
- 06.ImageLoader组件
- 07.Contact组件
- 08.Menu组件
- 09.SiteAside组件
- 10.Layout组件
- 11.路由
- 12.弹出消息
- 13.获取远程数据
- 14.Home组件
- 15.vLoading指令
- 16.组件混入
- 17.组件递归
- 18.文章列表页
- 19.文章详情页-1
- 20.文章详情页-2
- 21.文章详情页-3
- 22.事件总线
- 23.文章详情页-4
- 24.文章详情页-5
- 25.图片懒加载
- 26.使用vuex
- 27.标题统一处理
- 28.关于我
- 29.项目&效果
- 30.留言板
- 31.打包结果分析
- 32.异步组件
- 33.无数据显示
- 34.404页面
- 35.vuex优化
- mysite项目后台
- 01.项目准备
