Audio cannot be started muted

Description

My program requires multiple audios to start at the same time at startup, so that they are synchronized, but I need to start them muted. The problem is that they play for a fraction of a second when starting them this way, preventing it from being an initial mute.

Reproduction steps

// Set mute
for(const sound of sounds) sound.setVolume(0)

// Loop
for(const sound of sounds) sound.loop = true

// Play song
for(const sound of sounds) sound.play()

Example: https://daftpunkins.vercel.app/

for(const sound of sounds) sound.setVolume(1)
for(const sound of sounds) sound.loop = true
for(const sound of sounds) sound.play()
for(const sound of sounds) sound.setVolume(0)

It doesn’t work either :'(. Same results

Understood. I will try it at my sound script.

I test at mine sound script starting sound muted and after few seconds changed volume to 1 and works ok. Then need to “fix” your sound script.

Are you starting multiple audios or only one? In my case for 1 audio works, but for 6 audios not

I am starting 6 sounds muted. All ok.

Could you share your code please?

this is my base audio funcion, used in 3d or not

const audios = [];
var AUDIOlistener = null;
var waitforaudio, waitforaudiotimes = 0;
function initUserWait(userdata) {
    waitforaudiotimes += 1;
    if (navigator.userActivation.hasBeenActive) {
        clearTimeout(waitforaudio);
        waitforaudio = false;
        init(userdata);
    } else {
        //console.log('waiting gestue');
        if (waitforaudiotimes > 100) {
            waitforaudiotimes = 0;
            clearTimeout(waitforaudio);
            waitforaudio = true;
            init(userdata);
        } else {
            waitforaudio = setTimeout(() => { initUserWait(); }, 500);
        }
    }
}
async function init(userdata){
    var xx=await createAudioEX('./sound1.mp3',0.2,true,false,undefined,undefined,'sound1');
    var yy=await createAudioEX('./sound2.mp3',0.2,true,false,undefined,undefined,'sound2');
    xx.play();yy.play();
}
async function createAudioEX(local, volume, loop, autostart, toObject, distance, newname) {
    if (!AUDIOlistener) {
        AUDIOlistener = new THREE.AudioListener();
        camera.add(AUDIOlistener);
    }
    let sound = audios.find(audio => audio.name === (newname || local));
    if (sound) {
        if (toObject) toObject.add(sound);
        if (typeof volume !== 'number' || !isFinite(volume)) {
            console.warn('Volume is not a valid number:', volume);
            volume = 1; // Define um volume padrĂŁo
        }
        sound.setVolume(volume);
        sound.setLoop(loop);
        sound.autoplay = autostart;
        if (autostart) sound.play();
    } else {
        sound = toObject ? new THREE.PositionalAudio(AUDIOlistener) : new THREE.Audio(AUDIOlistener);
        if (distance && typeof distance !== 'number') {
            console.warn('Distance is not a valid number:', distance);
            distance = 1; // Define uma distância padrão
        }
        if (distance && toObject) sound.setRefDistance(distance);
        const buffer = await audioLoader.loadAsync(local);
        if (!buffer) {
            console.error('Audio buffer could not be loaded:', local);
            return; // Saia da função se o buffer não for válido
        }
        sound.setBuffer(buffer);
        sound.setVolume(volume);
        sound.setLoop(loop);
        sound.autoplay = autostart;
        if (autostart) sound.play();
        sound.name = newname || local;
        audios.push(sound);
        if (toObject) toObject.add(sound);
    }
    return sound;
}

That’s odd because sounds should not start playing until there is user input. (See the notice generated in the console of the example.)

Since the example appears to involve attaching sounds to objects, one thing you could do is to wait to attach the sounds to the objects until initialization.

And maybe set the sounds to stop instead of play?

Yes, cant start without player itteraction and with volume=0. But anyway there is no “click” sound at loading. I use vanilla javascript for 2d and 3d sound instead THREE.PositionalAudio.
Test: 444.zip (7.9 MB)

1 Like

I’m starting the app with user interaction. But I’m using THREE.Audio.

I found a solution. Putting a little delay on play function, the bug dissappears. Maybe it requires a little time to process audio functions.

// Set mute
for(const sound of sounds) sound.setVolume(0)

// Loop
for(const sound of sounds) sound.loop = true

// Play song
for(const sound of sounds) sound.play(0.1)

If you’re using large file size sounds it’d probably be best to wait till all the sounds are loaded and ready with a LoadingManager rather than an arbitrary delay, as a delay may not account for slow network speeds and could lead to the same error for some sounds…

In my case after all sounds loaded runs this code in js/init.js

sounds_play("v1",'voice',false,test_effect,1,0,0,false,false);
sounds_play("v2",'Fight-Shorts',false,test_effect,1,0,0,false,false);
sounds_play("v3",'03_-just-forget-about-it',false,test_effect,1,0,0,false,false);
sounds_play("v4",'Fight-Shorts',false,test_effect,1,0,0,false,false);
sounds_play("v5",'Fight-Shorts',false,test_effect,1,0,0,false,false);
sounds_play("v6",'Fight-Shorts',false,test_effect,1,0,0,false,false);

And then can press “6 SOUNDS TEST”

sounds_volume_i[9].gain.value=1;
sounds_volume_i[8].gain.value=1;
sounds_volume_i[7].gain.value=1;
sounds_volume_i[6].gain.value=1;
sounds_volume_i[5].gain.value=1;
sounds_volume_i[4].gain.value=1;
sounds["v1"].start();
sounds["v2"].start();
sounds["v3"].start();
sounds["v4"].start();
sounds["v5"].start();
sounds["v6"].start();

or start them after button press with some time offset without all this code