Partial Progress with rewriting parts of Song.js
Also started work on Writing Storage.js Storage.js manages info across sessions of melodii
This commit is contained in:
parent
dd58f5512f
commit
152ef58e41
11
src/App.js
11
src/App.js
|
@ -24,17 +24,16 @@ const filepath = new Filepath("C:\\Users\\Paoda\\Downloads\\Music");
|
|||
(async () => {
|
||||
let list = await filepath.getValidFiles();
|
||||
|
||||
let song = new Song(list[~~(Math.random() * list.length)]);
|
||||
song = await Song.getMetadata(song);
|
||||
Song.setAlbumArt(song.metadata);
|
||||
let song = new Song(list[~~(Math.random() * list.length)], true);
|
||||
await song.getMetadata();
|
||||
|
||||
mp.loadSong(song);
|
||||
// mp.play();
|
||||
|
||||
mp.element.onended = async () => {
|
||||
let song = new Song(list[~~(Math.random() * list.length)]);
|
||||
song = await Song.getMetadata(song);
|
||||
Song.setAlbumArt(song.metadata);
|
||||
let song = new Song(list[~~(Math.random() * list.length)], true);
|
||||
await song.getMetadata();
|
||||
|
||||
mp.loadSong(song);
|
||||
mp.play();
|
||||
};
|
||||
|
|
|
@ -152,7 +152,7 @@ export default class Body extends React.Component {
|
|||
term = parseInt(term, 10);
|
||||
temp.tbody = table.tbody.filter(obj => obj.year === term);
|
||||
} else {
|
||||
// type == time
|
||||
// type === time
|
||||
term = term.toLowerCase();
|
||||
temp.tbody = table.tbody.filter(obj =>
|
||||
obj.time.toLowerCase().includes(term)
|
||||
|
|
|
@ -262,7 +262,7 @@ export function sortTable(table, term) {
|
|||
return a.year - b.year;
|
||||
});
|
||||
} else if (term === "time") {
|
||||
//term == time convert the time into seconds
|
||||
//term === time convert the time into seconds
|
||||
//The messy else if + else is becomes a.inSeconds || b.inSeconds can be undefined.
|
||||
tbody.sort((a, b) => {
|
||||
if (a.inSeconds && b.inSeconds) {
|
||||
|
|
|
@ -49,6 +49,8 @@ export default class MusicPlayer {
|
|||
*/
|
||||
load(playlist) {
|
||||
const song = playlist.next();
|
||||
|
||||
song.getMetadata().then(() => {
|
||||
let path = song.location;
|
||||
|
||||
try {
|
||||
|
@ -58,12 +60,16 @@ export default class MusicPlayer {
|
|||
} catch(e) {
|
||||
console.error(path + " failed to load " + e.name + " from " + playlist.title);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/** Loads Song
|
||||
* @param {Song} song
|
||||
*/
|
||||
loadSong(song) {
|
||||
|
||||
song.displayAlbumArt();
|
||||
|
||||
if (archive.getCurrentSong() !== undefined)
|
||||
archive.add(archive.getCurrentSong());
|
||||
let path = song.location;
|
||||
|
|
|
@ -9,10 +9,85 @@ export default class Song {
|
|||
* @param {String} path
|
||||
* @param {Boolean} ShouldAlbumArtExist
|
||||
*/
|
||||
constructor(path, ShouldAlbumArtExist) { //whether album art should exist
|
||||
constructor(path, shouldCreateAlbumArt = false) { //whether album art should exist
|
||||
this.location = path;
|
||||
this.title = "";
|
||||
this.unf_time = 0;
|
||||
this.album = "";
|
||||
this.year = 0;
|
||||
this.genres = [];
|
||||
this.genre = "";
|
||||
|
||||
this.albumArt = "";
|
||||
this.albumArtPresent = false;
|
||||
|
||||
this.shouldCreateAlbumArt = shouldCreateAlbumArt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets Metadata from File.
|
||||
*/
|
||||
getMetadata() {
|
||||
return new Promise((res, rej) => {
|
||||
mm.parseFile(this.location, { native: true, duration: true }).then((metadata) => {
|
||||
|
||||
this.metadata = metadata;
|
||||
|
||||
console.log(metadata);
|
||||
|
||||
const format = metadata.format;
|
||||
const common = metadata.common;
|
||||
|
||||
|
||||
this.title = common.title || "";
|
||||
this.unf_time = format.duration || 0;
|
||||
this.album = common.album || "";
|
||||
this.year = common.year || 0;
|
||||
this.genre = common.genre ? common.genre.toString() : "";
|
||||
|
||||
if (this.shouldCreateAlbumArt) this.getAlbumArt(common.picture);
|
||||
|
||||
|
||||
res();
|
||||
}).catch((err) => rej(err));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds and Loads Album Art. Saves it to Song instance.
|
||||
* TODO: Move the Event emission to only occur when the song is played.
|
||||
* @param {*} picture
|
||||
*/
|
||||
getAlbumArt(picture) {
|
||||
if (picture) {
|
||||
if (picture.length > 0) {
|
||||
console.log(picture);
|
||||
const pic = picture[0];
|
||||
|
||||
this.albumArt = URL.createObjectURL(new Blob([pic.data], {
|
||||
'type': pic.format
|
||||
}));
|
||||
this.albumArtPresent = true;
|
||||
} else console.error(this.title + ' Has Album Art, however, no data was found.');
|
||||
|
||||
} else console.warn(this.title, + ' does not have Album Art.');
|
||||
}
|
||||
|
||||
displayAlbumArt() {
|
||||
console.log("Album Art", this.albumArt);
|
||||
console.log("Album Art is Present: ", this.albumArtPresent)
|
||||
if (this.albumArtPresent) Emitter.emit('updateAlbumArt', this.albumart);
|
||||
else Emitter.emit('updateAlbumArt', noalbumart);
|
||||
}
|
||||
|
||||
get time() {
|
||||
let min = ~~((format.duration % 3600) / 60);
|
||||
let sec = ~~(format.duration % 60);
|
||||
if (sec < 10) sec = "0" + sec;
|
||||
return min + ":" + sec;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets Metadata from Song
|
||||
* @param {Song} song
|
||||
|
|
|
@ -0,0 +1,133 @@
|
|||
import Song from './Song';
|
||||
import Filepath from './Filepath'
|
||||
|
||||
/**
|
||||
* This classs Manages:
|
||||
* - User Settings
|
||||
* - Metadata Saving
|
||||
* - Passing of Metadata to Table Generation
|
||||
*
|
||||
* The Goal of This function is to remove the complete dependence of electron-settings
|
||||
* and the fact that melodii (2019.03.22) relies on Tabe.js for Saving metadata as well as table configurations.
|
||||
*/
|
||||
class Storage {
|
||||
constructor(path) {
|
||||
this.path = path;
|
||||
this.ready = false; // Async Actions still need to happen
|
||||
|
||||
/** @type {Array<Albums>} */
|
||||
this.albums = [];
|
||||
|
||||
this.init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the Storage Instance.
|
||||
* @async
|
||||
* @private
|
||||
*/
|
||||
async init() {
|
||||
const filepath = new Filepath(path);
|
||||
this.knownFiles = await filepath.getValidFiles();
|
||||
|
||||
this.ready = true; // All prerequisite Async has been done.
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Goes Through all Known Songs and
|
||||
* Creates Object Representatinos of all of them.
|
||||
*
|
||||
*/
|
||||
parseSongList() {
|
||||
const files = this.knownFiles;
|
||||
|
||||
// Need to Iterate over every song, find the name of the album and create an album with that instance.
|
||||
// Store the album in some array so we know what albums exist and have a method to check whether the album has been
|
||||
// created or not. Once that is done we can then create a Song based of that, and add it to the album.
|
||||
|
||||
// The end result should be an album class with all the properties filled in
|
||||
// with attention put towards this.songs which would be an array of Song classes.
|
||||
|
||||
files.forEach(async path => {
|
||||
const song = new Song(path, true);
|
||||
|
||||
const albumName = song.metadata.common.album;
|
||||
|
||||
if (!albumExists(albumName)) {
|
||||
const album = new Album(albumName);
|
||||
album.addSong(song);
|
||||
|
||||
|
||||
this.albums.push(album)
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
const self = this;
|
||||
|
||||
/**
|
||||
* Returns true if album is already present in List of known Albums.
|
||||
* @param {*} name
|
||||
*/
|
||||
function albumExists(name) {
|
||||
/// Please Write a Better version of this later.
|
||||
let exists = false;
|
||||
|
||||
for (let i = 0; i < self.albums.length; i++) {
|
||||
if (self.albums[i].name === name) {
|
||||
exists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return exists;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Class Representation of an Album of Songs
|
||||
*
|
||||
*/
|
||||
class Album {
|
||||
/** @param {String} name */
|
||||
constructor(name) {
|
||||
// Properties Here are based off what is commonly found within Mp3 Tags.
|
||||
|
||||
/** @type {String} */
|
||||
this.name
|
||||
|
||||
/** @type {Array<Song>} */
|
||||
this.songs = [];
|
||||
|
||||
/** Album Artist */
|
||||
this.artist = ""
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds Class Representation of a Song to an Album Class
|
||||
* @param {Song} song
|
||||
*/
|
||||
addSong(song) {
|
||||
this.songs.push(song);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes a Song Class from the Album
|
||||
* @param {String} path
|
||||
*/
|
||||
removeSong(path) {
|
||||
console.error("This feature is unimplimented.")
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue