user19485937
user19485937

Reputation:

how to change volume on the left/right side of a audio JavaScript?

how to make onclick the sound start only on a side of the earphones

like for example right or left.

something like this: https://www.onlinemictest.com/sound-test/

so if it plays the sound on the left it, the right earphone doesn't need to make any sound.


I think it can be done by using volumes or something like that. how to do that?

(I can't edit the sound in a video editor, I want it will automatically done by javascript)

function playSound(options) {
  const choosedDirection = () => {
    return Object.keys(options)
      .reverse()
      .find(
        (direction) => direction === "left" || direction === "right",
      );
  };

  const audio = new Audio("audio.mp3");

  switch (choosedDirection()) {
    case "left":
      audio.play();
      // how to make here play only on the left side
      // by making the volume high on the left and 0 on the right
      break;
    case "right":
      audio.play();
      // how to make here play only on the right side
      // by making the volume high on the right and 0 on the left
      break;
  }
}
<head>
  <script src="https://cdn.tailwindcss.com/"></script>
</head>

<body class="h-screen grid place-items-center bg-gray-200 overflow-hidden">
  <div class="flex gap-[5vmin]">
    <div class="flex gap-[5vmin]">
    <!-- left -->
      <button title="๐ŸŽถ Left sound" class="transition hover:-translate-y-1 hover:shadow-2xl focus:rotate-3 hover:border-blue-200 hover:shadow-blue-200 focus:border-blue-500 focus:shadow-blue-500 border-4 border-blue-50 shadow-md p-[10vmin] bg-white rounded-[3vmin] text-[10vmin] text-blue-500 after:content-[attr(title)] relative after:absolute after:text-sm after:-bottom-20 after:left-0 after:w-max after:bg-white after:shadow-lg after:-translate-x-[50%] after:left-[50%] after:px-4 after:py-2 after:rounded-lg after:opacity-0 focus:after:opacity-100 focus:after:duration-500 after:translate-y-12 focus:after:translate-y-0 focus:after:animate-pulse focus:animate-bounce"
        onclick="playSound({left:true})">
        ๐Ÿกฐ
      </button>
      
      <!-- right -->
      <button title="๐ŸŽถ Right sound" class="transition hover:-translate-y-1 hover:shadow-2xl focus:rotate-3 hover:border-blue-200 hover:shadow-blue-200 focus:border-blue-500 focus:shadow-blue-500 border-4 border-blue-50 shadow-md p-[10vmin] bg-white rounded-[3vmin] text-[10vmin] text-blue-500 after:content-[attr(title)] relative after:absolute after:text-sm after:-bottom-20 after:left-0 after:w-max after:bg-white after:shadow-lg after:-translate-x-[50%] after:left-[50%] after:px-4 after:py-2 after:rounded-lg after:opacity-0 focus:after:opacity-100 focus:after:duration-500 after:translate-y-12 focus:after:translate-y-0 focus:after:animate-pulse focus:animate-bounce"
        onclick="playSound({right:true})">
        ๐Ÿกฒ
      </button>
    </div>

    <script>
      console.clear(); // not important, just to delete the tailwind warning of using CDN instead of NPM package
    </script>
</body>

Upvotes: 1

Views: 265

Answers (1)

trane
trane

Reputation: 123

You can use this solution:

const audioUrl = "https://s3-us-west-2.amazonaws.com/s.cdpn.io/858/outfoxing.mp3";
const audioElement = new Audio(audioUrl);
audioElement.crossOrigin = "anonymous";

const audioContext = new AudioContext();

const audioSource = audioContext.createMediaElementSource(audioElement);

const volumeNodeL = new GainNode(audioContext);
const volumeNodeR = new GainNode(audioContext);

volumeNodeL.gain.value = 2;
volumeNodeR.gain.value = 2;

const channelsCount = 2;

const splitterNode = new ChannelSplitterNode(audioContext, {
  numberOfOutputs: channelsCount
});
const mergerNode = new ChannelMergerNode(audioContext, {
  numberOfInputs: channelsCount
});

audioSource.connect(splitterNode);

splitterNode.connect(volumeNodeL, 0);
splitterNode.connect(volumeNodeR, 1);

volumeNodeL.connect(mergerNode, 0, 0);
volumeNodeR.connect(mergerNode, 0, 1);

mergerNode.connect(audioContext.destination);

let isPlaying;

function playPause() {
  if (audioContext.state === 'suspended') {
    audioContext.resume();
  }

  isPlaying = !isPlaying;
  if (isPlaying) {
    audioElement.play();
  } else {
    audioElement.pause();
  }
}

function setBalance(val) {
  volumeNodeL.gain.value = 1 - val;
  volumeNodeR.gain.value = 1 + val;
}
<h3>Check if your speakers are connected and working with this test.</h3>

<button onclick="playPause()">Play/Pause</button>
<br><br>
<button onclick="setBalance(-1)">๐ŸŽถ Left</button>
<button onclick="setBalance(0)">๐ŸŽถ Center</button>
<button onclick="setBalance(+1)">๐ŸŽถ Right</button>

Upvotes: 3

Related Questions