Parcel: How to correctly load local assets like audio files

Created on 20 Aug 2018  ยท  9Comments  ยท  Source: parcel-bundler/parcel

โ” Question

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.

๐Ÿ”ฆ Context

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

structure

๐Ÿ’ป Code Sample

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++;
            }
        }
    }

๐ŸŒ Your Environment

| Software | Version(s) |
| ---------------- | ---------- |
| Parcel | 1.9.7
| Node | /
| npm/Yarn | 5.6.0
| Operating System | Windows 10

Question

All 9 comments

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:

  • works only with parcel (not compatible with node)
  • works only with a true path, not with require('some-module/**/*.mp3')
Was this page helpful?
0 / 5 - 0 ratings

Related issues

termhn picture termhn  ยท  3Comments

mnn picture mnn  ยท  3Comments

donaldallen picture donaldallen  ยท  3Comments

philipodev picture philipodev  ยท  3Comments

oliger picture oliger  ยท  3Comments