How to correctly load local assets like audio files? I try to load a simple sound like that:
let sound = new Audio("../sounds/happy/happy-0.mp3");
But I keep getting a GET http://localhost:1234/sounds/happy/happy-0.mp3 404 (Not Found) error.
I am building a kind of web radio using mp3 files. I want to preload multiple files in order to be able to play them after. I use Typescript and parcel. I use this command to start the server: parcel --no-cache index.html --public-url /
My folder is structured like that: My code is in loadSoundFiles.ts

let sound = new Audio("../sounds/happy/happy-0.mp3");
I am using variables for generating the url. When I console.log the url I get ../sounds/happy/happy-0.mp3
The actual code is:
audioFiles = [];
loaded = 0;
preload(numberOfSounds: object): void {
// iterates through all the files
for (const emotion in numberOfSounds) {
for (let i=0; i<numberOfSounds[emotion]; i++) {
const url = `./../sounds/${emotion}/${emotion}-${i}.mp3`;
console.log(url); // ../sounds/happy/happy-0.mp3
this.audioFiles[this.loaded] = new Audio(url);
this.loaded++;
}
}
}
| Software | Version(s) |
| ---------------- | ---------- |
| Parcel | 1.9.7
| Node | /
| npm/Yarn | 5.6.0
| Operating System | Windows 10
Parcel only loads paths from requires, imports and workers.
Therefore the easiest fix is just adding a require to the code to resolve it into a url and copy the file into dist.
let audioUrl = require('../sounds/happy/happy-0.mp3');
let sound = new Audio(audioUrl);
Thanks!
If I want to load one file it's working. But I need to load several files so I don't want to manually require each sound. That's why I did a preload function in a class like this:
export class LoadSounds {
audioFiles = [];
loaded = 0;
preload(numberOfSounds: object): void {
// iterates through all the files
for (const emotion in numberOfSounds) {
for (let i=0; i<numberOfSounds[emotion]; i++) {
const url = `../sounds/${emotion}/${emotion}-${i}.mp3`;
const loadUrl = require(url);
this.audioFiles[this.loaded] = new Audio(loadUrl);
this.loaded++;
}
}
}
}
If I move the loop outside of the class, I get a Uncaught Error: Cannot find module '../sounds/happy/happy-0.mp3'
let audioFiles = [];
let loaded = 0;
for (const emotion in numberOfSounds) {
for (let i=0; i<numberOfSounds[emotion]; i++) {
const url = `../sounds/${emotion}/${emotion}-${i}.mp3`;
const loadUrl = require(url);
audioFiles[loaded] = new Audio(loadUrl);
loaded++;
}
}
You could use globs, for example: require('../sounds/*/*.mp3'); this would return an object with mapping from original to hashed bundle.
I'm having the same problem. Is there a simple asset plugin that would solve this? I know with webpack you can just use a file-loader.
@bozdoz Have you tried using a glob as suggested?
The code from https://github.com/parcel-bundler/parcel/issues/1911#issuecomment-414935461 is very hard to parse statically to determine which files to bundle.
Tried a glob as suggested; still could not load audio. I just switched to webpack for my project.
Mhh, running this packs all mp3 files in sounds and clicking in the browser window will then play all of them at once.
const files = Object.values(require('./sounds/*.mp3'));
const audios = files.map(v => new Audio(v));
document.body.onclick = () => {
audios.forEach(v => v.play());
};
Could you please be more specific about "still could not load audio"?
Closing because of inactivity
I tried with a glob:
require('some-module/**/*.mp3')