You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Expo Web端使用ImagePicker无法获取视频时长与文件大小求助

解决Expo ImagePicker Web端缺失视频元数据的问题

问题原因

Expo ImagePicker在Web端基于浏览器API实现,无法像iOS/Android原生平台那样直接获取完整的媒体元数据(文件大小、视频时长等),默认仅返回base64格式的uri、宽高信息,需要通过浏览器原生API手动补充这些数据。

解决方案

1. 获取文件大小

将base64格式的uri转换为字节数计算文件大小:

const getFileSizeFromBase64 = (base64Uri) => {
  // 剥离base64前缀部分
  const base64Data = base64Uri.split(',')[1];
  // base64编码规则:每4个字符对应3字节,末尾补位的=不占实际字节
  const byteLength = Math.ceil(base64Data.length * 3 / 4);
  return byteLength;
};

2. 获取视频时长

利用HTML5 Video元素加载视频,通过loadedmetadata事件读取时长:

const getVideoDuration = async (base64Uri) => {
  return new Promise((resolve, reject) => {
    const video = document.createElement('video');
    video.src = base64Uri;
    video.onloadedmetadata = () => {
      resolve(video.duration); // 返回时长(单位:秒)
      video.remove(); // 清理临时DOM元素
    };
    video.onerror = (err) => {
      reject(err);
      video.remove();
    };
  });
};

3. 整合到现有代码

修改onVideo函数,针对Web平台补充缺失的元数据:

import { Platform } from 'react-native';

const onVideo = async () => {
  let result = await ImagePicker.launchImageLibraryAsync({
    mediaTypes: ImagePicker.MediaTypeOptions.Videos,
    allowsEditing: true,
    quality: 1,
  });

  if (!result.canceled && result.assets?.length === 1) {
    let videoAsset = result.assets[0];
    
    // 仅Web端执行元数据补充逻辑
    if (Platform.OS === 'web') {
      try {
        videoAsset.fileSize = getFileSizeFromBase64(videoAsset.uri);
        videoAsset.duration = await getVideoDuration(videoAsset.uri);
      } catch (err) {
        console.error('获取视频元数据失败:', err);
      }
    }

    setVideo(videoAsset);
  }
};

优化建议

如果视频文件较大,base64格式会占用过多内存,可修改ImagePicker配置,在Web端直接获取File对象而非base64:

let result = await ImagePicker.launchImageLibraryAsync({
  mediaTypes: ImagePicker.MediaTypeOptions.Videos,
  allowsEditing: true,
  quality: 1,
  base64: false, // 关闭base64返回
  web: {
    allowFileAccess: true, // 允许返回File对象
  },
});

此时videoAsset.uri为Blob URL,可通过fetch(videoAsset.uri).then(res => res.blob())获取Blob对象读取size,视频时长的获取逻辑保持不变。

内容的提问来源于stack exchange,提问作者BOLIBICK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 17:57:26