All Projects → aadsm → Jsmediatags

aadsm / Jsmediatags

Licence: other
Media Tags Reader (ID3, MP4, FLAC)

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to Jsmediatags

Atldotnet
Fully managed, portable and easy-to-use C# library to read and edit audio data and metadata (tags) from various audio formats, playlists and CUE sheets
Stars: ✭ 180 (-65.52%)
Mutual labels:  reader, mp3, flac
audio-metadata
A library for reading and, in the future, writing audio metadata. https://audio-metadata.readthedocs.io/
Stars: ✭ 41 (-92.15%)
Mutual labels:  mp3, flac
audio-tag-analyzer
Extracts metadata music metadata found in audio files
Stars: ✭ 18 (-96.55%)
Mutual labels:  mp3, flac
java-stream-player
🌌Java Advanced Audio Controller Library (WAV, AU, AIFF, MP3, OGG VORBIS, FLAC, MONKEY's AUDIO and SPEEX audio formats )
Stars: ✭ 112 (-78.54%)
Mutual labels:  mp3, flac
aplay-
a simple BitPerfect player
Stars: ✭ 23 (-95.59%)
Mutual labels:  mp3, flac
acxi
acxi is an audio conversion tool that helps sync lossless to lossy formats.
Stars: ✭ 35 (-93.3%)
Mutual labels:  mp3, flac
record-encode-audio-from-browser
Record/Encode Audio on Browser using the WebAudio API and "ported" libraries.
Stars: ✭ 55 (-89.46%)
Mutual labels:  mp3, flac
sox-stream
📣 A stream-friendly wrapper around SoX
Stars: ✭ 50 (-90.42%)
Mutual labels:  mp3, flac
slibs
Single file libraries for C/C++
Stars: ✭ 80 (-84.67%)
Mutual labels:  mp3, flac
flutter audio desktop
[WIP] An 🎵 audio playback library for Flutter Desktop. Supports Windows & Linux. Based on miniaudio.
Stars: ✭ 42 (-91.95%)
Mutual labels:  mp3, flac
Libnyquist
🎤 Cross platform C++11 library for decoding audio (mp3, wav, ogg, opus, flac, etc)
Stars: ✭ 311 (-40.42%)
Mutual labels:  mp3, flac
sox.js
📢 NodeJS wrapper for the SoX audio tool
Stars: ✭ 18 (-96.55%)
Mutual labels:  mp3, flac
genshin-audio-exporter
Export audio files from Genshin Impact game data into different audio formats.
Stars: ✭ 83 (-84.1%)
Mutual labels:  mp3, flac
loudgain
ReplayGain 2.0 loudness normalizer based on the EBU R128/ITU BS.1770 standard (-18 LUFS, FLAC, Ogg, MP2, MP3, MP4, M4A, AAC, ALAC, Opus, ASF, WMA, WAV, AIFF, WavPack, APE)
Stars: ✭ 127 (-75.67%)
Mutual labels:  mp3, flac
uos
United Open-libraries of Sound. United procedures for open-source audio libraries. For FPC/Lazarus/fpGUI/MSEgui.
Stars: ✭ 112 (-78.54%)
Mutual labels:  mp3, flac
discogstagger
Console based audio-file metadata tagger that uses the Discogs.com API v2 (JSON based). Relies on the Mutagen and discogs-client libraries. Currently supports FLAC and MP3 file types.
Stars: ✭ 65 (-87.55%)
Mutual labels:  mp3, flac
Music Metadata
Stream and file based music metadata parser for node. Supporting a wide range of audio and tag formats.
Stars: ✭ 455 (-12.84%)
Mutual labels:  mp3, flac
Youtube-DL-GUI
Graphical User Interace built around youtube-dl CLI
Stars: ✭ 38 (-92.72%)
Mutual labels:  mp3, flac
libwinmedia
[Archived] A cross-platform simple media playback library for C/C++.
Stars: ✭ 35 (-93.3%)
Mutual labels:  mp3, flac
Tag
ID3, MP4 and OGG/FLAC metadata parsing in Go
Stars: ✭ 314 (-39.85%)
Mutual labels:  mp3, flac

JS MediaTags

The next version of https://github.com/aadsm/JavaScript-ID3-Reader.

Donations

A few people have asked me about donations (or even crowdfunding). I would prefer you to consider making a donation to the "Girls Who Code" NPO. If you do please send me a message so I can add you as a contributor.

Contributors

Contributing

Current Support

  • File Readers
    • NodeJS
    • XMLHttpRequest
    • Blob
    • File
    • Buffers/Arrays
    • React Native
  • Tag Readers
    • ID3v1
    • ID3v2 (with unsynchronisation support!)
    • MP4
    • FLAC

How to use

NodeJS

Run npm install jsmediatags --save to install.

// Simple API - will fetch all tags
var jsmediatags = require("jsmediatags");

jsmediatags.read("./music-file.mp3", {
  onSuccess: function(tag) {
    console.log(tag);
  },
  onError: function(error) {
    console.log(':(', error.type, error.info);
  }
});
// Advanced API
var jsmediatags = require("jsmediatags");

new jsmediatags.Reader("http://www.example.com/music-file.mp3")
  .setTagsToRead(["title", "artist"])
  .read({
    onSuccess: function(tag) {
      console.log(tag);
    },
    onError: function(error) {
      console.log(':(', error.type, error.info);
    }
  });

Browser

Copy the dist/jsmediatags.min.js file into your web application directory and include it with a script tag. This library is also available on cdnjs at https://cdnjs.com/libraries/jsmediatags. UMD will give you multiple usage options to use it:

// As a global Object
var jsmediatags = window.jsmediatags;
// As a CommonJS Module
var jsmediatags = require("jsmediatags");

It supports loading files from remote hosts, Blob and File objects:

// From remote host
jsmediatags.read("http://www.example.com/music-file.mp3", {
  onSuccess: function(tag) {
    console.log(tag);
  },
  onError: function(error) {
    console.log(error);
  }
});

Note that the URI has to include the scheme (e.g.: https://), as relative URIs are not supported.

// From Blob
jsmediatags.read(blob, ...);
// From File
inputTypeFile.addEventListener("change", function(event) {
  var file = event.target.files[0];
  jsmediatags.read(file, ...);
}, false);

You can find more about UMD usage options here.

React Native

React Native support requires some additional dependencies:

npm install --save jsmediatags buffer react-native-fs

With these dependencies installed, usage with React Native should remain the same:

const jsmediatags = require('jsmediatags');

new jsmediatags.Reader('/path/to/song.mp3')
  .read({
    onSuccess: (tag) => {
      console.log('Success!');
      console.log(tag);
    },
    onError: (error) => {
      console.log('Error');
      console.log(error);
    }
});

// Or wrap it with a promise
new Promise((resolve, reject) => {
  new jsmediatags.Reader('/path/to/song.mp3')
    .read({
      onSuccess: (tag) => {
        console.log('Success!');
        resolve(tag);
      },
      onError: (error) => {
        console.log('Error');
        reject(error);
      }
  });
})
  .then(tagInfo => {
    // handle the onSuccess return
  })
  .catch(error => {
    // handle errors
  });

Articles

Documentation

The Output

This is an example of the object passed to the jsmediatags.read's onSuccess callback.

ID3v2

{
  type: "ID3",
  version: "2.4.0",
  major: 4,
  revision: 0,
  tags: {
    artist: "Sam, The Kid",
    album: "Pratica(mente)",
    track: "12",
    TPE1: {
      id: "TPE1",
      size: 14,
      description: "Lead performer(s)/Soloist(s)",
      data: "Sam, The Kid"
    },
    TALB: {
      id: "TALB",
      size: 16,
      description: "Album/Movie/Show title",
      data: "Pratica(mente)"
    },
    TRCK: {
      id: "TRCK",
      size: 3,
      description: "Track number/Position in set",
      data: "12",
    }
  },
  size: 34423,
  flags: {
    unsynchronisation: false,
    extended_header: false,
    experimental_indicator: false,
    footer_present: false
  }
}

MP4

{
  type: "MP4",
  ftyp: "M4A",
  version: 0,
  tags: {
    "©too": {
      id: "©too",
      size: 35,
      description: 'Encoding Tool',
      data: 'Lavf53.24.2'
    }
  }
}

FLAC

{
  type: "FLAC",
  version: "1",
  tags: {
    title: "16/12/95",
    artist: "Sam, The Kid",
    album: "Pratica(mente)",
    track: "12",
    picture: ...
  }
}

The tags property includes all tags that were found or specified to be read. Since each tag type (e.g.: ID3, MP4) uses different tag names for the same type of data (e.g.: the artist name) the most common tags are also available under human readable names (aka shortcuts). In this example, artist will point to TPE1.data, album to TALB.data and so forth.

The expected tag object depends on the type of tag read (ID3, MP4, etc.) but they all share a common structure:

{
  type: <the tag type: ID3, MP4, etc.>
  tags: {
    <shortcut name>: <points to a tags data>
    <tag name>: {
      id: <tag name>,
      data: <the actual tag data>
    }
  }
}

Shortcuts

These are the supported shortcuts.

  • title
  • artist
  • album
  • year
  • comment
  • track
  • genre
  • picture
  • lyrics

Picture data

The picture tag contains an array buffer of all the bytes of the album artwork image as well as the content type of the image. The data can be converted and displayed as an image using:

const { data, format } = result.tags.picture;
let base64String = "";
for (const i = 0; i < data.length; i++) {
  base64String += String.fromCharCode(data[i]);
}
img.src = `data:${format};base64,${base64String}`;

HTTP Access Control (CORS)

When using HTTP CORS requests you need to make sure that the server is configured to receive If-Modified-Since and Range headers with the request. This can be configured by returning the Access-Control-Allow-Headers HTTP header with the OPTIONS request response.

Similarly, you should also allow for the browser to read the Content-Length and Content-Range headers. This can be configured by returning the Access-Control-Expose-Headers HTTP header.

In short, the following headers are expected:

Access-Control-Allow-Headers: If-Modified-Since, Range
Access-Control-Expose-Headers: Content-Length, Content-Range

This library still works without these options configured on the server. However it will download the entire file instead of only the necessary bytes for reading the tags.

File and Tag Readers

This library uses file readers (MediaFileReader API) to read the file itself and media tag readers (MediaTagReader API) to parse the tags in the file.

By default the library will automatically pick the most appropriate file reader depending on the file location. In the common case this will be the URL or local path where the file is located.

A similar approach is taken for the tag reader. The most appropriate tag reader will be selected depending on the tag signature found in the file.

However, you can specify exactly which file reader or tag reader to use using the advanced API.

New file and tag readers can be implemented by extending the MediaFileReader and MediaTagReader classes. Check the Development section down bellow for more information.

Reference

  • jsmediatags.Reader

    • setTagsToRead(tags: Array<string>) - Specify which tags to read
    • setFileReader(fileReader: typeof MediaFileReader) - Use this particular file reader
    • setTagReader(tagReader: typeof MediaTagReader) - Use this particular tag reader
    • read({onSuccess, onError}) - Read the tags.
  • jsmediatags.Config

    • addFileReader(fileReader: typeof MediaFileReader) - Add a new file reader to the automatic detection system.
    • addTagReader(tagReader: typeof MediaTagReader) - Add a new tag reader to the automatic detection system.
    • setDisallowedXhrHeaders(disallowedXhrHeaders: Array<string>) - Prevent the library from using specific http headers. This can be useful when dealing with CORS enabled servers you don't control.
    • setXhrTimeoutInSec(timeoutInSec: number) - Sets the timeout time for http requests. Set it to 0 for no timeout at all. It defaults to 30s.

Development

Source code uses Flow for type checking meaning that a compilation step is needed to remove all type annotations. When using this library with NodeJS you can use the runtime compilation that is supported by babel. It will be slightly slower but no compilation step is required.

NodeJS (With Runtime Compilation)

require('babel-core/register');

var NodeFileReader = require('./src/NodeFileReader');
var ID3v2TagReader = require('./src/ID3v2TagReader');
...

NodeJS (With Compiled Code (faster))

Run npm run build to generate proper JavaScript code into the build2 directory.

var NodeFileReader = require('./build2/NodeFileReader');
var ID3v2TagReader = require('./build2/ID3v2TagReader');
...

Run npm run watch to automatically recompile the source code whenever a file is changed.

Browser

Run npm run dist to generate a UMD version of this library that is ready to be used in a browser.

Two packages are created for the browser: dist/jsmediatags.min.js and dist/jsmediatags.js. One is a minimized version that is meant to be used in production and the other a regular version meant to be used for debugging.

Run npm run dist-watch to recompile and browserify the source code whenever a file is changed. This will only regenerate the dist/jsmediatags.js file.

New File Readers

Extend the MediaFileReader class to implement a new file reader. Methods to implement are:

  • init
  • loadRange
  • getBytesLoaded
  • getByteAt

Current Implementations:

New Tag Readers

Extend the MediaTagReader class to implement a new tag reader. Methods to implement are:

  • getTagIdentifierByteRange
  • canReadTagFormat
  • _loadData
  • _parseData

Current Implementations:

Unit Testing

Jest is the framework used. Run npm test to execute all the tests.

JavaScript-ID3-Reader

If you want to migrate your project from JavaScript-ID3-Reader to jsmediatags use the following guiding examples:

All tags

JavaScript-ID3-Reader:

ID3.loadTags("filename.mp3", function() {
  var tags = ID3.getAllTags("filename.mp3");
  alert(tags.artist + " - " + tags.title + ", " + tags.album);
});

jsmediatags:

jsmediatags.read("filename.mp3", {
  onSuccess: function(tag) {
    var tags = tag.tags;
    alert(tags.artist + " - " + tags.title + ", " + tags.album);
  }
});

Specific tags

JavaScript-ID3-Reader:

ID3.loadTags("filename.mp3", function() {
  var tags = ID3.getAllTags("filename.mp3");
  alert(tags.COMM.data + " - " + tags.TCON.data + ", " + tags.WXXX.data);
},
{tags: ["COMM", "TCON", "WXXX"]});

jsmediatags:

new jsmediatags.Reader("filename.mp3")
  .setTagsToRead(["COMM", "TCON", "WXXX"])
  .read({
    onSuccess: function(tag) {
      var tags = tag.tags;
      alert(tags.COMM.data + " - " + tags.TCON.data + ", " + tags.WXXX.data);
    }
  });

Error handling

JavaScript-ID3-Reader:

ID3.loadTags("http://localhost/filename.mp3", function() {
  var tags = ID3.getAllTags("http://localhost/filename.mp3");
  alert(tags.comment + " - " + tags.track + ", " + tags.lyrics);
},
{
  tags: ["comment", "track", "lyrics"],
  onError: function(reason) {
    if (reason.error === "xhr") {
      console.log("There was a network error: ", reason.xhr);
    }
  }
});

jsmediatags:

new jsmediatags.Reader("filename.mp3")
  .setTagsToRead(["comment", "track", "lyrics"])
  .read({
    onSuccess: function(tag) {
      var tags = tag.tags;
      alert(tags.comment + " - " + tags.track + ", " + tags.lyrics);
    },
    onError: function(error) {
      if (error.type === "xhr") {
        console.log("There was a network error: ", error.xhr);
      }
    }
  });

Goals

  • Improve the API of JavaScript-ID3-Reader
  • Improve the source code with readable code and Flow annotated types
  • Have unit tests
  • Support NodeJS
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].