npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

museria

v0.3.5

Published

Decentralized music storage

Downloads

166

Readme

Museria [alpha] npm version Build status

Museria is a decentralized music storage based on spreadable, storacle and metastocle.

There is an article here with an explanation.

import { Node } from 'museria';

try {
  const node = new Node({
    port: 4000,
    hostname: 'localhost'
  });
  await node.init();
}
catch(err) {
  console.error(err.stack);
  process.exit(1);
}
import { Client } from 'museria';
import utils from 'museria/src/utils.js';

try {
  const client = new Client({
    address: 'localhost:4000'
  });
  await client.init();
  const title = 'Artist - Title';

  // Prepare the song tags
  await utils.addSongTags('./audio.mp3', {
    fullTitle: title,
    APIC: './cover.jpg'
  });

  // Add the song
  await client.addSong('./audio.mp3');

  // Get the song info
  const info = await client.getSong(title);

  // Find songs
  const songs = await client.findSongs('arti', { limit: 5 });

  // Find the artist songs
  const artistSongs = await client.findArtistSongs('artist');

  // Get the song audio link
  const audioLink = await client.getSongAudioLink(title);

  // Get the song cover link
  const coverLink = await client.getSongCoverLink(title);
  
  // Remove the song
  await client.removeSong(title);
}
catch(err) {
  console.error(err.stack);
  process.exit(1);
}

Browser client

You can also use the client in a browser. Look at the description of the spreadable library. In window you have window.ClientMuseria instead of window.ClientSpreadable. The prepared file name is museria.client.js.

How to use it via the command line

Look at the description of the spreadable library. You only need to change everywhere spreadable word to museria.

How it works

The mechanism of the library is very similar to storacle. The only difference is that the key to the file is the name of the song, not the hash. Also, a unique song is considered not with the full title match, but the percentage of coincidence set in the options.

What are the limitations

Currently only mp3 format is supported. The tags are id3, based on node-id3. TPE1 and TIT2 tags are required to store the song. You can use setter fullTitle as TPE1 - TIT2 when you set the tags using utils. It must be a valid combination for utils.isSongTitle() function. Also, the network may have its own cover size requirements. The number of songs that can be added to one node is configurable as well.

What are the requirements

Look at the storacle requirements and the metastocle requirements.

Moderation and priority

By adding a song, you can indicate whether you moderate it or not. The controlled option is responsible for this. By default, it is false. The moderation mode implies that you take care of the conformity and quality of the song. The file of the corresponding song located in the storage will be replaced with a new one without checks. Adding songs in this mode requires captcha confirmation.

await client.addSong(file, { controlled: true });

You can also specify the priority of your file as -1, 0 or 1. By default, it is 0. If the priority of the new song is higher than the existing one, then it will replace that without checks. If they are equal, then the storage itself will decide which one to choose. If less, then the song in the repository will remain the same. Only the tags, cover and other additional information might be updated in this case. Priority 1 may only be used in moderation mode.

await client.addSong(file, { priority: -1 });
await client.addSong(file, { priority: 1, controlled: true });

Where to use it

1. Wherever songs need to be stored decentralized

For example, we can collect all the music on the planet together in one place, but in a decentralized way with the ability to access it at any time.

2. For own needs

You can use it to store music as you like.

3. Serverless solutions

Since the library is written in javascript, you can receive / send / work with songs in the browser and do not use server code at all. In some cases, it can be very convenient.

Node configuration

When you create an instance of the node you can pass options below. Only specific options of this library are described here, without considering the options of the parent classes.

  • {object} [music] - section that responds for music settings.

  • {number} [music.similarity=0.91] - number from 0 to 1 indicating how similar songs titles have to be, in order to consider them the same.

  • {number|string} [music.audioHeadersMaxSize="180kb"] - maximum audio headers size.

  • {number|string} [music.coverHeadersMaxSize="5kb"] - maximum cover headers size.

  • {number} [music.findingStringMinLength=4] - minimum symbols to find songs.

  • {number} [music.findingLimit=200] - songs finding maximum result list size.

  • {number|string} [music.relevanceTime="14d"] - how long does an existing song take precedence over newly added.

  • {boolean} [music.prepareTitle=true] - prepare the title before addition or not. Preparation means bringing the title to a general view.

  • {boolean} [music.prepareCover=true] - prepare the cover before addition or not. Preparation means bringing the size and image quality to the right values.

  • {integer} [music.coverQuality=80] - prepared cover quality from 0 to 100. It works only when music.prepareCover is true.

  • {integer} [music.coverMinSize=200] - minimum cover size in px. It works only when music.prepareCover is true.

  • {integer} [music.coverMaxSize=500] - maximum cover size in px. It works only when music.prepareCover is true.

  • {number|string} [music.coverMaxFileSize="110kb"] - maximum cover file size. It works only when music.prepareCover is true.

  • {number|string} [task.cleanUpMusicInterval="1m"] - music cleanup task interval.

Client interface

async Client.prototype.addSong() - add the file to the network.

  • {string|fse.ReadStream|Buffer|Blob} file - mp3 audio file
  • {object} [options] - addition options
  • {number} [options.timeout] - addition timeout
  • {integer} [options.priority=0] - song priority -1, 1 or 0
  • {boolean} [options.controlled=false] - enable moderation mode or not

async Client.prototype.getSong() - get the song main info.

  • {string} title - song title
  • {object} [options] - getting options
  • {number} [options.timeout] - getting timeout

async Client.prototype.getSongInfo() - get the song complete info.

  • {string} title - song title
  • {object} [options] - getting options
  • {number} [options.timeout] - getting timeout

async Client.prototype.findSongs() - find songs by the match.

  • {string} str - string to match
  • {object} [options] - getting options
  • {number} [options.limit] - result list maximum size
  • {number} [options.timeout] - getting timeout

async Client.prototype.findArtistSongs() - find songs by the artist name.

  • {string} artist - artist name
  • {object} [options] - getting options
  • {number} [options.timeout] - getting timeout

async Client.prototype.getSongAudioLink() - get the song audio file link.

  • {string} title - song title
  • {object} [options] - getting options
  • {number} [options.timeout] - getting timeout

async Client.prototype.getSongCoverLink() - get the song cover file link.

  • {string} title - song title
  • {object} [options] - getting options
  • {number} [options.timeout] - getting timeout

async Client.prototype.getSongAudioToBuffer() - download the song audio file and return the buffer.

  • {string} title - song title
  • {object} [options] - getting options
  • {number} [options.timeout] - getting timeout

async Client.prototype.getSongCoverToBuffer() - download the song cover file and return the buffer.

  • {string} title - song title
  • {object} [options] - getting options
  • {number} [options.timeout] - getting timeout

async Client.prototype.getSongAudioToPath() - download the song audio file and write it to the specified path.

  • {string} title - song title
  • {object} [options] - getting options
  • {number} [options.timeout] - getting timeout

async Client.prototype.getSongCoverToPath() - download the song cover file and write it to the specified path.

  • {string} title - song title
  • {object} [options] - getting options
  • {number} [options.timeout] - getting timeout

async Client.prototype.getSongAudioToBlob() - download the song audio file and return the blob. For browser client only.

  • {string} title - song title
  • {object} [options] - getting options
  • {number} [options.timeout] - getting timeout

async Client.prototype.getSongCoverToBlob() - download the song cover file and return the blob. For browser client only.

  • {string} title - song title
  • {object} [options] - getting options
  • {number} [options.timeout] - getting timeout

async Client.prototype.removeSong() - Remove the song.

  • {string} title - song title
  • {object} [options] - removal options
  • {number} [options.timeout] - removal timeout

Client.prototype.createRequestedSongAudioLink() - сreate a requested audio file link. This is convenient if you need to get the link without doing any asynchronous operations at the moment.

  • {string} title - song title
  • {object} [options] - options

Client.prototype.createRequestedSongCoverLink() - сreate a requested cover file link. This is convenient if you need to get the link without doing any asynchronous operations at the moment.

  • {string} title - song title
  • {object} [options] - options

Exporting songs

If necessary, you have the opportunity to export songs from one server to another. There are two options:

  • Copy all project files to the second server. It is convenient and works at the current moment, because the node is able to reconfigure all information to a new address. But there is no guarantee that this will work in the future.

  • Use the song export feature: run node.exportSongs() method or via the command line as museria -a exportSongs -n 2.2.2.2:2079. Here, you should add the first server to the trust list of the second one to transfer all songs, including those with priority 1. Without this, the node will require a captcha solution and the file will not be added. Use the option network.trustlist of the spreadable library.

Contribution

If you face a bug or have an idea how to improve the library, create an issue on github. In order to fix something or add new code yourself, fork the library, make changes and create a pull request to the master branch. Don't forget about tests in this case. Also you can join the project on github.