After I updated to BabylonJS 4.0, I get this error:
babylon.js:16 Uncaught (in promise) TypeError: Cannot read property 'canUseWebAudio' of undefined
When this line is reached in my code:
this.pickUpSound = new BABYLON.Sound('Letter.PickUp', './assets/sounds/letter_collection_2notes.wav', this.scene);
I thought it was because BabylonJS 4.0 was enforcing the audioContext policy of waiting for a button press of the user to resume the audio, as explained here: Autoplay Policy Changes | Web | Google Developers
Hence I added these lines to my code:
this.startButton.onPointerDownObservable.add(e=> {
let audioContext = new AudioContext();
audioContext.resume().then(
() => {
console.log('Playback resumed successfully');
});
});
Ok, I don’t understand anything anymore. I reverted to BabylonJS 4.0.0-alpha.4 and reverted my changes (by checking out to the previous commit) and the problem is still there
How is that possible?
It seems that no AudioEngine is initialised… when I stopped the execution just before I load my sounds, and I check the variable BABYLON.Engine.audioEngine, it is undefined.
When I stopped the execution at the same line on my online backup of the game, I get a well-defined BABYLON.Engine.audioEngine …
EDIT: I made it work again, with 4.0.0-alpha.4! I needed to delete node_modules and re-run npm install. Somehow npm did not revert babylonjs correctly. The question remains: how to make my sounds work with the real 4.0?
I installed it through npm, I run my local server with webpack, and I use typescript, with the settings:
{
"compilerOptions": {
/* Basic Options */
"target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
"lib": ["es2015", "dom"], /* Specify library files to be included in the compilation. */
/* Strict Type-Checking Options */
"strict": true, /* Enable all strict type-checking options. */
/* List of folders to include type definitions from. */
"types": [
"babylonjs",
"babylonjs-materials",
"babylonjs-gui"
], /* Type declaration files to be included in compilation. */
"allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
}
}
this.pickUpSound = new BABYLON.Sound('Letter.PickUp', './assets/sounds/letter_collection_2notes.wav', this.scene);
would work in the PG, right? it seems that my problem is that the BABYLON.Engine.audioEngine is undefined at the time I reach this line; not sure how I could reproduce that…
Ok so I started a project from scratch installing the last version of babylonjs (stable) and of webpack. I wrote the bare minimum:
import * as BABYLON from 'babylonjs';
export class Main { // that is kind of our Game State Manager
private _canvas: HTMLCanvasElement;
private _engine!: BABYLON.Engine;
scene !: BABYLON.Scene;
constructor(canvasElement : string) {
// Create canvas and engine.
this._canvas = document.getElementById(canvasElement) as HTMLCanvasElement;
this._engine = new BABYLON.Engine(this._canvas, true);
this.createScene(this._engine, this._canvas);
this.initScene();
}
createScene(engine:BABYLON.Engine, canvas:HTMLCanvasElement){
this.scene = new BABYLON.Scene(engine);
// This creates and positions a free camera (non-mesh)
var camera = new BABYLON.FreeCamera("camera1", new BABYLON.Vector3(0, 5, -10), this.scene);
var music1 = new BABYLON.Sound("Violons11", "./assets/sounds/congratulation-small.wav", this.scene,
soundReady, { loop: true });
function soundReady() {
music1.play();
}
}
protected initScene() {
// Register update function:
this.scene.registerBeforeRender(() => this.update())
// Run the render loop.
this._engine.runRenderLoop(() => {
this.scene.render();
});
// The canvas/window resize event handler.
window.addEventListener('resize', () => {
this._engine.resize();
});
}
update(){}
}
window.addEventListener('DOMContentLoaded', () => {
// Create the game using the 'renderCanvas'.
let game = new Main('renderCanvas');
});
And it worked …
So I have no idea what is going on in my other project