前端两种方式获取视频基本信息

前言

在前端获取视频资源的信息有下面的两种方式:

1、使用FileReader读取为base64,然后赋值给视频的src属性;
2、使用URL.createObjectURL创建一个临时的url地址给视频的src属性;

FileReader实现

对比上面的两种方式,FileReader随着读取文件的变大会导致读取到的base64是空的,也比较慢(因为需要完成整个文件的读取,尤其是在低配置的电脑更加卡顿,在我加载一个600多M视频的时候就出现了这个问题);

查看 FileReader.readAsDataURL API

export const getVideoInfo = (
  file: RcFile,
): Promise<File | void> => {
  const fileReader = new FileReader();
  return new Promise((resolve, reject) => {
    // 整个文件加载完成后触发该事件
    fileReader.onload = (e: any) => {
      const src = e.target.result;
      const video = document.createElement('video');
      video.src = src;
      video.addEventListener(
        'loadeddata',
        () => {
          const width = video.videoWidth;
          const height = video.videoHeight;
      const duration = video.duration;
          return resolve({width, height, duration});
        }
      );
      video.addEventListener(
        'error',
        (e) => {
          reject(e.message)
        }
      );
    };
    // 文件太大会获取失败
    // https://developer.mozilla.org/zh-CN/docs/Web/API/FileReader/readAsDataURL
    fileReader.readAsDataURL(file);
  });
};

URL.createObjectURL实现

如果使用URL.createObjectURL就可以很快读取到地址,但是我们在后面要回收一下。下面我们看下实例代码。

查看 URL.createObjectURL API

 export const getVideoInfo = (
  file: RcFile,
): Promise<File | void> => {
  return new Promise((resolve, reject) => {
    const src = URL.createObjectURL(file);
    const video = document.createElement('video');
    video.src = src;
    video.addEventListener(
      'loadeddata',
      () => {
        const width = video.videoWidth;
        const height = video.videoHeight;
    const duration = video.duration;
        // 注意获取完需要的数据之后需要回收一下这个资源减少内存的占用
        URL.revokeObjectURL(src);
        return resolve({width, height, duration});
      }
    );
    video.addEventListener('error', (e) => {
      // 加载失败也需要回收一下
      URL.revokeObjectURL(src);
      reject(e.message);
    });
  });
};

所以在这里还是建议使用URL.createObjectURL的方式去预览,没有延迟和卡顿;

注意:上面的RcFile是Antd中定义的类型;
当然我们能拿到视频的宽高(其实还能拿到时长等信息)的话,我们甚至可以在前端做一些校验;

如果获取图片的信息,我们可以直接new Image()去监听load事件,来获取一些信息;

留下回复