如何实现antd upload 上传视频回显第一帧图片

0 阅读1分钟

image.png 目前已有的组件是不能使这个上传组件实现视频回显第一帧的

1.已有代码

1.1 父组件

父组件使用 

import YxProFormSortableUpload from '@yx-dg-base/components/YxProFormSortableUpload'; 
<YxProFormSortableUpload 
    fieldProps={{ fileType: 'imgFile', maxCount: 20, multiple: true }} 
    // name={['skus',0,'pics']} 
    label={t(rules?.image?.label || '商品主图(SPU图)')}
    rules={[{ required: rules?.image?.require == 1 && rules?.image?.isShow == 1 }]}
    hidden={rules?.image?.isShow == 0} 
    name={['image']} extra="支持jpg、jpeg、png格式,最多20张,比例建议1:1或3:4;可拖拽改变图片顺序" 
/> 
<YxProFormSortableUpload 
    fieldProps={{ fileType: 'imgFile', maxCount: 1, multiple: true }} 
    label={t(rules?.pics?.label || '商品规格图(SPU图)')} 
    rules={[{ required: rules?.pics?.require == 1 && rules?.pics?.isShow == 1 }]} 
    hidden={rules?.pics?.isShow == 0} 
    name={['skus', 0, 'pics']} extra="支持jpg、jpeg、png格式,1张" 
/>

在不改变引用的情况下,需要处理

  1. 上传需要展示视频缩略图 --- 传的file文件
  2. 回显需要展示视频缩略图 --- 后端返回的是一个地址

image.png

// 🔥 通用:支持 本地File(上传) + 网络URL(回显) 自动生成视频第一帧
const getVideoFirstFrame = (source: File | string): Promise<string> => {
  return new Promise((resolve) => {
    const video = document.createElement('video');
    video.muted = true;
    video.playsInline = true;
    video.crossOrigin = 'anonymous';

    // 自动判断:URL 或 本地File
    const videoUrl = typeof source === 'string' 
      ? source 
      : URL.createObjectURL(source);

    video.src = videoUrl;

    video.addEventListener('loadedmetadata', () => {
      video.currentTime = 0.1;
    });

    video.addEventListener('seeked', () => {
      const canvas = document.createElement('canvas');
      canvas.width = video.videoWidth || 320;
      canvas.height = video.videoHeight || 240;
      const ctx = canvas.getContext('2d');
      
      if (ctx) {
        ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
        const base64 = canvas.toDataURL('image/jpeg', 0.8);
        
        // 内存释放(只释放本地文件)
        if (typeof source !== 'string') URL.revokeObjectURL(video.src);
        resolve(base64);
      } else {
        if (typeof source !== 'string') URL.revokeObjectURL(video.src);
        resolve(videoUrl);
      }
    });

    video.addEventListener('error', () => {
      if (typeof source !== 'string') URL.revokeObjectURL(video.src);
      resolve(videoUrl);
    });
  });
};

image.png

上传的时候需要处理 image.png

回显的时候的处理

image.png

现在的展示效果

image.png

image.png

image.png

image.png