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

React Native Expo中Audio Blob无法播放问题求助

解决Expo-AV加载Eleven Labs API返回Blob时的"Cannot load an AV asset from a null playback source"错误

问题分析

你调用Eleven Labs API获取到Blob格式的音频数据,但直接用Audio.Sound.loadAsync(labsResponse.data)加载时触发错误。核心原因是Expo环境下,axios返回的Blob对象无法被AV模块直接识别,需要转换成Expo支持的资源格式(base64 URI或本地文件URI)。

解决方案1:将Blob转换为Base64 URI

通过FileReader把Blob转换成base64编码的URI,再传给loadAsync:

// 新增Blob转Base64的工具函数
async function blobToBase64(blob) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onloadend = () => resolve(reader.result);
    reader.onerror = reject;
    reader.readAsDataURL(blob);
  });
}

const triggerTextToSpeech = async () => {
  try {
    const labsResponse = await elevenLabsToSpeech("Hello!");

    if (labsResponse) {
      const sound = new Audio.Sound();
      // 转换Blob为Base64格式URI
      const base64AudioUri = await blobToBase64(labsResponse.data);
      
      await sound.loadAsync({ uri: base64AudioUri });
      await sound.playAsync();
    } else {
      console.log("文本转语音失败:API响应不包含音频数据。");
    }
  } catch (error) {
    console.log("文本转语音失败:" + error);
  }
};

解决方案2:将Blob保存为本地文件后加载

利用expo-file-system把Blob写入本地临时文件,通过文件URI加载音频(适合较大音频文件):

import * as FileSystem from 'expo-file-system';

const triggerTextToSpeech = async () => {
  try {
    const labsResponse = await elevenLabsToSpeech("Hello!");

    if (labsResponse) {
      const sound = new Audio.Sound();
      const blob = labsResponse.data;
      // 生成临时文件路径
      const tempFileUri = FileSystem.documentDirectory + "temp_speech.mp3";
      
      // 将Blob转换为ArrayBuffer后写入本地文件
      const arrayBuffer = await blob.arrayBuffer();
      await FileSystem.writeAsStringAsync(
        tempFileUri,
        String.fromCharCode(...new Uint8Array(arrayBuffer)),
        { encoding: FileSystem.EncodingType.Base64 }
      );

      await sound.loadAsync({ uri: tempFileUri });
      await sound.playAsync();

      // 播放完成后自动删除临时文件
      sound.setOnPlaybackStatusUpdate(async (status) => {
        if (status.didJustFinish) {
          await FileSystem.deleteAsync(tempFileUri);
        }
      });
    } else {
      console.log("文本转语音失败:API响应不包含音频数据。");
    }
  } catch (error) {
    console.log("文本转语音失败:" + error);
  }
};

关键说明

  • Expo的AV模块在iOS/Android原生环境下不支持直接加载Blob对象,必须使用URI格式的资源。
  • 两种方案都能解决问题,Base64转换更轻量,本地文件方式适合处理较大音频。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 20:57:11