React Native Expo中从Blob加载Audio.Sound失败,求解决方案
Expo Audio.Sound加载Blob URI报错-1002的解决方法
错误码-1002(NSURLErrorUnsupportedURL)本质是iOS的AVPlayer不支持Blob URI格式,而图片组件对Blob URI兼容性更好,所以出现音频加载失败但图片正常的情况。以下是几个实用的解决思路:
直接使用后端原始音频URL
跳过Blob转换步骤,直接用后端返回的音频文件URL加载。Expo Audio.Sound对标准HTTP/HTTPS URI的支持最稳定。
示例代码:const sound = new Audio.Sound(); try { await sound.loadAsync({ uri: 'https://your-backend.com/path/to/audio.m4a' }); await sound.playAsync(); } catch (error) { console.error('加载音频失败:', error); }将Blob转为Base64 Data URI
如果必须通过Blob获取音频(比如需要携带鉴权信息,无法直接暴露URL),可以把Blob转成Base64格式的Data URI,AVPlayer能识别这种格式。
示例代码:const blobToBase64 = (blob) => { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = () => resolve(reader.result); reader.onerror = reject; reader.readAsDataURL(blob); }); }; // 假设audioBlob是你从后端获取的Blob对象 const base64Uri = await blobToBase64(audioBlob); const sound = new Audio.Sound(); await sound.loadAsync({ uri: base64Uri });检查后端响应配置
- 确认后端返回的音频文件
Content-Type头是严格的audio/x-m4a,iOS的AVPlayer对MIME类型校验很严格,类型不匹配会导致加载失败。 - 确保后端配置了正确的CORS规则,允许你的Expo应用域名发起跨域请求,否则AVPlayer可能无法正确获取音频资源。
- 确认后端返回的音频文件
用Expo FileSystem缓存Blob到本地
把Blob保存到Expo的本地文件系统,再通过本地URI加载,这种方式兼容性最好,尤其适合离线使用场景。
示例代码:import * as FileSystem from 'expo-file-system'; import { Audio } from 'expo-av'; // 把Blob转成Base64后写入本地文件 const saveBlobToLocal = async (blob, filename) => { const base64 = await blobToBase64(blob); const fileUri = `${FileSystem.documentDirectory}${filename}`; await FileSystem.writeAsStringAsync(fileUri, base64.split(',')[1], { encoding: FileSystem.EncodingType.Base64, }); return fileUri; }; // 使用本地URI加载音频 const localAudioUri = await saveBlobToLocal(audioBlob, 'audio.m4a'); const sound = new Audio.Sound(); await sound.loadAsync({ uri: localAudioUri });
内容的提问来源于stack exchange,提问作者fredyjimenezrendon
相关产品推荐
相关产品推荐

