Using AudioLoader to load a user-defined file

The example of how to use AudioLoader from threejs.org is as follows:

`// create an AudioListener and add it to the camera
var listener = new THREE.AudioListener();
camera.add( listener );

// create a global audio source
var sound = new THREE.Audio( listener );

// load a sound and set it as the Audio object’s buffer
var audioLoader = new THREE.AudioLoader();
audioLoader.load( ‘sounds/ambient.ogg’, function( buffer ) {
sound.setBuffer( buffer );
sound.setLoop( true );
sound.setVolume( 0.5 );
sound.play();
});`

This all makes sense to me, but I am trying to change something minor in here and I cannot figure out how I am supposed to do this. What I want to do is change the file location loaded by audioLoader.load (which in the example is ‘sounds/ambient.ogg’) into a file location defined by the user.

Currently I have an that lets the user load an audio file (.mp3 for example), but after hours of looking around for an answer I still do not know how I can change the above code segment to instead take in that file.

If anyone knows how to do this I would really appreciate if you could take the time and explain it to me!

It’s not clear yet how the user defines the audio file. Does this happen via an input field (<input type="file">)? It’s best if you demonstrate with a live example what you are trying to do.

Oh, thought I wrote that too but apperently missed it. Yes, the file is loaded through , and I then access it through the id of the input (document.getElementById). This gives me the audio file that I am then binding to some Audio Controls so that the user can control the playback.

The relevant code snippet of what I am trying to acomplish would be as follows:

input = document.getElementById("audioInput"); <-- This is the id to <input type="file">
audio = document.getElementById("audioControls"); <-- This is the id to <audio controls>

if (input != null){
    input.onchange = function() {

        audio.src = URL.createObjectURL(input.files[0]);

        audioLoader.load(input.value, function( buffer ) {
            sound.setBuffer( buffer );
            sound.setLoop(true);
            sound.setVolume(0.5);
            sound.play();
        });
    }
}

I’ve spent hours trying to come up with another solution since I do not understand how I am supposed to be able to load the file through audioLoader, but the solution gets a lot more complicated and presents me with other issues so I’d prefer to simply load the file as I am trying to here.

To clarify, in “audioLoader.load” I want to replace the argument where I have currently put “input.value” (since this does not work, amongst with many other attempts) with something that will make the actual file load. I’ve been trying to log the file through “input.value”, but this gives a rather strange path (C:/fakepath/SongName.mp3), and I am not sure how I can get the full file path since it will be unknown to me personally when someone else wants to load a file.

I’m afraid you can’t use AudioLoader for your use case since the parsing logic is directly embedded in the load() method. However, it’s no deal to use THREE.AudioContext directly. Try it like so:

var fileInput = document.querySelector( '#file' );
fileInput.addEventListener( 'change', function( event ) {

	var reader = new FileReader();
	reader.addEventListener( 'load', function ( event ) {

		var buffer = event.target.result;

		var context = THREE.AudioContext.getContext();
		context.decodeAudioData( buffer, function ( audioBuffer ) {

			var listener = new THREE.AudioListener();
			var sound = new THREE.Audio( listener );
			sound.setBuffer( audioBuffer );
			sound.play();

		} );

	} );

	var file = event.target.files[ 0 ];
	reader.readAsArrayBuffer( file );

} );

Live demo: https://jsfiddle.net/tch5q8wn/1/

1 Like

Brilliant! That explains why I couldn’t find a solution for this online. I was fiddling around with something similar trying to use AudioContext to solve it, but bumped into other issues so I tried reverting back to running it through AudioLoader instead.

Knowing AudioLoader cannot be used for this directly helps me a bunch though. Thanks heaps, Mugen87!

1 Like