brianzinn / react-babylonjs

React for Babylon 3D engine
https://brianzinn.github.io/react-babylonjs/
809 stars 102 forks source link

Sound support #309

Closed Identifier closed 4 months ago

Identifier commented 4 months ago

Thanks for this great project. Are there any plans to add support for Sounds? Or do you have an example on how we could do it ourselves in a declarative manner in the meantime?

brianzinn commented 4 months ago

Can you share what you are doing imperatively and how you would like to be able to declaratively?

Identifier commented 4 months ago

Sure, just something like this:

    <Engine>
      <Scene>
        <freeCamera name="camera1" position={new Vector3(0, 5, -10)} setTarget={[Vector3.Zero()]} />
        <hemisphericLight name="light1" intensity={0.7} direction={new Vector3(0, 1, 0)} />
        <sound source={mySoundUrl} spatialSound autoplay/>
        <sound source={Buffer.from(base64data, 'base64').buffer} autoplay skipCodecCheck onFinished={onMySoundFinished} />
      </Scene>
    </Engine>

But since I couldn't find anything like that, I just ended up implementing my code with a custom component that just uses useEffect and doesn't return anything, like this:

function Sound({ source, onFinished }: { source: any; onFinished: () => any; }) {
  const scene = useScene();

  useEffect(() => {
    if (scene) {
      const sound = new Sound(`mySound`, source, scene, null, { autoplay: true, spatialSound: true, skipCodecCheck: true });
      sound.onended = onFinished;
      return () => {
        sound.dispose();
      };
    }
  }, [scene, source, onFinished]);

  return !!scene || "This component can only be used within a <Scene>";
}
brianzinn commented 4 months ago

I can add that. Certainly the version with a buffer looks like something that would need to be memoized. Maybe to start just with a url. Thanks for the request - that's what keeps the library expanding it's API support 😄

brianzinn commented 4 months ago

hi @Identifier should be working as you were expecting: brianzinn.github.io/react-babylonjs/examples/basic/sound/

<sound name="sound" urlOrArrayBuffer={'file.wav'} loop autoplay />

Note that where you had suggested source I have urlOrArrayBuffer. The naming follows the API (https://doc.babylonjs.com/typedoc/classes/BABYLON.Sound#constructor) with the options spread out. If you have any issues kindly re-open. Cheers