Skip to content

Commit 6da3266

Browse files
committed
Migrate music-metadata-browser to music-metadata
1 parent a6b6e3e commit 6da3266

File tree

5 files changed

+48
-60
lines changed

5 files changed

+48
-60
lines changed

docs/README.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,10 @@ And all the developers and artists, for the following resources:
6565

6666
### JavaScript libraries <!-- {docsify-ignore} -->
6767

68-
* [buffer](https://www.npmjs.com/package/buffer) - Node.js Buffer API, for the browser
6968
* [http-server](https://www.npmjs.com/package/http-server) - a simple zero-configuration command-line http server
7069
* [idb-keyval](https://www.npmjs.com/package/idb-keyval) - super-simple promise-based keyval store implemented with IndexedDB
71-
* [music-metadata-browser](https://www.npmjs.com/package/music-metadata-browser) - stream and file based music metadata parser for the browser
70+
* [music-metadata](https://www.npmjs.com/package/music-metadata) - comprehensive metadata parser for audio and video files, supporting both file and stream inputs in Node.js and the browser
7271
* [notie](https://www.npmjs.com/package/notie) - clean and simple notification, input, and selection suite for javascript, with no dependencies
73-
* [process](https://www.npmjs.com/package/process) - process information for node.js and browsers
7472
* [scrollIntoViewIfNeeded 4 everyone](https://gist.github.com/hsablonniere/2581101) - polyfill for non-standard scrollIntoViewIfNeeded() method
7573
* [sortablejs](https://www.npmjs.com/package/sortablejs) - JavaScript library for reorderable drag-and-drop lists
7674
* [webpack](https://www.npmjs.com/package/webpack) - JavaScript module bundler for the browser

package.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,13 @@
1212
},
1313
"devDependencies": {
1414
"audiomotion-analyzer": "^4.5.1",
15-
"buffer": "^6.0.3",
1615
"css-loader": "^7.1.2",
1716
"css-minimizer-webpack-plugin": "^7.0.0",
1817
"http-server": "^14.1.1",
1918
"idb-keyval": "^6.2.1",
2019
"mini-css-extract-plugin": "^2.9.0",
21-
"music-metadata-browser": "^2.5.10",
20+
"music-metadata": "^11.7.0",
2221
"notie": "^4.3.1",
23-
"process": "^0.11.10",
2422
"sortablejs": "^1.15.2",
2523
"style-loader": "^4.0.0",
2624
"webpack": "^5.91.0",

src/index.js

Lines changed: 46 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
import AudioMotionAnalyzer from 'audiomotion-analyzer';
3333
import packageJson from '../package.json';
3434
import * as fileExplorer from './file-explorer.js';
35-
import * as mm from 'music-metadata-browser';
35+
import {parseBlob, parseBuffer, parseWebStream} from 'music-metadata';
3636
import './scrollIntoViewIfNeeded-polyfill.js';
3737
import { get, set, del } from 'idb-keyval';
3838

@@ -840,7 +840,6 @@ let audioElement = [],
840840
supportsFileSystemAPI, // browser supports File System API (may be disabled via config.json)
841841
useFileSystemAPI, // load music from local device when in web server mode
842842
userPresets,
843-
waitingMetadata = 0,
844843
wasMuted, // mute status before switching to microphone input
845844
webServer; // web server available? (boolean)
846845

@@ -2016,7 +2015,7 @@ function keyboardControls( event ) {
20162015
}
20172016

20182017
/**
2019-
* Sets (or removes) the `src` attribute of a audio element and
2018+
* Sets (or removes) the `src` attribute of an audio element and
20202019
* releases any data blob (File System API) previously in use by it
20212020
*
20222021
* @param {object} audio element
@@ -2120,7 +2119,8 @@ function loadGradientIntoCurrentGradient(gradientKey) {
21202119
/**
21212120
* Load a music file from the user's computer
21222121
*/
2123-
function loadLocalFile( obj ) {
2122+
async function loadLocalFile( obj ) {
2123+
21242124
const fileBlob = obj.files[0];
21252125

21262126
if ( fileBlob ) {
@@ -2129,11 +2129,14 @@ function loadLocalFile( obj ) {
21292129
audioEl.dataset.file = fileBlob.name;
21302130
audioEl.dataset.title = parsePath( fileBlob.name ).baseName;
21312131

2132-
// load and play
2133-
loadFileBlob( fileBlob, audioEl, true )
2134-
.then( url => mm.fetchFromUrl( url ) )
2135-
.then( metadata => addMetadata( metadata, audioEl ) )
2136-
.catch( e => {} );
2132+
try {
2133+
await loadFileBlob( fileBlob, audioEl, true );
2134+
// Maybe do this parallel?
2135+
const metadata = await parseBlob( fileBlob );
2136+
await addMetadata( metadata, audioEl );
2137+
} catch( error ) {
2138+
consoleLog("Failed to load local file", error);
2139+
}
21372140
}
21382141
}
21392142

@@ -3297,57 +3300,54 @@ async function retrieveBackgrounds() {
32973300
* Retrieve metadata for files in the play queue
32983301
*/
32993302
async function retrieveMetadata() {
3300-
// leave when we already have enough concurrent requests pending
3301-
if ( waitingMetadata >= MAX_METADATA_REQUESTS )
3302-
return;
33033303

3304-
// find the first play queue item for which we haven't retrieved the metadata yet
3305-
const queueItem = Array.from( playlist.children ).find( el => el.dataset.retrieve );
3304+
// find the first MAX_METADATA_REQUESTS items for which we haven't retrieved the metadata yet
3305+
const retrievalQueue = Array.from(playlist.children).filter(el => el.dataset.retrieve).slice(0, MAX_METADATA_REQUESTS);
33063306

3307-
if ( queueItem ) {
3307+
let file;
33083308

3309-
let uri = queueItem.dataset.file,
3310-
revoke = false;
3309+
// Execute in parallel
3310+
return Promise.all(retrievalQueue.map(async queueItem => {
33113311

3312-
waitingMetadata++;
33133312
delete queueItem.dataset.retrieve;
3313+
let metadata;
33143314

3315-
queryMetadata: {
3315+
try {
33163316
if ( queueItem.handle ) {
3317-
try {
3318-
if ( await queueItem.handle.requestPermission() != 'granted' )
3319-
break queryMetadata;
33203317

3321-
uri = URL.createObjectURL( await queueItem.handle.getFile() );
3322-
revoke = true;
3323-
}
3324-
catch( e ) {
3325-
break queryMetadata;
3326-
}
3327-
}
3318+
// Fetch metadata from File object
3319+
if (await queueItem.handle.requestPermission() !== 'granted')
3320+
return;
33283321

3329-
try {
3330-
const metadata = await mm.fetchFromUrl( uri, { skipPostHeaders: true } );
3331-
if ( metadata ) {
3332-
addMetadata( metadata, queueItem ); // add metadata to play queue item
3333-
syncMetadataToAudioElements( queueItem );
3334-
if ( ! ( metadata.common.picture && metadata.common.picture.length ) ) {
3335-
getFolderCover( queueItem ).then( cover => {
3336-
queueItem.dataset.cover = cover;
3337-
syncMetadataToAudioElements( queueItem );
3338-
});
3339-
}
3322+
file = await queueItem.handle.getFile();
3323+
metadata = await parseBlob(file);
3324+
}
3325+
else
3326+
{
3327+
// Fetch metadata from URI
3328+
const response = await fetch(uri);
3329+
if (response.body && typeof response.body.getReader === 'function') {
3330+
metadata = await parseWebStream(response.body, {skipPostHeaders: true});
3331+
} else {
3332+
// Fallback to Blob, in case the HTTP Result cannot be streamed
3333+
metadata = await parseBlob(await response.blob());
33403334
}
33413335
}
3342-
catch( e ) {}
3336+
}
3337+
catch( e ) {
3338+
consoleLog(`Error converting queued file="${queueItem.handle.file}" to URI`, e);
3339+
return;
3340+
}
33433341

3344-
if ( revoke )
3345-
URL.revokeObjectURL( uri );
3342+
addMetadata( metadata, queueItem ); // add metadata to play queue item
3343+
syncMetadataToAudioElements( queueItem );
3344+
queueItem.dataset.cover = await getFolderCover( queueItem );
3345+
if ( ! queueItem.handle && ! ( metadata.common.picture && metadata.common.picture.length ) ) {
3346+
queueItem.dataset.cover = await getFolderCover( queueItem );
3347+
syncMetadataToAudioElements( queueItem );
33463348
}
33473349

3348-
waitingMetadata--;
3349-
retrieveMetadata(); // call again to continue processing the queue
3350-
}
3350+
}));
33513351
}
33523352

33533353
/**

webpack.config.js

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,6 @@ module.exports = {
3636
new MiniCssExtractPlugin({
3737
filename: 'styles.css',
3838
}),
39-
new webpack.ProvidePlugin({
40-
Buffer: ['buffer', 'Buffer'],
41-
process: 'process/browser.js',
42-
}),
4339
],
4440
output: {
4541
filename: pathData => {

webpack.dev.js

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,6 @@ module.exports = {
3030
},
3131
plugins: [
3232
new webpack.HotModuleReplacementPlugin(),
33-
new webpack.ProvidePlugin({
34-
Buffer: ['buffer', 'Buffer'],
35-
process: 'process/browser.js',
36-
}),
3733
],
3834
output: {
3935
filename: 'audioMotion.js',

0 commit comments

Comments
 (0)