• Stars
    star
    148
  • Rank 249,983 (Top 5 %)
  • Language
    TypeScript
  • Created almost 6 years ago
  • Updated 3 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Node MusicBrainz API client for reading and submitting metadata

Node.js CI NPM version npm downloads Coverage Status Codacy Badge CodeQL Known Vulnerabilities DeepScan grade Discord

musicbrainz-api

A MusicBrainz-API-client for reading and submitting metadata

Features

  • Access metadata from MusicBrainz
  • Submit metadata
  • Smart and adjustable throttling, like MusicBrainz, it allows a bursts of requests
  • Build in TypeScript definitions

Hint

This package is currently only developed for the use in a node.js environment. We are looking into making this package usable in the browser as well.

Before using this library

MusicBrainz asks that you identifying your application by filling in the 'User-Agent' Header. By passing appName, appVersion, appMail musicbrainz-api takes care of that.

Submitting metadata

If you plan to use this module for submitting metadata, please ensure you comply with the MusicBrainz Code of conduct/Bots.

Example

Import the module JavaScript example, how to import 'musicbrainz-api:

const MusicBrainzApi = require('musicbrainz-api').MusicBrainzApi;

const mbApi = new MusicBrainzApi({
  appName: 'my-app',
  appVersion: '0.1.0',
  appContactInfo: '[email protected]'
});

In TypeScript it would look like this:

import {MusicBrainzApi} from 'musicbrainz-api';

const mbApi = new MusicBrainzApi({
  appName: 'my-app',
  appVersion: '0.1.0',
  appContactInfo: '[email protected]' // Or URL to application home page
});

The following configuration settings can be passed

import {MusicBrainzApi} from '../src/musicbrainz-api';

const config = {
  // MusicBrainz bot account username & password (optional)
  botAccount: { 
    username: 'myUserName_bot',
    password: 'myPassword' 
  },
  
  // API base URL, default: 'https://musicbrainz.org' (optional)
  baseUrl: 'https://musicbrainz.org',

  appName: 'my-app',
  appVersion: '0.1.0',

  // Optional, default: no proxy server
  proxy: {
    host: 'localhost',
    port: 8888
   },

  // Your e-mail address, required for submitting ISRCs
  appMail: string
}

const mbApi = new MusicbrainzApi(config);

Lookup MusicBrainz Entities

MusicBrainz API documentation: XML Web Service/Version 2 Lookups

Generic lookup function

Arguments:

  • entity: 'artist' | 'label' | 'recording' | 'release' | 'release-group' | 'work' | 'area' | 'url'
  • MBID (MusicBrainz identifier)
const artist = await mbApi.lookupEntity('artist', 'ab2528d9-719f-4261-8098-21849222a0f2');

Lookup area

const area = await mbApi.lookupArea('ab2528d9-719f-4261-8098-21849222a0f2');

Lookup artist

Lookup an artist and include their releases, release-groups and aliases

const artist = await mbApi.lookupArtist('ab2528d9-719f-4261-8098-21849222a0f2');

Lookup instrument

Lookup an instrument

const instrument = await mbApi.lookupInstrument('b3eac5f9-7859-4416-ac39-7154e2e8d348');

Lookup label

Lookup a label

const label = await mbApi.lookupLabel('25dda9f9-f069-4898-82f0-59330a106c7f');

Lookup place

const place = await mbApi.lookupPlace('e6cfb74d-d69b-44c3-b890-1b3f509816e4');

The second argument can be used to pass subqueries, which will return more (nested) information:

const artist = await mbApi.lookupArtist('ab2528d9-719f-4261-8098-21849222a0f2', ['releases', 'recordings', 'url-rels']);

Lookup recording

The second argument can be used to pass subqueries:

const recording = await mbApi.lookupRecording('16afa384-174e-435e-bfa3-5591accda31c', ['artists', 'url-rels']);

Lookup release

const release = await mbApi.lookupRelease('976e0677-a480-4a5e-a177-6a86c1900bbf', ['artists', 'url-rels']);

Lookup release-group

const releaseGroup = await mbApi.lookupReleaseGroup('19099ea5-3600-4154-b482-2ec68815883e');

Lookup work

const work = await mbApi.lookupWork('b2aa02f4-6c95-43be-a426-aedb9f9a3805');

Lookup URL

const url = await mbApi.lookupUrl('c69556a6-7ded-4c54-809c-afb45a1abe7d');

Browse entities

Browse area

const area = await browseAreas(query);
Query argument Query value
query.collection Collection MBID

Browse artist

const artist = await browseArtist(query);
Query argument Query value
query.area Area MBID
query.collection Collection MBID
query.recording Recording MBID
query.release Release MBID
query.release-group Release-group MBID
query.work Work MBID

Browse collection

const artist = await browseCollection(query);
Query argument Query value
query.area Area MBID
query.artist Artist MBID
query.editor Editor MBID
query.event Event MBID
query.label Label MBID
query.place Place MBID
query.recording Recording MBID
query.release Release MBID
query.release-group Release-group MBID
query.work Work MBID

Browse events

const events = await browseEvents(query);
Query argument Query value
query.area Area MBID
query.artist Artist MBID
query.collection Collection MBID
query.place Place MBID

Browse instruments

const instruments = await browseEvents(query);
Query argument Query value
query.collection Collection MBID

Browse labels

const labels = await browseLabels(query);
Query argument Query value
query.area Area MBID
query.collection Collection MBID
query.release Release MBID

Browse places

const places = await browsePlaces(query);
Query argument Query value
query.area Area MBID
query.collection Collection MBID

Browse recordings

const recordings = await browseRecordings(query);
Query argument Query value
query.artist Area MBID
query.collection Collection MBID
query.release Release MBID
query.work Work MBID

Browse releases

const places = await browseReleases(query);
Query argument Query value
query.area Area MBID
query.artist Artist MBID
query.editor Editor MBID
query.event Event MBID
query.label Label MBID
query.place Place MBID
query.recording Recording MBID
query.release Release MBID
query.release-group Release-group MBID
query.work Work MBID

Browse release-groups

const places = await browseReleaseGroups(query);
Query argument Query value
query.artist Artist MBID
query.collection Collection MBID
query.release Release MBID

Browse series

const places = await browseSeries();
Query argument Query value
query.area Area MBID
query.artist Artist MBID
query.editor Editor MBID
query.event Event MBID
query.label Label MBID
query.place Place MBID
query.recording Recording MBID
query.release Release MBID
query.release-group Release-group MBID
query.work Work MBID

Browse works

const places = await browseWorks();
Query argument Query value
query.artist Artist MBID
query.xollection Collection MBID

Browse urls

const urls = await browseUrls();
Query argument Query value
query.artist Artist MBID
query.xollection Collection MBID

Search (query)

Implements XML Web Service/Version 2/Search.

There are different search fields depending on the entity.

Generic search function

Searches can be performed using the generic search function: query(entity: mb.EntityType, query: string | IFormData, offset?: number, limit?: number)

Arguments:

  • Entity type, which can be one of:
  • query {query: string, offset: number, limit: number}
    • query.query: supports the full Lucene Search syntax; you can find a detailed guide at Lucene Search Syntax. For example, you can set conditions while searching for a name with the AND operator.
    • query.offset: optional, return search results starting at a given offset. Used for paging through more than one page of results.
    • limit.query: optional, an integer value defining how many entries should be returned. Only values between 1 and 100 (both inclusive) are allowed. If not given, this defaults to 25.

For example, to find any recordings of 'We Will Rock You' by Queen:

const query = 'query="We Will Rock You" AND arid:0383dadf-2a4e-4d10-a46a-e9e041da8eb3';
const result = await mbApi.query<mb.IReleaseGroupList>('release-group', {query});
Example: search ÃŽle-de-France
 mbApi.search('area', 'ÃŽle-de-France');
Example: search release by barcode

Search a release with the barcode 602537479870:

 mbApi.search('release', {query: {barcode: 602537479870}});
Example: search by object

Same as previous example, but automatically serialize parameters to search query

 mbApi.search('release', 'barcode: 602537479870');

Entity specific search functions

The following entity specific search functions are available:

searchArtist(query: string | IFormData, offset?: number, limit?: number): Promise<mb.IArtistList>
searchReleaseGroup(query: string | IFormData, offset?: number, limit?: number): Promise<mb.IReleaseGroupList>`

Search artist:

const result = await mbApi.searchArtist({query: 'Stromae'});

Search release-group:

const result = await mbApi.searchReleaseGroup({query: 'Racine carrée'});

Search a combination of a release-group and an artist.

const result = await mbApi.searchReleaseGroup({artist: 'Racine carrée', releasegroup: 'Stromae'});

Submitting data via XML POST

Submitting data via XML POST may be done using personal MusicBrainz credentials.

Submit ISRC code using XML POST

Using the XML ISRC submission API.

const mbid_Formidable = '16afa384-174e-435e-bfa3-5591accda31c';
const isrc_Formidable = 'BET671300161';

const xmlMetadata = new XmlMetadata();
const xmlRecording = xmlMetadata.pushRecording(mbid_Formidable);
xmlRecording.isrcList.pushIsrc(isrc_Formidable);
await mbApi.post('recording', xmlMetadata);

Submitting data via user form-data

For all of the following function you need to use a dedicated bot account.

Submitting ISRC via post user form-data

Use with caution, and only on a test server, it may clear existing metadata as side effect.
const mbid_Formidable = '16afa384-174e-435e-bfa3-5591accda31c';
const isrc_Formidable = 'BET671300161';

    
const recording = await mbApi.lookupRecording(mbid_Formidable);

// Authentication the http-session against MusicBrainz (as defined in config.baseUrl)
const succeed = await mbApi.login();
assert.isTrue(succeed, 'Login successful');

// To submit the ISRC, the `recording.id` and `recording.title` are required
await mbApi.addIsrc(recording, isrc_Formidable);

Submit recording URL

const recording = await mbApi.lookupRecording('16afa384-174e-435e-bfa3-5591accda31c');

const succeed = await mbApi.login();
assert.isTrue(succeed, 'Login successful');

await mbApi.addUrlToRecording(recording, {
  linkTypeId: LinkType.stream_for_free,
  text: 'https://open.spotify.com/track/2AMysGXOe0zzZJMtH3Nizb'
});

Actually a Spotify-track-ID can be submitted easier:

const recording = await mbApi.lookupRecording('16afa384-174e-435e-bfa3-5591accda31c');

const succeed = await mbApi.login();
assert.isTrue(succeed, 'Login successful');
await mbApi.addSpotifyIdToRecording(recording, '2AMysGXOe0zzZJMtH3Nizb');

Compatibility

The JavaScript in runtime is compliant with ECMAScript 2017 (ES8). Requires Node.js® version 6 or higher.

More Repositories

1

music-metadata

Stream and file based music metadata parser for node. Supporting a wide range of audio and tag formats.
TypeScript
892
star
2

music-metadata-browser

Browser version of music-metadata parser Supporting a wide range of audio and tag formats.
TypeScript
239
star
3

readable-web-to-node-stream

Converts a Web-API readable-stream into a Node readable-stream.
TypeScript
44
star
4

strtok3

Promise based streaming tokenizer
TypeScript
33
star
5

audio-tag-analyzer

Extracts metadata music metadata found in audio files
TypeScript
31
star
6

listFix

listFix() - Playlist Repair Done Right
Java
13
star
7

token-types

A primitive token library used to read from, and to write a node Buffer
TypeScript
11
star
8

music-metadata-react

React application to test integration with music-metadata-browser
JavaScript
11
star
9

tokenizer-s3

Amazon S3 tokenizer
TypeScript
8
star
10

tokenizer-http

Fetch HTTP streamed chunks using RFC-7233 range requests
TypeScript
8
star
11

peek-readable

A promise based asynchronous stream reader, which makes reading from a stream easy.
TypeScript
7
star
12

music-metadata-s3

Extension for music-metadata to retrieve metadata from files stored on AWS S3 cloud storage
JavaScript
5
star
13

tokenizer-range

Range-request tokenizer adapter
TypeScript
3
star
14

lizzy

Multimedia playlist parser, supporting a wide range of playlist file formats.
Java
3
star
15

tokenizer-token

TypeScript definition for strtok3 token
2
star
16

gazelle-client

Gazelle API client
TypeScript
2
star
17

musicbrainz-augmentation

MusicBrainz metadata augmentation using Spotify metadata
TypeScript
1
star
18

t-readable

Split a readable-stream into 2 or more readable-streams
TypeScript
1
star
19

ogg-radio-stream

Test to listen to an infinite Ogg stream
JavaScript
1
star
20

file-type-example

file-type examples
TypeScript
1
star