Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
@bhunter179/jsmediatags
Advanced tools
The next version of https://github.com/aadsm/JavaScript-ID3-Reader.
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.
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);
}
});
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 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
});
This is an example of the object passed to the jsmediatags.read
's onSuccess
callback.
{
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
}
}
{
type: "MP4",
ftyp: "M4A",
version: 0,
tags: {
"©too": {
id: "©too",
size: 35,
description: 'Encoding Tool',
data: 'Lavf53.24.2'
}
}
}
{
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>
}
}
}
These are the supported shortcuts.
title
artist
album
year
comment
track
genre
picture
lyrics
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:${data.format};base64,${window.btoa(base64String)}`;
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.
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.
jsmediatags.Reader
setTagsToRead(tags: Array<string>)
- Specify which tags to readsetFileReader(fileReader: typeof MediaFileReader)
- Use this particular file readersetTagReader(tagReader: typeof MediaTagReader)
- Use this particular tag readerread({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.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.
require('babel-core/register');
var NodeFileReader = require('./src/NodeFileReader');
var ID3v2TagReader = require('./src/ID3v2TagReader');
...
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.
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.
Extend the MediaFileReader
class to implement a new file reader. Methods to implement are:
Current Implementations:
Extend the MediaTagReader
class to implement a new tag reader. Methods to implement are:
Current Implementations:
Jest is the framework used. Run npm test
to execute all the tests.
If you want to migrate your project from JavaScript-ID3-Reader to jsmediatags
use the following guiding examples:
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);
}
});
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);
}
});
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);
}
}
});
FAQs
Media Tags Reader (ID3, MP4)
The npm package @bhunter179/jsmediatags receives a total of 0 weekly downloads. As such, @bhunter179/jsmediatags popularity was classified as not popular.
We found that @bhunter179/jsmediatags demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.