Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,10 @@ And all the developers and artists, for the following resources:

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

* [buffer](https://www.npmjs.com/package/buffer) - Node.js Buffer API, for the browser
* [http-server](https://www.npmjs.com/package/http-server) - a simple zero-configuration command-line http server
* [idb-keyval](https://www.npmjs.com/package/idb-keyval) - super-simple promise-based keyval store implemented with IndexedDB
* [music-metadata-browser](https://www.npmjs.com/package/music-metadata-browser) - stream and file based music metadata parser for the browser
* [music-metadata](https://www.npmjs.com/package/music-metadata) - Metadata parser for audio and video media files. Supports file and stream inputs in Node.js and browser environments, extracting format, tag, and duration information.
* [notie](https://www.npmjs.com/package/notie) - clean and simple notification, input, and selection suite for javascript, with no dependencies
* [process](https://www.npmjs.com/package/process) - process information for node.js and browsers
* [scrollIntoViewIfNeeded 4 everyone](https://gist.github.com/hsablonniere/2581101) - polyfill for non-standard scrollIntoViewIfNeeded() method
* [sortablejs](https://www.npmjs.com/package/sortablejs) - JavaScript library for reorderable drag-and-drop lists
* [webpack](https://www.npmjs.com/package/webpack) - JavaScript module bundler for the browser
Expand Down
4 changes: 1 addition & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,14 @@
},
"devDependencies": {
"audiomotion-analyzer": "^4.5.1",
"buffer": "^6.0.3",
"css-loader": "^7.1.2",
"css-minimizer-webpack-plugin": "^7.0.0",
"http-server": "^14.1.1",
"idb-keyval": "^6.2.1",
"js-yaml": "^4.1.0",
"mini-css-extract-plugin": "^2.9.0",
"music-metadata-browser": "^2.5.10",
"music-metadata": "^11.8.3",
"notie": "^4.3.1",
"process": "^0.11.10",
"sortablejs": "^1.15.2",
"style-loader": "^4.0.0",
"webpack": "^5.91.0",
Expand Down
60 changes: 40 additions & 20 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
import AudioMotionAnalyzer from 'audiomotion-analyzer';
import packageJson from '../package.json';
import * as fileExplorer from './file-explorer.js';
import * as mm from 'music-metadata-browser';
import {parseBlob, parseWebStream} from 'music-metadata';
import './scrollIntoViewIfNeeded-polyfill.js';
import { get, set, del } from 'idb-keyval';
import * as yaml from 'js-yaml';
Expand Down Expand Up @@ -1973,7 +1973,7 @@ function keyboardControls( event ) {
}

/**
* Sets (or removes) the `src` attribute of a audio element and
* Sets (or removes) the `src` attribute of an audio element and
* releases any data blob (File System API) previously in use by it
*
* @param {object} audio element
Expand Down Expand Up @@ -2077,7 +2077,7 @@ function loadGradientIntoCurrentGradient(gradientKey) {
/**
* Load a music file from the user's computer
*/
function loadLocalFile( obj ) {
async function loadLocalFile( obj ) {
const fileBlob = obj.files[0];

if ( fileBlob ) {
Expand All @@ -2086,11 +2086,17 @@ function loadLocalFile( obj ) {
audioEl.dataset.file = fileBlob.name;
audioEl.dataset.title = parsePath( fileBlob.name ).baseName;

// load and play
loadFileBlob( fileBlob, audioEl, true )
.then( url => mm.fetchFromUrl( url ) )
.then( metadata => addMetadata( metadata, audioEl ) )
.catch( e => {} );
try {
// Start both tasks, but only await parseBlob immediately
const loadTask = loadFileBlob(fileBlob, audioEl, true);
const metadata = await parseBlob( fileBlob );
await addMetadata(metadata, audioEl);

// Wait for loadTask to complete
await loadTask;
} catch( error ) {
consoleLog("Failed to load local file", error);
}
}
}

Expand Down Expand Up @@ -3279,21 +3285,35 @@ async function retrieveMetadata() {
break queryMetadata;
}
}

try {
const metadata = await mm.fetchFromUrl( uri, { skipPostHeaders: true } );
if ( metadata ) {
addMetadata( metadata, queueItem ); // add metadata to play queue item
syncMetadataToAudioElements( queueItem );
if ( ! ( metadata.common.picture && metadata.common.picture.length ) ) {
getFolderCover( queueItem ).then( cover => {
queueItem.dataset.cover = cover;
syncMetadataToAudioElements( queueItem );
});
else {
// Fetch metadata from URI
const response = await fetch(queueItem.dataset.file);
if (response.ok) {
try {
let metadata;
if (response.body?.getReader) {
const contentType = response.headers.get("Content-Type");
const contentSize = response.headers.get("Content-Length");
try {
metadata = await parseWebStream(response.body, {
mimeType: contentType,
size: contentSize ? Number.parseInt(contentSize, 10) : undefined
}, {skipPostHeaders: true});
} finally {
await response.body.cancel();
}
} else {
// Fallback to Blob, in case the HTTP Result cannot be streamed
metadata = await parseBlob(await response.blob());
}
addMetadata(metadata, queueItem); // add metadata to play queue item
} catch(e) {
consoleLog('Failed to retrieve metadata', e)
}
} else {
consoleLog(`Failed to fetch metadata http-response=${response.status} for url=${queueItem.dataset.file}`, true);
}
}
catch( e ) {}

if ( revoke )
URL.revokeObjectURL( uri );
Expand Down
4 changes: 0 additions & 4 deletions webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,6 @@ module.exports = {
new MiniCssExtractPlugin({
filename: 'styles.css',
}),
new webpack.ProvidePlugin({
Buffer: ['buffer', 'Buffer'],
process: 'process/browser.js',
}),
],
output: {
filename: pathData => {
Expand Down
4 changes: 0 additions & 4 deletions webpack.dev.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,6 @@ module.exports = {
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.ProvidePlugin({
Buffer: ['buffer', 'Buffer'],
process: 'process/browser.js',
}),
],
output: {
filename: 'audioMotion.js',
Expand Down