Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to correctly load local assets like audio files #1911

Closed
mathildebuenerd opened this issue Aug 20, 2018 · 14 comments
Closed

How to correctly load local assets like audio files #1911

mathildebuenerd opened this issue Aug 20, 2018 · 14 comments

Comments

@mathildebuenerd
Copy link

❔ 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
@DeMoorJasper
Copy link
Member

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);

@mathildebuenerd
Copy link
Author

mathildebuenerd commented Aug 22, 2018

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

@DeMoorJasper
Copy link
Member

DeMoorJasper commented Aug 22, 2018

You could use globs, for example: require('../sounds/*/*.mp3'); this would return an object with mapping from original to hashed bundle.

@bozdoz
Copy link

bozdoz commented Feb 19, 2019

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.

@mischnic
Copy link
Member

@bozdoz Have you tried using a glob as suggested?
The code from #1911 (comment) is very hard to parse statically to determine which files to bundle.

@bozdoz
Copy link

bozdoz commented Mar 18, 2019

Tried a glob as suggested; still could not load audio. I just switched to webpack for my project.

@mischnic
Copy link
Member

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"?

@mischnic
Copy link
Member

mischnic commented Jun 2, 2019

Closing because of inactivity

@Offirmo
Copy link

Offirmo commented Sep 6, 2019

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')

@ELI7VH
Copy link

ELI7VH commented Apr 29, 2021

I am getting the error:

Error: No transformers found for /.../src/audio/eli7vh-tezos-till-i-bezos-final.wav.

@jeremymec
Copy link

Also getting the error about No transformers found

@mischnic
Copy link
Member

With Parcel 2, you need to prefix the import with url:: https://v2.parceljs.org/getting-started/migration/#importing-non-code-assets-from-javascript

@karltaylor
Copy link

With Parcel 2, you need to prefix the import with url:: https://v2.parceljs.org/getting-started/migration/#importing-non-code-assets-from-javascript

If this isn't immediately clear, (like it was for me pre-coffee)

Change this;

const track = require("../sounds/track3.mp3");

To this

const track = require("url:../sounds/track3.mp3");

And it will load the correct uri

@hemantvardani
Copy link

My issue got solved when, I started using the path as ('assets/static/audio.mp3'), instead of ('./../static/audio.mp3') i.e. complete path.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants