Merge pull request #1105 from mzgoddard/dynamic-load-music

Dynamically load music extension manifest
This commit is contained in:
Ray Schamp 2018-05-07 14:38:37 -04:00 committed by GitHub
commit 784705d46e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -5,17 +5,6 @@ const Cast = require('../../util/cast');
const MathUtil = require('../../util/math-util'); const MathUtil = require('../../util/math-util');
const Timer = require('../../util/timer'); const Timer = require('../../util/timer');
/**
* The instrument and drum sounds, loaded as static assets.
* @type {object}
*/
let assetData = {};
try {
assetData = require('./manifest');
} catch (e) {
// Non-webpack environment, don't worry about assets.
}
/** /**
* Icon svg to be displayed at the left edge of each extension block, encoded as a data URI. * Icon svg to be displayed at the left edge of each extension block, encoded as a data URI.
* @type {string} * @type {string}
@ -102,6 +91,27 @@ class Scratch3MusicBlocks {
}); });
} }
_fetchSounds () {
if (!this._assetData) {
this._assetData = new Promise((resolve, reject) => {
// Use webpack supported require.ensure to dynamically load the
// manifest as an another javascript file. Once the file
// executes the callback will be called and we can require the
// manifest.
//
// You can either make require calls in the callback function or
// specify dependencies in the array to load. The third argument
// is an error callback. The forth argument is a name for the
// javascript that can be used depending on the webpack
// configuration.
require.ensure([], () => {
resolve(require('./manifest'));
}, reject, 'vm-music-manifest');
});
}
return this._assetData;
}
/** /**
* Decode a sound and store the buffer in an array. * Decode a sound and store the buffer in an array.
* @param {string} filePath - the audio file name. * @param {string} filePath - the audio file name.
@ -112,14 +122,23 @@ class Scratch3MusicBlocks {
_storeSound (filePath, index, bufferArray) { _storeSound (filePath, index, bufferArray) {
const fullPath = `${filePath}.mp3`; const fullPath = `${filePath}.mp3`;
if (!assetData[fullPath]) return; return this._fetchSounds()
// In case require.ensure is not available (such as running this
// file directly in node instead of through the webpack built script
// for node) or that require.ensure fails, turn the error into an
// empty object. The music extension will ignore the sound files.
.catch(() => ({}))
.then(assetData => {
if (!assetData[fullPath]) return;
// The sound buffer has already been downloaded via the manifest file required above. // The sound buffer has already been downloaded via the manifest file required above.
const soundBuffer = assetData[fullPath]; const soundBuffer = assetData[fullPath];
return this._decodeSound(soundBuffer).then(buffer => { return this._decodeSound(soundBuffer);
bufferArray[index] = buffer; })
}); .then(buffer => {
bufferArray[index] = buffer;
});
} }
/** /**