美文网首页
H5(react)实现在原生壳中实时拍照和录像上传以及显示

H5(react)实现在原生壳中实时拍照和录像上传以及显示

作者: 兜兜转转的小菊 | 来源:发表于2019-09-29 13:51 被阅读0次

    最近用react写了一款App, 其中有要求实现采集拍照或摄像数据上传的功能。本来打算让原生壳中实现方法给H5调用,无奈配合太麻烦。基于产品兼容性没有那么严格,最后还是让万能的h5实现吧。
    实现效果如下所示:


    最终效果.png

    基本思路还是用<input type="file" />实现。

    实现方式

    H5的文件上传会根据accept属性值打开文件目录,但是我们需要的是直接打开相机和录像,好在H5给了我们方法。camera属性可以捕获系统默认的设备,camera表示相机,camcorder表示摄像。

    /* H5 打开图库 */
    <input type="file" accept="image/jpeg,image/jpg,image/png,image/svg" />
    /* H5 直接打开相机 */
    <input type="file" accept="image/jpeg,image/jpg,image/png,image/svg" capture="camera" />
    /* H5 直接打开摄像 */
    <input type="file" accept="video/*" capture="camcorder"  />
    

    使用react的布局

    /** 上传按钮布局 
    * 根据cameraType判断是相机还是摄像, 也可以分为两个添加按钮来显示
    * 这里拍照和摄像的添加是放在一起的,点击添加的时候再次选择
    * accept中的 camera/* 是为了配合安卓端的调用而特别添加的
    */
    <div className="flexbox-item">
      <input style={{display: 'none'}}
             ref={el => this.input = el } // 获取input元素,用于获取元素模拟点击事件
             type="file"
             accept={cameraType ? 'video/*' : 'camera/*,image/jpeg,image/jpg,image/png,image/svg'}
             capture={cameraType ? 'camcorder' : 'camera'}
             onChange={this.handleImageChange} // 发生变化时调用
      />
      <div className="image-picker-item image-picker-upload-btn"
           onClick={this.chooseType}>
      </div>
    </div>
    

    react方法:

    /**
    * chooseType点击添加按钮,选择拍照还是摄像,
    * 选择后直接模拟input点击事件,打开对应设备
    */
    chooseType = () => {
        ... // 弹出层选择设备
        this.addImage(); // 模拟input点击事件
    }
    /*
    * 选择设备后,
    */
    addImage = () => {
        this.input.click(); // 触发input:file的click事件
    };
    /**
    * 处理图片
    */
    handleImageChange = () => {
        const file = e.target.files[0];  // 这是上传的文件流数据
        const _this = this;
        // const isLt20M = file.size / 1024 / 1024 < 20; // 限制20M以内
        // const windowURL = window.URL || window.webkitURL;// 实现预览
        // const dataURl = windowURL.createObjectURL(file); // 硬盘或sd卡指向文件路径, 可以直接用于预览的地址
    
        // 我需要本地缓存文件,所以使用了base64格式
        const reader = new FileReader()
        reader.readAsDataURL(file)
        reader.onload = (e) => {
            //  e.target.result  这是base64格式的文件
            ... // 其他处理, 可以从这里获取其他方式,如文件url路径、Blob格式的文件
        }
    };
    

    以上就是H5(react)实现在原生壳中实时拍照和录像上传以及显示的主要方法。

    实现中遇到的问题:

    1、input[type: file] 文件上传在安卓原生壳中使用无反应?
    解决:这是原生壳中禁用了H5的方法,需要原生那边重写方法,安卓的事情,需要安卓大神解决。

    2、大量图片在保存前需要保存在本地,图片资源大,缓存的问题?
    解决:使用IndexedDB缓存图片,很高效又简单。

    3、安卓原生壳中无法捕获input中的capture属性值,怎么分辨相机、摄像还是文件上传?
    解决:据安卓大神说,他那里得到的capture属性值只有true和false,但是可以得到accept属性值,这个时候为了兼容就在accept中添加相机的特殊标志,让安卓打开对应设备。

    4、文件上传在ios中需要点击两次才能调起?
    解决: emmmm, 这个问题,那就判断如果是ios设备上就把一次点击变点击两次嘛。哈哈哈,开玩笑,这是没有办法的办法。经检测我这里因为添加了fastclick.js,去掉就没有问题了。

    相关文章

      网友评论

          本文标题:H5(react)实现在原生壳中实时拍照和录像上传以及显示

          本文链接:https://www.haomeiwen.com/subject/grcauctx.html