Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

node-id3

Package Overview
Dependencies
Maintainers
1
Versions
38
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

node-id3 - npm Package Compare versions

Comparing version 0.1.16 to 0.1.17

51

index.d.ts

@@ -286,3 +286,52 @@ declare module "node-id3" {

data: string
}]
}],
chapter?: Array<{
elementID: string,
endTimeMs: number,
startTimeMs: number,
tags?: {
image?: Tags["image"],
title?: string,
},
}>,
/**
* The 'Commercial information' frame is a URL pointing at a webpage with information such as where the album can be bought. There may be more than one "WCOM" frame in a tag, but not with the same content.
*/
commercialUrl?: Array<string>,
/**
* The 'Copyright/Legal information' frame is a URL pointing at a webpage where the terms of use and ownership of the file is described.
*/
copyrightUrl?: string,
/**
* The 'Official audio file webpage' frame is a URL pointing at a file specific webpage.
*/
fileUrl?: string,
/**
* The 'Official artist/performer webpage' frame is a URL pointing at the artists official webpage. There may be more than one "WOAR" frame in a tag if the audio contains more than one performer, but not with the same content.
*/
artistUrl?: Array<string>,
/**
* The 'Official audio source webpage' frame is a URL pointing at the official webpage for the source of the audio file, e.g. a movie.
*/
audioSourceUrl?: string,
/**
* The 'Official internet radio station homepage' contains a URL pointing at the homepage of the internet radio station.
*/
radioStationUrl?: string,
/**
* The 'Payment' frame is a URL pointing at a webpage that will handle the process of paying for this file.
*/
paymentUrl?: string,
/**
* The 'Publishers official webpage' frame is a URL pointing at the official wepage for the publisher.
*/
publisherUrl?: string,
/**
* The 'User-defined URL link' frame is intended for URL links concerning the audiofile in a similar way to the other "W"-frames. There may be more than one "WXXX" frame in each tag, but only one with the same description.
*/
userDefinedUrl?: Array<{
description: string,
url: string
}>
}

@@ -289,0 +338,0 @@ export function write(tags: Tags, filebuffer: Buffer): Buffer

@@ -139,2 +139,9 @@ const fs = require('fs')

multiple: true
},
userDefinedUrl: {
create: "createUserDefinedUrl",
read: "readUserDefinedUrl",
name: "WXXX",
multiple: true,
updateCompareKey: "description"
}

@@ -152,2 +159,74 @@ }

/*
** List of URL frames.
** name => Frame ID
** multiple => Whether multiple of this frame can exist
** hasDescription => Whether this frame may include a description
*/
const WFrames = {
commercialUrl: {
name: "WCOM",
multiple: true
},
copyrightUrl: {
name: "WCOP"
},
fileUrl: {
name: "WOAF"
},
artistUrl: {
name: "WOAR",
multiple: true
},
audioSourceUrl: {
name: "WOAS"
},
radioStationUrl: {
name: "WORS"
},
paymentUrl: {
name: "WPAY"
},
publisherUrl: {
name: "WPUB"
}
}
/*
4.3.1 WAF Official audio file webpage
4.3.1 WAR Official artist/performer webpage
4.3.1 WAS Official audio source webpage
4.3.1 WCM Commercial information
4.3.1 WCP Copyright/Legal information
4.3.1 WPB Publishers official webpage
4.3.2 WXX User defined URL link frame
*/
const WFrames220 = {
commercialUrl: {
name: "WCM",
multiple: true
},
copyrightUrl: {
name: "WCP"
},
fileUrl: {
name: "WAF"
},
artistUrl: {
name: "WAR",
multiple: true
},
audioSourceUrl: {
name: "WAS"
},
publisherUrl: {
name: "WPB"
},
userDefinedUrl: {
name: "WXX",
multiple: true,
hasDescription: true
}
}
/*
** Officially available types of the picture frame

@@ -273,2 +352,14 @@ */

frame = this.createTextFrame(specName, tags[tag])
} else if (WFrames[tag] || Object.keys(WFrames).map(i => WFrames[i]).map(x => x.name).indexOf(tag) !== -1) {
let specName = WFrames[tag] ? WFrames[tag].name : tag
let multiple = WFrames[Object.keys(WFrames)[Object.keys(WFrames).map(i => WFrames[i]).map(x => x.name).indexOf(specName)]].multiple
if(multiple && tags[tag] instanceof Array && tags[tag].length > 0) {
frame = Buffer.alloc(0);
// deduplicate array
for(var url of [...new Set(tags[tag])]) {
frame = Buffer.concat([frame, this.createUrlFrame(specName, url)])
}
} else {
frame = this.createUrlFrame(specName, tags[tag])
}
} else if (SFrames[tag]) { // Check if Alias of special frame

@@ -339,2 +430,6 @@ let createFrameFunction = SFrames[tag].create

// if js name passed (WF)
} else if(WFrames[tagKey]) {
rawTags[WFrames[tagKey].name] = tags[tagKey]
// if js name passed (SF)

@@ -348,2 +443,6 @@ } else if(SFrames[tagKey]) {

// if raw name passed (WF)
} else if(Object.keys(WFrames).map(i => WFrames[i]).map(x => x.name).indexOf(tagKey) !== -1) {
rawTags[tagKey] = tags[tagKey]
// if raw name passed (SF)

@@ -360,3 +459,3 @@ } else if(Object.keys(SFrames).map(i => SFrames[i]).map(x => x.name).indexOf(tagKey) !== -1) {

if(SFrames[SRawToNameMap[tag]] && SFrames[SRawToNameMap[tag]].multiple && currentTags[tag] && rawTags[tag]) {
cCompare = {}
const cCompare = {}
currentTags[tag].forEach((cTag, index) => {

@@ -389,3 +488,3 @@ cCompare[cTag[SFrames[SRawToNameMap[tag]].updateCompareKey]] = index

if(SFrames[SRawToNameMap[tag]] && SFrames[SRawToNameMap[tag]].multiple && currentTags[tag] && rawTags[tag]) {
cCompare = {}
const cCompare = {}
currentTags[tag].forEach((cTag, index) => {

@@ -493,2 +592,22 @@ cCompare[cTag[SFrames[SRawToNameMap[tag]].updateCompareKey]] = index

})
} else if (frame.name[0] === "W" && frame.name !== "WXXX") {
let versionFrames = WFrames
if(ID3Version == 2) {
versionFrames = WFramesV220
}
Object.keys(versionFrames).map(function(key) {
if(versionFrames[key].name === frame.name) {
// URL fields contain no encoding byte and are always ISO-8859-1 as per spec
let decoded = iconv.decode(frame.body, "ISO-8859-1").replace(/\0/g, "")
if(versionFrames[key].multiple) {
if(!tags[key]) tags[key] = []
if(!tags.raw[frame.name]) tags.raw[frame.name] = []
tags.raw[frame.name].push(decoded)
tags[key].push(decoded)
} else {
tags.raw[frame.name] = decoded
tags[key] = decoded
}
}
})
} else {

@@ -690,2 +809,25 @@ let versionFrames = SFrames

/*
** Create URL frame
** specName => string (ID)
** text => string (body)
*/
NodeID3.prototype.createUrlFrame = function(specName, text) {
if(!specName || !text) {
return null
}
let encoded = iconv.encode(text, "ISO-8859-1")
let buffer = Buffer.alloc(10)
buffer.fill(0)
buffer.write(specName, 0) // ID of the specified frame
buffer.writeUInt32BE((encoded).length + 1, 4) // Size of frame (string length + encoding byte)
let encBuffer = Buffer.alloc(1) // Encoding (URLs are always ISO-8859-1)
encBuffer.fill(0) // ISO-8859-1
var contentBuffer = Buffer.from(encoded, 'binary') // Text -> Binary encoding for ISO-8859-1
return Buffer.concat([buffer, encBuffer, contentBuffer])
}
/*
** data => string || buffer

@@ -994,3 +1136,3 @@ */

NodeID3.prototype.createUserDefinedText = function(userDefinedText, recursiveBuffer) {
udt = userDefinedText || {}
let udt = userDefinedText || {}
if(udt instanceof Array && udt.length > 0) {

@@ -1192,12 +1334,12 @@ if(!recursiveBuffer) {

/*
** chapter => object|array {
** startTimeMs: number,
** endTimeMs: number,
** startOffsetBytes: number,
** endOffsetBytes: number,
** tags: object
** }
**/
NodeID3.prototype.createChapterFrame = function(chapter) {
/**
* @typedef {Object} Chapter
* @property {string} elementID
* @property {number} startTimeMs
* @property {number} endTimeMs
* @property {number} [startOffsetBytes]
* @property {number} [endOffsetBytes]
* @property {object} [tags]
*/
NodeID3.prototype.createChapterFrame = function (/** @type Chapter[] | Chapter */chapter) {
if(chapter instanceof Array && chapter.length > 0) {

@@ -1218,3 +1360,3 @@ let frames = []

NodeID3.prototype.createChapterFrameHelper = function(chapter, id) {
if(!chapter || !chapter.elementID || !chapter.startTimeMs || !chapter.endTimeMs) {
if(!chapter || !chapter.elementID || typeof chapter.startTimeMs === "undefined" || !chapter.endTimeMs) {
return null

@@ -1228,12 +1370,12 @@ }

let startTimeBuffer = Buffer.alloc(4)
startTimeBuffer.writeUInt32BE(chapter.startTimeMs)
startTimeBuffer.writeUInt32BE(chapter.startTimeMs, 0)
let endTimeBuffer = Buffer.alloc(4)
endTimeBuffer.writeUInt32BE(chapter.endTimeMs)
endTimeBuffer.writeUInt32BE(chapter.endTimeMs, 0)
let startOffsetBytesBuffer = Buffer.alloc(4, 0xFF)
if(chapter.startOffsetBytes) {
startOffsetBytesBuffer.writeUInt32BE(chapter.startOffsetBytes)
startOffsetBytesBuffer.writeUInt32BE(chapter.startOffsetBytes, 0)
}
let endOffsetBytesBuffer = Buffer.alloc(4, 0xFF)
if(chapter.endOffsetBytes) {
endOffsetBytesBuffer.writeUInt32BE(chapter.endOffsetBytes)
endOffsetBytesBuffer.writeUInt32BE(chapter.endOffsetBytes, 0)
}

@@ -1245,3 +1387,3 @@

}
framesBuffer = frames ? Buffer.concat(frames) : Buffer.alloc(0)
const framesBuffer = frames ? Buffer.concat(frames) : Buffer.alloc(0)

@@ -1270,6 +1412,6 @@ header.writeUInt32BE(elementIDBuffer.length + 16 + framesBuffer.length, 4)

tags.endTimeMs = frame.readUInt32BE(endOfElementIDString + 5)
if(frame.readUInt32BE(endOfElementIDString + 9) != Buffer.alloc(4, 0xff).readUInt32BE()) {
if(frame.readUInt32BE(endOfElementIDString + 9) != Buffer.alloc(4, 0xff).readUInt32BE(0)) {
tags.startOffsetBytes = frame.readUInt32BE(endOfElementIDString + 9)
}
if(frame.readUInt32BE(endOfElementIDString + 13) != Buffer.alloc(4, 0xff).readUInt32BE()) {
if(frame.readUInt32BE(endOfElementIDString + 13) != Buffer.alloc(4, 0xff).readUInt32BE(0)) {
tags.endOffsetBytes = frame.readUInt32BE(endOfElementIDString + 13)

@@ -1284,2 +1426,67 @@ }

return tags
}
NodeID3.prototype.createUserDefinedUrl = function(userDefinedUrl, recursiveBuffer) {
let udu = userDefinedUrl || {}
if(udu instanceof Array && udu.length > 0) {
if(!recursiveBuffer) {
// Don't alter passed array value!
userDefinedUrl = userDefinedUrl.slice(0)
}
udu = userDefinedUrl.pop()
}
if(udu && udu.description) {
// Create frame header
let buffer = Buffer.alloc(10)
buffer.fill(0)
buffer.write("WXXX", 0) // Write header ID
let encodingBuffer = this.createTextEncoding(0x01)
let descriptorBuffer = this.createContentDescriptor(udu.description, 0x01, true)
let urlBuffer = this.createText(udu.url, 0x00, false)
buffer.writeUInt32BE(encodingBuffer.length + descriptorBuffer.length + urlBuffer.length, 4)
if(!recursiveBuffer) {
recursiveBuffer = Buffer.concat([buffer, encodingBuffer, descriptorBuffer, urlBuffer])
} else {
recursiveBuffer = Buffer.concat([recursiveBuffer, buffer, encodingBuffer, descriptorBuffer, urlBuffer])
}
}
if(userDefinedUrl instanceof Array && userDefinedUrl.length > 0) {
return this.createUserDefinedUrl(userDefinedUrl, recursiveBuffer)
} else {
return recursiveBuffer
}
}
NodeID3.prototype.readUserDefinedUrl = function(frame) {
let tags = {}
if(!frame) {
return tags
}
if(frame[0] == 0x00) {
tags = {
description: iconv.decode(frame, "ISO-8859-1").substring(1, frame.indexOf(0x00, 1)).replace(/\0/g, ""),
url: iconv.decode(frame, "ISO-8859-1").substring(frame.indexOf(0x00, 1) + 1).replace(/\0/g, "")
}
} else if(frame[0] == 0x01) {
let descriptorEscape = 0
while(frame[descriptorEscape] !== undefined && frame[descriptorEscape] !== 0x00 || frame[descriptorEscape + 1] !== 0x00 || frame[descriptorEscape + 2] === 0x00) {
descriptorEscape++
}
if(frame[descriptorEscape] === undefined) {
return tags
}
let description = frame.slice(1, descriptorEscape)
let value = frame.slice(descriptorEscape + 2)
tags = {
description: iconv.decode(description, "utf16").replace(/\0/g, ""),
url: iconv.decode(value, "ISO-8859-1").replace(/\0/g, "")
}
}
return tags
}

4

package.json
{
"name": "node-id3",
"version": "0.1.16",
"version": "0.1.17",
"description": "Pure JavaScript ID3 Tag writer/reader",

@@ -35,4 +35,4 @@ "author": "Jan Metzger <jan.metzger@gmx.net>",

"dependencies": {
"iconv-lite": "^0.4.15"
"iconv-lite": "0.5.1"
}
}

@@ -174,2 +174,14 @@ # node-id3

}]
commercialUrl: ["commercialurl.com"], // array or single string
copyrightUrl: "example.com",
fileUrl: "example.com",
artistUrl: ["example.com"], // array or single string
audioSourceUrl: "example.com",
radioStationUrl: "example.com",
paymentUrl: "example.com",
publisherUrl: "example.com",
userDefinedUrl: [{
description: "URL description"
url: "https://example.com/"
}] // array or single object
```

@@ -225,2 +237,11 @@

chapter "CHAP"
commercialUrl "WCOM"
copyrightUrl "WCOP"
fileUrl "WOAF"
artistUrl "WOAR"
audioSourceUrl "WOAS"
radioStationUrl "WORS"
paymentUrl "WPAY"
publisherUrl "WPUB"
userDefinedUrl "WXXX"
```
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc