react+ant design upload组件实现限制视频时长,图片宽高,大小

862 阅读1分钟

在做上传需求时,经常遇到各种上传限制,格式限制已经必备的了,今天来汇总下对于视频时长,图片宽高,及大小的限制:

  1. upload上传前的钩子函数:

当我们点击上传后,此刻能获取的file内容如下

image.png 可以用到的信息有file的type,name和size,视频的时长和图片的宽高是拿不到的,这两项的校验需要写单独的方法:

那么先根据file的size来对file的大小进行校验,不符合条件的可以直接return Upload.LIST_IGNORE,upload组件就会终止上传

 const beforeUpload = async (file) => {
    if (type === 'image') {
      const isLt20M = file.size / 1024 / 1024 < 20;
      if (!isLt20M) {
        message.warning('图片大小不超过20M');
        return Upload.LIST_IGNORE;
      }
      const imageWH = await checkImageWH(file, 1080, 960)
      if(!imageWH) {
        message.warning('图片尺寸上限为1080 x 960');
        return Upload.LIST_IGNORE;
      }
      return true 
    } else if (type === 'video') {
      const isLt10M = file.size / 1024 / 1024 < 10;
      if (!isLt10M) {
        message.warning('视频大小不超过10M');
        return Upload.LIST_IGNORE;
      }      
      const videoDuration = await checkVideoDuration(file, 20)
      if(!videoDuration) {
        message.warning('上传的视频应在20s内');
        return Upload.LIST_IGNORE;
      }
      return true 
    }
    return false;
  };
  1. 校验视频时长:

此处videoObj.onloadedmetadata存在异步问题,需要利用Promise,下方的image.onload同理

const checkVideoDuration = (file, t) => {
  return new Promise((resolve, reject) => {
    const videoUrl = URL.createObjectURL(file)
    const videoObj = document.createElement('video')
    videoObj.preload = 'metadata'
    videoObj.src = videoUrl
    videoObj.onloadedmetadata = () => {
      URL.revokeObjectURL(videoUrl)
      let times = Math.round(videoObj.duration)
      console.log(times, 'times')
      if (parseFloat(times) > t) {
        resolve(false);
      }else {
        resolve(true);
      }
    }
  });
}
  1. 校验图片尺寸:
const checkImageWH = (file, width, height) =>{
  return new Promise(function (resolve, reject) {
    const filereader = new FileReader();
    filereader.onload = (e) => {
      const src = e.target.result;
      const image = new Image();
      image.onload = function () {
        if (this?.width >= width || this?.height >= height) {   
          resolve(false);
        } else {
          resolve(true);
        }
      };
      image.onerror = reject;
      image.src = src;
    };
    filereader.readAsDataURL(file);
  });
}
  1. 上传模块:
        <Upload
          accept={'image/png,video/mp4'}
          action={'http://www.test.upload'}
          listType="picture-card"
          fileList={fileList}
          maxCount={1}
          onChange={handleChange}
          beforeUpload={beforeUpload}
        >
          <div>
            <PlusOutlined />
            <div style={{ marginTop: 8 }}>
              upload
            </div>
          </div>
        </Upload>
  1. 收尾,end