rg_
rg_

Reputation: 431

Using PreloadJS and SoundJS in React app to preload sounds

I’m trying to use PreloadJS and SoundJS in a React app to preload all sounds and then play from the preloaded cache.

I can't figure out how to create the LoadQueue and load the sounds in one component (top level: App.jsx ), and play them in a different component (child of App.jsx: Board.jsx).

The preloader is working fine but I can't get sounds to play in the child component. When I try to call createjs.Sound.play() I keep getting error messages that createjs.Sound is undefined. I think it has something to do with the fact that I'm installing the Sound plugin in one component and then trying to access it somewhere else, but the Sound plugin seems to be attached to the LoadQueue itself and I don't think I want a new LoadQueue in the Board component? What am I doing wrong?

Things I have tried so far that have not worked:

  1. Modifying webpack.config according to instructions in this answer, which is supposed to make createjs available in the global context
  2. Defining a playSound method in my top-level component (where the LoadQueue is defined) and passing that method as a prop to the child component where I want to play the sound.

asset_loader.js

import createjs from 'preload-js';
import manifest from '../sounds/asset_manifest.json';

const assetLoader = () => {
  // Reset the UI
  document.getElementById('progress').style.width = '0px';

  // Create a preloader.
  const preload = new createjs.LoadQueue();
  preload.installPlugin(createjs.Sound);
  const assetManifest = manifest.manifest;

  // If there is an open preload queue, close it.
  if (preload != null) {
    preload.close();
  }

  // File complete handler
  const handleFileLoad = (event) => {
    console.log(`Preloaded: ${event.item.id}`);
  };

  // Overall progress handler
  const handleOverallProgress = () => {
    document.getElementById('progress').style.width = `${(preload.progress * document.getElementById('progress-wrap').clientWidth)}px`;
  };

  // Error handler
  const handleFileError = (event) => {
    console.log(`error: ${event.item.id}, ${event.text}`);
  };

  const handleComplete = () => {
    console.log('loading complete');
  };

  preload.on('fileload', handleFileLoad);
  preload.on('progress', handleOverallProgress);
  preload.on('error', handleFileError);
  preload.on('complete', handleComplete);
  preload.setMaxConnections(5);

  const loadAnother = () => {
    // Get the next manifest item, and load it
    const item = assetManifest.shift();
    preload.loadFile(item);
  };

  const loadAll = () => {
    while (assetManifest.length > 0) {
      loadAnother();
    }
  };
  loadAll();
};

export default assetLoader;

App.jsx

import React from 'react';

// …

import assetLoader from './utils/asset_loader';


class App extends React.Component {

  componentDidMount() {
    assetLoader();
  }

// …

Board.jsx

// …
import createjs from 'preload-js';

//…

playSound(item) {
     console.log(`playing sound: ${item}`);
     createjs.Sound.play(item);
  }

Error message: Uncaught TypeError: Cannot read property 'play' of undefined

Upvotes: 1

Views: 1540

Answers (0)

Related Questions