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
相关产品推荐
相关产品推荐

