视频上传流程整理

122 阅读2分钟

前言

最近在做复盘,刚入职的时候做过一个视频上传相关的项目,这里回顾一下流程~,用的技术栈是react

一、视频上传

1.1 原生功能

首先需要实现视频上传功能,input原生的样式很丑,不能直接用

<div>
   <input type='file'/>视频上传
</div>

image.png

1.2 二次封装

采用的方案就是,将原有的隐藏,用新的样式进行覆盖

import './App.css';
import React, {useRef} from 'react';

function App () {
    const uploadRef = useRef(null);
    
    const onDropAreaClick = () => {
        uploadRef.current.click();
    };
    
    const uploadFileChange = async e => {
        const fileObj = e.target.files && e.target.files[0];
        if (!fileObj) {
          return;
        }
    
        let files = e.target.files;
        console.log('files', files)
      };
    
    
  return (
    <div className='group-title-upload' onClick={onDropAreaClick}>
          <input
              type='file'
              className='upload-input'
              onChange={uploadFileChange}
              ref={uploadRef}
          />视频上传
      </div>
  );
}

export default App;
.group-title-upload{
    width: 140px;
    height: 42px;
    line-height: 42px;
    background-color: #ff4141;
    color: #fff;
    text-align: center;
    cursor: pointer;
}

.upload-input{
    display: none;
}

image.png

  1. 将原有的input通过css进行隐藏
  2. 通过ref获取input的dom,点击外层div时,调用input的click事件
  3. 选择文件后,触发onChange事件,上传的文件得到的信息如上图控制台输出所示

二、视频文件校验

在视频上传之前,需要对用户上传的视频文件进行校验

  1. 根据type对视频的类型进行校验
  2. 根据size对视频的大小进行校验
  3. 对视频时长进行校验

Q: 如何获取时长?

image.png

import './App.css';
import React, {useRef} from 'react';

function App () {
    const uploadRef = useRef(null);
    
    const onDropAreaClick = () => {
        uploadRef.current.click();
    };
    
    const uploadFileChange = async e => {
        const fileObj = e.target.files && e.target.files[0];
        if (!fileObj) {
          return;
        }
    
        let file = e.target.files[0];
        console.log('file', file)

        // 校验时长
        await checkDuration(file)
    
    };

    const checkDuration = async file => {
        const src = URL.createObjectURL(file);
        const video = await getVideoDurationPromise(src);
        const duration = video?.target?.duration;
        // 单位是秒
        console.log('duration',duration)
    }

    const getVideoDurationPromise = src => {
        const video = document.createElement('video');
        return new Promise((res, rej) => {
          video.addEventListener('loadeddata', params => {
            res(params);
          });
          video.src = src;
        });
      };
    
  return (
    <div className='group-title-upload' onClick={onDropAreaClick}>
          <input
              type='file'
              className='upload-input'
              onChange={uploadFileChange}
              ref={uploadRef}
          />视频上传
      </div>
  );
}

export default App;

总结:

  • 获取视频时长
    • 通过URL.createObjectURL为上传的文件创建一个临时的url
    • 创建一个video标签,将该url赋值给video标签,通过监听loadeddata,获取参数
    • 网上的其他文章也有介绍用loadedmetadata的,在示例里,用loadedmetadataloadeddata得到的结果是一样的