Angular+Capacitor项目iOS端访问assets文件夹文件失败求助
解决Angular v15 + Capacitor v4 iOS加载assets音频文件问题
一、修复@capacitor/filesystem的路径错误
Capacitor在iOS中对assets目录的访问逻辑和Web端完全不同,不能使用./src/assets/xxx这类Web相对路径,必须指定正确的目录类型与相对路径:
- 先导入Directory枚举:
import { Filesystem, Directory } from '@capacitor/filesystem';
- 使用正确的参数调用readdir:
const myFiles = await Filesystem.readdir({ path: 'myAudioFolder', // 仅填assets文件夹下的子目录名,无需带src路径 directory: Directory.Assets }); console.log('data:', myFiles);
说明:
Directory.Assets指向iOS应用打包后的assets根目录,path参数仅需要填写该根目录下的子路径即可。比如你的音频文件夹在src/assets/myAudioFolder,这里就直接填myAudioFolder。
二、修复Tone.Sampler在iOS的音频加载问题
Web端直接用assets/audio/myFile.wav可以加载,但iOS中必须获取文件的原生URI才能正常访问,步骤如下:
- 通过Filesystem获取音频文件的URI:
import { Filesystem, Directory } from '@capacitor/filesystem'; async loadAudio() { const fileUri = await Filesystem.getUri({ path: 'audio/myFile.wav', // assets根目录下的相对路径 directory: Directory.Assets }); // 用获取到的原生URI初始化Sampler this.mySampler = new Tone.Sampler({ C4: fileUri.uri }, () => { // 音频加载完成后的业务逻辑 }); }
- 确保angular.json的assets配置正确,保证音频文件被打包:
打开angular.json,确认assets数组包含你的音频目录,确保编译时文件会被复制到打包产物中:
"assets": [ "src/favicon.ico", "src/assets", // 若有单独的音频目录,也可单独配置 "src/assets/audio" ]
额外排查点
- 确认iOS编译时,音频文件已被正确打包进App Bundle(可通过Xcode查看包内容验证);
- 如果Tone.js加载仍失败,可尝试将音频转为Blob后传入:
const fileData = await Filesystem.readFile({ path: 'audio/myFile.wav', directory: Directory.Assets, encoding: 'base64' }); const blob = b64toBlob(fileData.data, 'audio/wav'); const blobUrl = URL.createObjectURL(blob); this.mySampler = new Tone.Sampler({ C4: blobUrl }, () => { // 加载完成逻辑 }); // 辅助函数:base64转Blob function b64toBlob(b64Data: string, contentType = '', sliceSize = 512) { const byteCharacters = atob(b64Data); const byteArrays = []; for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) { const slice = byteCharacters.slice(offset, offset + sliceSize); const byteNumbers = new Array(slice.length); for (let i = 0; i < slice.length; i++) { byteNumbers[i] = slice.charCodeAt(i); } const byteArray = new Uint8Array(byteNumbers); byteArrays.push(byteArray); } return new Blob(byteArrays, { type: contentType }); }
内容的提问来源于stack exchange,提问作者ebarooni
相关产品推荐
相关产品推荐

