乐趣区

关于前端:持续兼容微信H5选择照片图片视频及拍照录像

前言

做过 H5 调用手机相册或者拍照的同学可能深有体会,在不同型号手机和不同的浏览器上体现各有差别,实属头疼。因为手机自带浏览器或者第三方浏览器切实太多,联合最近正在做的我的项目用户群体 P90 在微信上,文本单从兼容微信浏览器方面进行试验剖析。

差别体现

个别的,应用 <input type="file" /> 调用其手机的文件资源管理器,通过 accept="image/*,video/*" 属性辨别调用相册,相册中筛选文件类型,能够是图片具体的格局,或者是视频的具体格局。采纳 capture="camera" 属性唤起相机,而在唤起相机后,是进行拍照还是录像是由 accept 决定。
而后,真的会如上规范定义操作咱们的手机吗?答案是否定的,Android 和 IOS 上的体现差别较大,上面别离剖析一下它们的差异性。

accept 在 Android 和 IOS 的体现

增加 accept 属性,在 IOS 微信浏览器上,点击后,会弹窗原生抉择,待用户下一步操作,如果 accept 的属性值

  • 仅有image/xxx -> 选项【照片图库】【拍照】,点击【拍照】-> 唤起相机,只能拍照,点击【照片图库】-> 关上相册,只能抉择图片
  • 仅有video/xxx -> 选项【照片图库】【录像】,点击【录像】-> 唤起相机,只能录像,点击【照片图库】-> 关上相册,只能抉择视频
  • video/xxx,video/xxx -> 选项【照片图库】【拍照或录像】,点击【录像】-> 唤起相机,能录像和拍照,点击【照片图库】-> 关上相册,能抉择视频和图片

    由此可知,IOS 上的体现与属性值的预期统一。
    在 Android 微信浏览器上,点击后,会弹出原生的抉择弹框,确认用户下一步操作

    接下来别离点击【拍摄】和【从相册抉择】进行测试。

  • accept=”image/*” -> 唤起原生【拍摄】和【从相册中抉择】弹窗 -> 点击【拍摄】唤起相机 - 拍照性能,点击【从相册中抉择】- 只能抉择图片,没有视频,安卓手机
  • accept=”image/,video/” -> 唤起原生【拍摄】和【从相册中抉择】弹窗 -> 点击【拍摄】唤起相机 - 拍照性能,点击【从相册中抉择】- 只能抉择图片,没有视频,安卓手机
  • accept=”video/,image/” -> 唤起原生【拍摄】和【从相册中抉择】弹窗 -> 点击【拍摄】唤起相机 - 拍照性能,点击【从相册中抉择】- 只能抉择视频,没有图片,安卓手机
  • accept=”video/*” -> 唤起原生【拍摄】和【从相册中抉择】弹窗 -> 点击【拍摄】唤起相机 - 摄像性能,点击【从相册中抉择】- 只能抉择视频,没有图片,安卓手机
  • accept=”video/mp4,video/ogg,video/webm,video/mov” -> 唤起原生【拍摄】和【从相册中抉择】弹窗 -> 点击【拍摄】唤起相机 - 摄像性能,点击【从相册中抉择】- 只能抉择视频和图片,安卓手机
  • accept=”image/jpg,image/jpeg,image/gif,image/png” -> 唤起原生【拍摄】和【从相册中抉择】弹窗 -> 点击【拍摄】唤起相机 - 拍照性能,点击【从相册中抉择】- 只能抉择视频和图片,安卓手机
  • accept=”image/jpg,image/jpeg,image/gif,image/png,video/mp4,video/ogg,video/webm,video/mov” -> 唤起原生【拍摄】和【从相册中抉择】弹窗 -> 点击【拍摄】唤起相机 - 拍照性能,点击【从相册中抉择】- 能够抉择视频和图片,安卓手机
  • accept=”image/*,video/mp4,video/ogg,video/webm,video/mov” -> 唤起原生【拍摄】和【从相册中抉择】弹窗 -> 点击【拍摄】唤起相机 - 拍照性能,点击【从相册中抉择】- 能够抉择视频和图片,安卓手机
  • accept=”video/mp4,video/ogg,video/webm,video/mov,image/*” -> 唤起原生【拍摄】和【从相册中抉择】弹窗 -> 点击【拍摄】唤起相机 - 拍照性能,点击【从相册中抉择】- 能够抉择视频和图片,安卓手机

有点乱,而且貌似不是严格遵循 accept 属性值法则。为了不便查看和比对区别,梳理成表格的模式

accept Android IOS
原生【拍摄】 原生【从照片抉择】 原生【拍照 / 录像】 原生【照片图库】
“image/*” 拍照 图片,没有视频 拍照 图片
“image/,video/ 拍照 图片,没有视频 拍照,录像 图片,视频
“video/,image/ 拍照 视频,没有图片 拍照,录像 图片,视频
“video/*” 录像 视频,没有图片 录像 视频
“video/mp4,video/ogg,video/webm,video/mov” 录像 视频,图片 录像 视频
“image/jpg,image/jpeg,image/gif,image/png” 拍照 视频,图片 拍照 图片
“image/jpg,image/jpeg,image/gif,image/png,video/mp4,video/ogg,video/webm,video/mov” 拍照 视频,图片 拍照,录像 图片,视频
“image/*,video/mp4,video/ogg,video/webm,video/mov” 拍照 视频,图片 拍照,录像 图片,视频
“video/mp4,video/ogg,video/webm,video/mov,image/*” 拍照 视频,图片 拍照,录像 图片,视频

从中咱们能够尝试总结法则

  • accept="video/xxx",即仅有视频格式状况下,Android 点击原生【拍摄】唤起相机是录像性能;
  • accept="image/xxx[,video/xxx]",即仅有图片格式或者图片加视频格式状况下,Android 点击原生【拍摄】唤起相机都是照相性能;
  • Android 点击原生【从照片抉择】唤起相册,若要想只筛选视频,最好应用accept="video/*",只筛选最好应用accept="image/*",而图片和视频同时共存,视频和图片格式最好写全或者accept="image/*,video/xxx"

    capture 在 Android 和 IOS 的体现

    <input type="file" />在以上已有 accept 属性下,加上 capture 属性,点击后可间接唤起相机,相机分为拍照和录像两种模式,同样的,咱们别离测试 Android 和 IOS 的微信浏览器上的后果如下

accept Android【拍摄】 IOS【拍摄】
“image/*” 拍照 拍照
“image/,video/ 拍照 录像,拍照
“video/,image/ 拍照 录像,拍照
“video/*” 录像 录像
“video/mp4,video/ogg,video/webm,video/mov” 录像 录像,拍照
“image/jpg,image/jpeg,image/gif,image/png” 拍照 录像,拍照
“image/jpg,image/jpeg,image/gif,image/png,video/mp4,video/ogg,video/webm,video/mov” 拍照 录像,拍照
“image/*,video/mp4,video/ogg,video/webm,video/mov” 拍照 录像,拍照
“video/mp4,video/ogg,video/webm,video/mov,image/*” 拍照 录像,拍照

能够发现,这里间接唤起拍摄和之前通过原生选项框中【拍摄】(Android)或者【录像】(IOS)的体现统一!

实现抉择照片(图片 & 视频)及拍照 & 录像

综合上述试验能够发现,没有一种 acceptcapture的值的组合能够实现在 Android 中,既要在相册中能够抉择图片和视频,又能够间接拍照和录像的状况。
这样能够多一个人为抉择弹窗或者将拍摄视频拆离开,相似这样

点击照片图标,Android 手机弹出原始选项框,能够【从相册抉择】图片和视频,也能够【拍摄】图片,点击拍摄图标,单纯反对录像。

最终的思路是
在 Android 微信环境下,点击照片图标触发的 inputaccept值为 video/mp4,video/ogg,video/webm,video/mov,image/* 使其后续【拍摄】唤起相机拍照,唤起相册能够抉择图片和视频;点击拍摄图标触发的 inputaccept值为 video/mp4,video/ogg,video/webm,video/mov,使其唤起相机录像性能;
伪代码实现

<uploader :accept="accept" label="照片" icon="picture" />
<uploader :accept="captureAccept" capture="camera" label="照片" icon="camera" />

const videoAccept = 'video/mp4,video/ogg,video/webm,video/mov'
//【照片】accept
const accept = `${videoAccept},image/*`
//【拍摄】accept
const UA = window.navigator.userAgent
const isAndroid = /Android/i.test(UA)
const isWechat = /MicroMessenger/i.test(UA)                                      
const {isAndroid, isWechat} = Terminal
const captureAccept = isAndroid && isWechat ? videoAccept : ${videoAccept},image/*`

完~

退出移动版