Add libs and update package.json & version for release v1.9.0

This commit is contained in:
SMLoardrDev 2018-04-10 19:09:26 +02:00
parent bd4935544d
commit f0c4811f16
18 changed files with 1372 additions and 174 deletions

View File

@ -1 +1 @@
1.8.0
1.9.0

View File

@ -0,0 +1,306 @@
# Browser ID3 Writer
[![npm package][npm-badge]][npm] [![Travis][build-badge]][build]
[build-badge]: https://img.shields.io/travis/egoroof/browser-id3-writer/master.svg?style=flat-square
[build]: https://travis-ci.org/egoroof/browser-id3-writer
[npm-badge]: https://img.shields.io/npm/v/browser-id3-writer.svg?style=flat-square
[npm]: https://www.npmjs.org/package/browser-id3-writer
Pure JS library for writing [ID3 (v2.3)](http://id3.org/id3v2.3.0) tag to MP3 files in browsers and Node.js.
It can't read the tag so use another lib to do it.
**Note**: the library removes existing ID3 tag (v2.2, v2.3 and v2.4).
Works in Node.js 4+, IE10+ and all modern browsers.
Here is an online demonstration: [egoroof.ru/browser-id3-writer/](https://egoroof.ru/browser-id3-writer/)
## Table of Contents
- [Installation](#installation)
- [Usage](#usage)
- [Browser](#browser)
1. [Get ArrayBuffer of song](#get-arraybuffer-of-song)
2. [Add a tag](#add-a-tag)
3. [Save file](#save-file)
4. [Memory control](#memory-control)
- [Node.js](#nodejs)
- [Supported frames](#supported-frames)
- [APIC picture types](#apic-picture-types)
## Installation
Take latest version [here](https://unpkg.com/browser-id3-writer) or with npm:
```
npm install browser-id3-writer --save
```
## Usage
### Browser
#### Get ArrayBuffer of song
In browsers you should first get
[ArrayBuffer](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer)
of the song you would like to add ID3 tag.
##### FileReader
For example you can create file input and use
[FileReader](https://developer.mozilla.org/en/docs/Web/API/FileReader):
```html
<input type="file" id="file" accept="audio/mpeg">
<script>
document.getElementById('file').addEventListener('change', function () {
if (this.files.length === 0) {
return;
}
const reader = new FileReader();
reader.onload = function () {
const arrayBuffer = reader.result;
// go next
};
reader.onerror = function () {
// handle error
console.error('Reader error', reader.error);
};
reader.readAsArrayBuffer(this.files[0]);
});
</script>
```
##### XMLHttpRequest
To get arrayBuffer from remote server you can use
[XMLHttpRequest](https://developer.mozilla.org/en/docs/Web/API/XMLHttpRequest):
```js
const xhr = new XMLHttpRequest();
xhr.open('GET', urlToSongFile, true);
xhr.responseType = 'arraybuffer';
xhr.onload = function () {
if (xhr.status === 200) {
const arrayBuffer = xhr.response;
// go next
} else {
// handle error
console.error(xhr.statusText + ' (' + xhr.status + ')');
}
};
xhr.onerror = function() {
// handle error
console.error('Network error');
};
xhr.send();
```
#### Add a tag
Create new `ID3Writer` instance with arrayBuffer of your song, set frames and add a tag:
```js
// arrayBuffer of song or empty arrayBuffer if you just want only id3 tag without song
const writer = new ID3Writer(arrayBuffer);
writer.setFrame('TIT2', 'Home')
.setFrame('TPE1', ['Eminem', '50 Cent'])
.setFrame('TALB', 'Friday Night Lights')
.setFrame('TYER', 2004)
.setFrame('TRCK', '6/8')
.setFrame('TCON', ['Soundtrack'])
.setFrame('TBPM', 128)
.setFrame('WPAY', 'https://google.com')
.setFrame('TKEY', 'Fbm')
.setFrame('APIC', {
type: 3,
data: coverArrayBuffer,
description: 'Super picture'
});
writer.addTag();
```
#### Save file
Now you can save it to file as you want:
```js
const taggedSongBuffer = writer.arrayBuffer;
const blob = writer.getBlob();
const url = writer.getURL();
```
For example you can save file using [FileSaver.js](https://github.com/eligrey/FileSaver.js/):
```js
saveAs(blob, 'song with tags.mp3');
```
If you are writing chromium extension you can save file using
[Downloads API](https://developer.chrome.com/extensions/downloads):
```js
chrome.downloads.download({
url: url,
filename: 'song with tags.mp3'
});
```
#### Memory control
When you generate URLs via `writer.getURL()` you should know
that whole file is kept in memory until you close the page or move to another one.
So if you generate lots of URLs in a single page you should manually free memory
after you finish downloading file:
```js
URL.revokeObjectURL(url); // if you know url or
writer.revokeURL(); // if you have access to writer
```
### Node.js
Simple example with blocking IO:
```js
const ID3Writer = require('browser-id3-writer');
const fs = require('fs');
const songBuffer = fs.readFileSync('path_to_song.mp3');
const coverBuffer = fs.readFileSync('path_to_cover.jpg');
const writer = new ID3Writer(songBuffer);
writer.setFrame('TIT2', 'Home')
.setFrame('TPE1', ['Eminem', '50 Cent'])
.setFrame('TALB', 'Friday Night Lights')
.setFrame('TYER', 2004)
.setFrame('APIC', {
type: 3,
data: coverBuffer,
description: 'Super picture'
});
writer.addTag();
const taggedSongBuffer = Buffer.from(writer.arrayBuffer);
fs.writeFileSync('song_with_tags.mp3', taggedSongBuffer);
```
You can also create only ID3 tag without song and use it as you want:
```js
const writer = new ID3Writer(Buffer.alloc(0));
writer.padding = 0; // default 4096
writer.setFrame('TIT2', 'Home');
writer.addTag();
const id3Buffer = Buffer.from(writer.arrayBuffer);
```
## Supported frames
Have not found needed frame? Open a new issue and we'll discuss it.
**array of strings:**
- TPE1 (song artists)
- TCOM (song composers)
- TCON (song genres)
**string**
- TIT2 (song title)
- TALB (album title)
- TPE2 (album artist)
- TPE3 (conductor/performer refinement)
- TPE4 (interpreted, remixed, or otherwise modified by)
- TRCK (song number in album): '5' or '5/10'
- TPOS (album disc number): '1' or '1/3'
- TPUB (label name)
- TKEY (initial key)
- TMED (media type)
- WCOM (commercial information)
- WCOP (copyright/Legal information)
- WOAF (official audio file webpage)
- WOAR (official artist/performer webpage)
- WOAS (official audio source webpage)
- WORS (official internet radio station homepage)
- WPAY (payment)
- WPUB (publishers official webpage)
**integer**
- TLEN (song duration in milliseconds)
- TYER (album release year)
- TBPM (beats per minute)
**object**
- COMM (comments):
```js
writer.setFrame('COMM', {
description: 'description here',
text: 'text here'
});
```
- USLT (unsychronised lyrics):
```js
writer.setFrame('USLT', {
description: 'description here',
lyrics: 'lyrics here'
});
```
- TXXX (user defined text):
```js
writer.setFrame('TXXX', {
description: 'description here',
value: 'value here'
});
```
- APIC (attached picture):
```js
writer.setFrame('APIC', {
type: 3,
data: coverArrayBuffer,
description: 'description here',
useUnicodeEncoding: false
});
```
`useUnicodeEncoding` should only be `true` when description contains non-Western characters.
When it's set to `true` some program might not be able to read the picture correctly.
See [#42](https://github.com/egoroof/browser-id3-writer/issues/42).
## APIC picture types
| Type | Name |
|------|-------------------------------------|
| 0 | Other |
| 1 | 32x32 pixels 'file icon' (PNG only) |
| 2 | Other file icon |
| 3 | Cover (front) |
| 4 | Cover (back) |
| 5 | Leaflet page |
| 6 | Media (e.g. lable side of CD) |
| 7 | Lead artist/lead performer/soloist |
| 8 | Artist/performer |
| 9 | Conductor |
| 10 | Band/Orchestra |
| 11 | Composer |
| 12 | Lyricist/text writer |
| 13 | Recording Location |
| 14 | During recording |
| 15 | During performance |
| 16 | Movie/video screen capture |
| 17 | A bright coloured fish |
| 18 | Illustration |
| 19 | Band/artist logotype |
| 20 | Publisher/Studio logotype |

File diff suppressed because one or more lines are too long

1
libs/flac-metadata/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
.DS_Store

View File

@ -0,0 +1,143 @@
# flac-metadata
A FLAC metadata processor for Node.js, implemented as Transform stream.
## Installation
```npm install flac-metadata```
## Usage Examples
Some simple examples to get you started:
#### Noop
Does nothing, just pipes a source FLAC through the Processor into a target FLAC.
```js
var fs = require("fs");
var flac = require("flac-metadata");
var reader = fs.createReadStream("source.flac");
var writer = fs.createWriteStream("target.flac");
var processor = new flac.Processor();
reader.pipe(processor).pipe(writer);
```
#### Trace Metadata
Traces out the metadata from a FLAC file.
```js
var fs = require("fs");
var flac = require("flac-metadata");
var reader = fs.createReadStream("source.flac");
var processor = new flac.Processor({ parseMetaDataBlocks: true });
processor.on("postprocess", function(mdb) {
console.log(mdb.toString());
});
reader.pipe(processor);
```
The output should be something like this:
```
[MetaDataBlockStreamInfo] type: 0, isLast: false
minBlockSize: 4096
maxBlockSize: 4096
minFrameSize: 14
maxFrameSize: 12389
samples: 9750804
sampleRate: 44100
channels: 2
bitsPerSample: 16
duration: 3:41.107
checksum: 1746dff27beb6d1875a88cfeed8a576b
[MetaDataBlockVorbisComment] type: 4, isLast: false
vendor: reference libFLAC 1.2.1 20070917
comments:
ALBUM: Close to the Glass
ARTIST: The Notwist
GENRE: Rock
DATE: 2014
TITLE: Signals
[MetaDataBlockPicture] type: 6, isLast: true
pictureType: 3
mimeType: image/png
description:
width: 120
height: 120
bitsPerPixel: 32
colors: 0
pictureData: 391383
```
#### Strip All Metadata
Pipes a source FLAC through the Processor into a target FLAC, removing all metadata.
```js
var fs = require("fs");
var flac = require("flac-metadata");
var reader = fs.createReadStream("source.flac");
var writer = fs.createWriteStream("target.flac");
var processor = new flac.Processor();
processor.on("preprocess", function(mdb) {
// STREAMINFO is always the first (and only mandatory) metadata block.
if (mdb.type === flac.Processor.MDB_TYPE_STREAMINFO) {
// When a metadata block's isLast flag is set to true in preprocess,
// subsequent blocks are automatically discarded.
mdb.isLast = true;
}
});
reader.pipe(processor).pipe(writer);
```
#### Inject Metadata
Injects a VORBIS_COMMENT block (and removes the existing one, if any).
```js
var fs = require("fs");
var flac = require("flac-metadata");
var reader = fs.createReadStream("source.flac");
var writer = fs.createWriteStream("target.flac");
var processor = new flac.Processor();
var vendor = "reference libFLAC 1.2.1 20070917";
var comments = [
"ARTIST=Boyracer",
"TITLE=I've Got It And It's Not Worth Having",
"ALBUM=B Is For Boyracer",
"TRACKNUMBER=A1",
"DATE=1993",
"DISCOGS=22379"
];
processor.on("preprocess", function(mdb) {
// Remove existing VORBIS_COMMENT block, if any.
if (mdb.type === flac.Processor.MDB_TYPE_VORBIS_COMMENT) {
mdb.remove();
}
// Inject new VORBIS_COMMENT block.
if (mdb.removed || mdb.isLast) {
var mdbVorbis = flac.data.MetaDataBlockVorbisComment.create(mdb.isLast, vendor, comments);
this.push(mdbVorbis.publish());
}
});
reader.pipe(processor).pipe(writer);
```
## License
MIT

View File

@ -0,0 +1,8 @@
module.exports.Processor = require("./lib/Processor");
module.exports.data = {
MetaDataBlock: require("./lib/data/MetaDataBlock"),
MetaDataBlockStreamInfo: require("./lib/data/MetaDataBlockStreamInfo"),
MetaDataBlockVorbisComment: require("./lib/data/MetaDataBlockVorbisComment"),
MetaDataBlockPicture: require("./lib/data/MetaDataBlockPicture")
};

View File

@ -0,0 +1,218 @@
var util = require("util");
var stream = require('stream');
var Transform = stream.Transform || require('readable-stream').Transform;
var MetaDataBlock = require("./data/MetaDataBlock");
var MetaDataBlockStreamInfo = require("./data/MetaDataBlockStreamInfo");
var MetaDataBlockVorbisComment = require("./data/MetaDataBlockVorbisComment");
var MetaDataBlockPicture = require("./data/MetaDataBlockPicture");
const STATE_IDLE = 0;
const STATE_MARKER = 1;
const STATE_MDB_HEADER = 2;
const STATE_MDB = 3;
const STATE_PASS_THROUGH = 4;
var Processor = function (options) {
this.state = STATE_IDLE;
this.isFlac = false;
this.buf;
this.bufPos = 0;
this.mdb;
this.mdbLen = 0;
this.mdbLast = false;
this.mdbPush = false;
this.mdbLastWritten = false;
this.parseMetaDataBlocks = false;
if (!(this instanceof Processor)) return new Processor(options);
if (options && !!options.parseMetaDataBlocks) { this.parseMetaDataBlocks = true; }
Transform.call(this, options);
}
util.inherits(Processor, Transform);
// MDB types
Processor.MDB_TYPE_STREAMINFO = 0;
Processor.MDB_TYPE_PADDING = 1;
Processor.MDB_TYPE_APPLICATION = 2;
Processor.MDB_TYPE_SEEKTABLE = 3;
Processor.MDB_TYPE_VORBIS_COMMENT = 4;
Processor.MDB_TYPE_CUESHEET = 5;
Processor.MDB_TYPE_PICTURE = 6;
Processor.MDB_TYPE_INVALID = 127;
Processor.prototype._transform = function (chunk, enc, done) {
var chunkPos = 0;
var chunkLen = chunk.length;
var isChunkProcessed = false;
var _this = this;
function _safePush (minCapacity, persist, validate) {
var slice;
var chunkAvailable = chunkLen - chunkPos;
var isDone = (chunkAvailable + this.bufPos >= minCapacity);
validate = (typeof validate === "function") ? validate : function() { return true; };
if (isDone) {
// Enough data available
if (persist) {
// Persist the entire block so it can be parsed
if (this.bufPos > 0) {
// Part of this block's data is in backup buffer, copy rest over
chunk.copy(this.buf, this.bufPos, chunkPos, chunkPos + minCapacity - this.bufPos);
slice = this.buf.slice(0, minCapacity);
} else {
// Entire block fits in current chunk
slice = chunk.slice(chunkPos, chunkPos + minCapacity);
}
} else {
slice = chunk.slice(chunkPos, chunkPos + minCapacity - this.bufPos);
}
// Push block after validation
validate(slice, isDone) && _this.push(slice);
chunkPos += minCapacity - this.bufPos;
this.bufPos = 0;
this.buf = null;
} else {
// Not enough data available
if (persist) {
// Copy/append incomplete block to backup buffer
this.buf = this.buf || new Buffer(minCapacity);
chunk.copy(this.buf, this.bufPos, chunkPos, chunkLen);
} else {
// Push incomplete block after validation
slice = chunk.slice(chunkPos, chunkLen);
validate(slice, isDone) && _this.push(slice);
}
this.bufPos += chunkLen - chunkPos;
}
return isDone;
};
var safePush = _safePush.bind(this);
while (!isChunkProcessed) {
switch (this.state) {
case STATE_IDLE:
this.state = STATE_MARKER;
break;
case STATE_MARKER:
if (safePush(4, true, this._validateMarker.bind(this))) {
this.state = this.isFlac ? STATE_MDB_HEADER : STATE_PASS_THROUGH;
} else {
isChunkProcessed = true;
}
break;
case STATE_MDB_HEADER:
if (safePush(4, true, this._validateMDBHeader.bind(this))) {
this.state = STATE_MDB;
} else {
isChunkProcessed = true;
}
break;
case STATE_MDB:
if (safePush(this.mdbLen, this.parseMetaDataBlocks, this._validateMDB.bind(this))) {
if (this.mdb.isLast) {
// This MDB has the isLast flag set to true.
// Ignore all following MDBs.
this.mdbLastWritten = true;
}
this.emit("postprocess", this.mdb);
this.state = this.mdbLast ? STATE_PASS_THROUGH : STATE_MDB_HEADER;
} else {
isChunkProcessed = true;
}
break;
case STATE_PASS_THROUGH:
safePush(chunkLen - chunkPos, false);
isChunkProcessed = true;
break;
}
}
done();
}
Processor.prototype._validateMarker = function(slice, isDone) {
this.isFlac = (slice.toString("utf8", 0) === "fLaC");
// TODO: completely bail out if file is not a FLAC?
return true;
}
Processor.prototype._validateMDBHeader = function(slice, isDone) {
// Parse MDB header
var header = slice.readUInt32BE(0);
var type = (header >>> 24) & 0x7f;
this.mdbLast = (((header >>> 24) & 0x80) !== 0);
this.mdbLen = header & 0xffffff;
// Create appropriate MDB object
// (data is injected later in _validateMDB, if parseMetaDataBlocks option is set to true)
switch (type) {
case Processor.MDB_TYPE_STREAMINFO:
this.mdb = new MetaDataBlockStreamInfo(this.mdbLast);
break;
case Processor.MDB_TYPE_VORBIS_COMMENT:
this.mdb = new MetaDataBlockVorbisComment(this.mdbLast);
break;
case Processor.MDB_TYPE_PICTURE:
this.mdb = new MetaDataBlockPicture(this.mdbLast);
break;
case Processor.MDB_TYPE_PADDING:
case Processor.MDB_TYPE_APPLICATION:
case Processor.MDB_TYPE_SEEKTABLE:
case Processor.MDB_TYPE_CUESHEET:
case Processor.MDB_TYPE_INVALID:
default:
this.mdb = new MetaDataBlock(this.mdbLast, type);
break
}
this.emit("preprocess", this.mdb);
if (this.mdbLastWritten) {
// A previous MDB had the isLast flag set to true.
// Ignore all following MDBs.
this.mdb.remove();
} else {
// The consumer may change the MDB's isLast flag in the preprocess handler.
// Here that flag is updated in the MDB header.
if (this.mdbLast !== this.mdb.isLast) {
if (this.mdb.isLast) {
header |= 0x80000000;
} else {
header &= 0x7fffffff;
}
slice.writeUInt32BE(header >>> 0, 0);
}
}
this.mdbPush = !this.mdb.removed;
return this.mdbPush;
}
Processor.prototype._validateMDB = function(slice, isDone) {
// Parse the MDB if parseMetaDataBlocks option is set to true
if (this.parseMetaDataBlocks && isDone) {
this.mdb.parse(slice);
}
return this.mdbPush;
}
Processor.prototype._flush = function(done) {
// All chunks have been processed
// Clean up
this.state = STATE_IDLE;
this.mdbLastWritten = false;
this.isFlac = false;
this.bufPos = 0;
this.buf = null;
this.mdb = null;
done();
}
module.exports = Processor;

View File

@ -0,0 +1,21 @@
var MetaDataBlock = module.exports = function(isLast, type) {
this.isLast = isLast;
this.type = type;
this.error = null;
this.hasData = false;
this.removed = false;
}
MetaDataBlock.prototype.remove = function() {
this.removed = true;
}
MetaDataBlock.prototype.parse = function(buffer) {
}
MetaDataBlock.prototype.toString = function() {
var str = "[MetaDataBlock]";
str += " type: " + this.type;
str += ", isLast: " + this.isLast;
return str;
}

View File

@ -0,0 +1,131 @@
var util = require("util");
var MetaDataBlock = require("./MetaDataBlock");
var MetaDataBlockPicture = module.exports = function(isLast) {
MetaDataBlock.call(this, isLast, 6);
this.pictureType = 0;
this.mimeType = "";
this.description = "";
this.width = 0;
this.height = 0;
this.bitsPerPixel = 0;
this.colors = 0;
this.pictureData = null;
}
util.inherits(MetaDataBlockPicture, MetaDataBlock);
MetaDataBlockPicture.create = function(isLast, pictureType, mimeType, description, width, height, bitsPerPixel, colors, pictureData) {
var mdb = new MetaDataBlockPicture(isLast);
mdb.pictureType = pictureType;
mdb.mimeType = mimeType;
mdb.description = description;
mdb.width = width;
mdb.height = height;
mdb.bitsPerPixel = bitsPerPixel;
mdb.colors = colors;
mdb.pictureData = pictureData;
mdb.hasData = true;
return mdb;
}
MetaDataBlockPicture.prototype.parse = function(buffer) {
try {
var pos = 0;
this.pictureType = buffer.readUInt32BE(pos);
pos += 4;
var mimeTypeLength = buffer.readUInt32BE(pos);
this.mimeType = buffer.toString("utf8", pos + 4, pos + 4 + mimeTypeLength);
pos += 4 + mimeTypeLength;
var descriptionLength = buffer.readUInt32BE(pos);
this.description = buffer.toString("utf8", pos + 4, pos + 4 + descriptionLength);
pos += 4 + descriptionLength;
this.width = buffer.readUInt32BE(pos);
this.height = buffer.readUInt32BE(pos + 4);
this.bitsPerPixel = buffer.readUInt32BE(pos + 8);
this.colors = buffer.readUInt32BE(pos + 12);
pos += 16;
var pictureDataLength = buffer.readUInt32BE(pos);
this.pictureData = new Buffer(pictureDataLength);
buffer.copy(this.pictureData, 0, pos + 4, pictureDataLength);
this.hasData = true;
}
catch (e) {
this.error = e;
this.hasData = false;
}
}
MetaDataBlockPicture.prototype.publish = function() {
var pos = 0;
var size = this.getSize();
var buffer = new Buffer(4 + size);
var header = size;
header |= (this.type << 24);
header |= (this.isLast ? 0x80000000 : 0);
buffer.writeUInt32BE(header >>> 0, pos);
pos += 4;
buffer.writeUInt32BE(this.pictureType, pos);
pos += 4;
var mimeTypeLen = Buffer.byteLength(this.mimeType);
buffer.writeUInt32BE(mimeTypeLen, pos);
buffer.write(this.mimeType, pos + 4);
pos += 4 + mimeTypeLen;
var descriptionLen = Buffer.byteLength(this.description);
buffer.writeUInt32BE(descriptionLen, pos);
buffer.write(this.description, pos + 4);
pos += 4 + descriptionLen;
buffer.writeUInt32BE(this.width, pos);
buffer.writeUInt32BE(this.height, pos + 4);
buffer.writeUInt32BE(this.bitsPerPixel, pos + 8);
buffer.writeUInt32BE(this.colors, pos + 12);
pos += 16;
buffer.writeUInt32BE(this.pictureData.length, pos);
this.pictureData.copy(buffer, pos + 4);
return buffer;
}
MetaDataBlockPicture.prototype.getSize = function() {
var size = 4;
size += 4 + Buffer.byteLength(this.mimeType);
size += 4 + Buffer.byteLength(this.description);
size += 16;
size += 4 + this.pictureData.length;
return size;
}
MetaDataBlockPicture.prototype.toString = function() {
var str = "[MetaDataBlockPicture]";
str += " type: " + this.type;
str += ", isLast: " + this.isLast;
if (this.error) {
str += "\n ERROR: " + this.error;
}
if (this.hasData) {
str += "\n pictureType: " + this.pictureType;
str += "\n mimeType: " + this.mimeType;
str += "\n description: " + this.description;
str += "\n width: " + this.width;
str += "\n height: " + this.height;
str += "\n bitsPerPixel: " + this.bitsPerPixel;
str += "\n colors: " + this.colors;
str += "\n pictureData: " + (this.pictureData ? this.pictureData.length : "<null>");
}
return str;
}

View File

@ -0,0 +1,86 @@
var util = require("util");
var MetaDataBlock = require("./MetaDataBlock");
var MetaDataBlockStreamInfo = module.exports = function(isLast) {
MetaDataBlock.call(this, isLast, 0);
this.minBlockSize = 0;
this.maxBlockSize = 0;
this.minFrameSize = 0;
this.maxFrameSize = 0;
this.sampleRate = 0;
this.channels = 0;
this.bitsPerSample = 0;
this.samples = 0;
this.checksum = null;
this.duration = 0;
this.durationStr = "0:00.000";
}
util.inherits(MetaDataBlockStreamInfo, MetaDataBlock);
MetaDataBlockStreamInfo.prototype.remove = function() {
console.error("WARNING: Can't remove StreamInfo block!");
}
MetaDataBlockStreamInfo.prototype.parse = function(buffer) {
try {
var pos = 0;
this.minBlockSize = buffer.readUInt16BE(pos);
this.maxBlockSize = buffer.readUInt16BE(pos + 2);
this.minFrameSize = (buffer.readUInt8(pos + 4) << 16) | buffer.readUInt16BE(pos + 5);
this.maxFrameSize = (buffer.readUInt8(pos + 7) << 16) | buffer.readUInt16BE(pos + 8);
var tmp = buffer.readUInt32BE(pos + 10);
this.sampleRate = tmp >>> 12;
this.channels = (tmp >>> 9) & 0x07;
this.bitsPerSample = (tmp >>> 4) & 0x1f;
this.samples = +((tmp & 0x0f) << 4) + buffer.readUInt32BE(pos + 14);
this.checksum = new Buffer(16);
buffer.copy(this.checksum, 0, 18, 34);
this.duration = this.samples / this.sampleRate;
var minutes = "" + Math.floor(this.duration / 60);
var seconds = pad(Math.floor(this.duration % 60), 2);
var milliseconds = pad(Math.round(((this.duration % 60) - Math.floor(this.duration % 60)) * 1000), 3);
this.durationStr = minutes + ":" + seconds + "." + milliseconds;
this.hasData = true;
}
catch (e) {
this.error = e;
this.hasData = false;
}
}
MetaDataBlockStreamInfo.prototype.toString = function() {
var str = "[MetaDataBlockStreamInfo]";
str += " type: " + this.type;
str += ", isLast: " + this.isLast;
if (this.error) {
str += "\n ERROR: " + this.error;
}
if (this.hasData) {
str += "\n minBlockSize: " + this.minBlockSize;
str += "\n maxBlockSize: " + this.maxBlockSize;
str += "\n minFrameSize: " + this.minFrameSize;
str += "\n maxFrameSize: " + this.maxFrameSize;
str += "\n samples: " + this.samples;
str += "\n sampleRate: " + this.sampleRate;
str += "\n channels: " + (this.channels + 1);
str += "\n bitsPerSample: " + (this.bitsPerSample + 1);
str += "\n duration: " + this.durationStr;
str += "\n checksum: " + (this.checksum ? this.checksum.toString("hex") : "<null>");
}
return str;
}
function pad(n, width) {
n = "" + n;
return (n.length >= width) ? n : new Array(width - n.length + 1).join("0") + n;
}

View File

@ -0,0 +1,108 @@
var util = require("util");
var MetaDataBlock = require("./MetaDataBlock");
var MetaDataBlockVorbisComment = module.exports = function(isLast) {
MetaDataBlock.call(this, isLast, 4);
this.vendor = "";
this.comments = [];
}
util.inherits(MetaDataBlockVorbisComment, MetaDataBlock);
MetaDataBlockVorbisComment.create = function(isLast, vendor, comments) {
var mdb = new MetaDataBlockVorbisComment(isLast);
mdb.vendor = vendor;
mdb.comments = comments;
mdb.hasData = true;
return mdb;
}
MetaDataBlockVorbisComment.prototype.parse = function(buffer) {
try {
var pos = 0;
var vendorLen = buffer.readUInt32LE(pos);
var vendor = buffer.toString("utf8", pos + 4, pos + 4 + vendorLen);
this.vendor = vendor;
pos += 4 + vendorLen;
var commentCount = buffer.readUInt32LE(pos);
pos += 4;
while (commentCount-- > 0) {
var commentLen = buffer.readUInt32LE(pos);
var comment = buffer.toString("utf8", pos + 4, pos + 4 + commentLen);
this.comments.push(comment);
pos += 4 + commentLen;
}
this.hasData = true;
}
catch (e) {
this.error = e;
this.hasData = false;
}
}
MetaDataBlockVorbisComment.prototype.publish = function() {
var pos = 0;
var size = this.getSize();
var buffer = new Buffer(4 + size);
var header = size;
header |= (this.type << 24);
header |= (this.isLast ? 0x80000000 : 0);
buffer.writeUInt32BE(header >>> 0, pos);
pos += 4;
var vendorLen = Buffer.byteLength(this.vendor);
buffer.writeUInt32LE(vendorLen, pos);
buffer.write(this.vendor, pos + 4);
pos += 4 + vendorLen;
var commentCount = this.comments.length;
buffer.writeUInt32LE(commentCount, pos);
pos += 4;
for (var i = 0; i < commentCount; i++) {
var comment = this.comments[i];
var commentLen = Buffer.byteLength(comment);
buffer.writeUInt32LE(commentLen, pos);
buffer.write(comment, pos + 4);
pos += 4 + commentLen;
}
return buffer;
}
MetaDataBlockVorbisComment.prototype.getSize = function() {
var size = 8 + Buffer.byteLength(this.vendor);
for (var i = 0; i < this.comments.length; i++) {
size += 4 + Buffer.byteLength(this.comments[i]);
}
return size;
}
MetaDataBlockVorbisComment.prototype.toString = function() {
var str = "[MetaDataBlockVorbisComment]";
str += " type: " + this.type;
str += ", isLast: " + this.isLast;
if (this.error) {
str += "\n ERROR: " + this.error;
}
if (this.hasData) {
str += "\n vendor: " + this.vendor;
if (this.comments.length) {
str += "\n comments:";
for (var i = 0; i < this.comments.length; i++) {
str += "\n " + this.comments[i].split("=").join(": ");
}
} else {
str += "\n comments: none";
}
}
return str;
}

View File

@ -0,0 +1,24 @@
{
"name": "flac-metadata",
"description": "FLAC metadata processor implemented as Transform stream",
"keywords": ["flac", "metadata", "audio"],
"author": "Claus Wahlers <claus@codeazur.com.br> (http://wahlers.com.br/claus/)",
"homepage": "https://github.com/claus/flac-metadata",
"version": "0.1.1",
"license": "MIT",
"main": "index.js",
"directories": {
"lib": "./lib"
},
"repository": {
"type": "git",
"url": "https://github.com/claus/flac-metadata.git"
},
"bugs": {
"url": "https://github.com/claus/flac-metadata/issues",
"email": "claus@codeazur.com.br"
},
"engines": {
"node": ">=0.8"
}
}

View File

@ -0,0 +1,31 @@
const WindowsPlatform = require('./platforms/windows');
const LinuxPlatform = require('./platforms/linux');
const DarwinPlatform = require('./platforms/darwin');
function getMethods() {
const classes = {
'win32': WindowsPlatform,
'linux': LinuxPlatform,
'darwin': DarwinPlatform
};
return classes[process.platform];
}
const methods = getMethods();
function total() {
return methods.getTotalMemory();
}
function used() {
return methods.getUsedMemory();
}
function free() {
return methods.getFreeMemory();
}
module.exports = {total, used, free};

View File

@ -0,0 +1,37 @@
const exec = require('child_process').execSync;
module.exports = class Darwin {
static getTotalMemory() {
return parseInt(exec('sysctl -n hw.memsize', {'encoding': 'utf8'}), 10);
}
static getUsedMemory() {
const memoryTypes = ['active', 'wired down', 'inactive'];
const pageSize = this.getPageSize();
let totalMemoryUsed = 0;
memoryTypes.forEach((memoryType) => {
totalMemoryUsed += this.getMemoryTypeUsage(memoryType);
});
return (totalMemoryUsed * pageSize);
}
static getFreeMemory() {
return this.getTotalMemory() - this.getUsedMemory();
}
static getPageSize() {
return parseInt(exec('sysctl -n hw.pagesize', {'encoding': 'utf8'}), 10);
}
static getMemoryTypeUsage(memoryType) {
let position = 3;
if (1 < memoryType.split(' ').length) {
position = 4;
}
return parseInt(exec(`vm_stat | grep 'Pages ${memoryType}:' | awk '{print $${position}}'`, {'encoding': 'utf8'}), 10);
}
};

View File

@ -0,0 +1,15 @@
const exec = require('child_process').execSync;
module.exports = class Linux {
static getTotalMemory() {
return parseInt(exec('free -b | grep "Mem:" | awk \'{print $2}\'', {'encoding': 'utf8'}), 10);
}
static getUsedMemory() {
return parseInt(exec('free -b | grep "Mem:" | awk \'{print $7}\'', {'encoding': 'utf8'}), 10);
}
static getFreeMemory() {
return this.getTotalMemory() - this.getUsedMemory();
}
};

View File

@ -0,0 +1,15 @@
const exec = require('child_process').execSync;
module.exports = class Windows {
static getTotalMemory() {
return parseInt(exec('wmic OS get TotalVisibleMemorySize /value', {'encoding': 'utf8'}).trim().split('=')[1], 10) * 1024;
}
static getUsedMemory() {
return this.getTotalMemory() - this.getFreeMemory();
}
static getFreeMemory() {
return parseInt(exec('wmic OS get FreePhysicalMemory /value', {'encoding': 'utf8'}).trim().split('=')[1], 10) * 1024;
}
};

371
package-lock.json generated
View File

@ -1,6 +1,6 @@
{
"name": "SMLoadr",
"version": "1.8.0",
"version": "1.9.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@ -10,23 +10,15 @@
"integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
"requires": {
"co": "4.6.0",
"fast-deep-equal": "1.0.0",
"fast-deep-equal": "1.1.0",
"fast-json-stable-stringify": "2.0.0",
"json-schema-traverse": "0.3.1"
}
},
"ansi-escape-sequences": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/ansi-escape-sequences/-/ansi-escape-sequences-4.0.0.tgz",
"integrity": "sha512-v+0wW9Wezwsyb0uF4aBVCjmSqit3Ru7PZFziGF0o2KwTvN2zWfTi3BRLq9EkJFdg3eBbyERXGTntVpBxH1J68Q==",
"requires": {
"array-back": "2.0.0"
}
},
"ansi-escapes": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.0.0.tgz",
"integrity": "sha512-O/klc27mWNUigtv0F8NJWbLF00OcegQalkqKURWdosW08YZKi4m6CnSUSvIZG1otNJbTWhN01Hhz389DW7mvDQ=="
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz",
"integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw=="
},
"ansi-regex": {
"version": "3.0.0",
@ -34,9 +26,9 @@
"integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="
},
"ansi-styles": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
"integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"requires": {
"color-convert": "1.9.1"
}
@ -68,6 +60,11 @@
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
},
"async": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
"integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo="
},
"asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
@ -79,9 +76,9 @@
"integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
},
"aws4": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz",
"integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4="
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.7.0.tgz",
"integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w=="
},
"bcrypt-pbkdf": {
"version": "1.0.1",
@ -102,46 +99,31 @@
"resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz",
"integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=",
"requires": {
"hoek": "4.2.0"
"hoek": "4.2.1"
}
},
"browser-id3-writer": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/browser-id3-writer/-/browser-id3-writer-4.0.0.tgz",
"integrity": "sha512-Q8ufttKbt1+vu5giG81o+yvNHg54NdNoWi1sFgCMAsOSKF7XvsjlfRZc4vKzbxP5LTnkoFRY2RusC5mM+Kkq8Q=="
},
"buffer-alloc": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.1.0.tgz",
"integrity": "sha1-BVFNM78WVtNUDGhPZbEgLpDsowM=",
"cache-manager": {
"version": "2.9.0",
"resolved": "https://registry.npmjs.org/cache-manager/-/cache-manager-2.9.0.tgz",
"integrity": "sha1-Xh9jF8oaJeQN3zZacWJ1evFSNT4=",
"requires": {
"buffer-alloc-unsafe": "0.1.1",
"buffer-fill": "0.1.0"
"async": "1.5.2",
"lru-cache": "4.0.0"
}
},
"buffer-alloc-unsafe": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-0.1.1.tgz",
"integrity": "sha1-/+H2dVHdBVc33iUzN7/oU9+rGmo="
},
"buffer-fill": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-0.1.0.tgz",
"integrity": "sha1-ypRw6NTRuXf9dUP04qtqfclRAag="
},
"caseless": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
"integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
},
"chalk": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz",
"integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==",
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz",
"integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==",
"requires": {
"ansi-styles": "3.2.0",
"ansi-styles": "3.2.1",
"escape-string-regexp": "1.0.5",
"supports-color": "4.5.0"
"supports-color": "5.3.0"
}
},
"chardet": {
@ -191,17 +173,17 @@
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
},
"combined-stream": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz",
"integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=",
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz",
"integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=",
"requires": {
"delayed-stream": "1.0.0"
}
},
"command-line-args": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.0.1.tgz",
"integrity": "sha512-gRJDcIjFSzMcmG/GrJlgL0wWoAxr11mVzCq32bjka0endupm9meLwvoJUKc4HDeFiEIB2X3GvNrhF5cKO4Bd4A==",
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.0.2.tgz",
"integrity": "sha512-/qPcbL8zpqg53x4rAaqMFlRV4opN3pbla7I7k9x8kyOBMQoGT6WltjN6sXZuxOXw6DgdK7Ad+ijYS5gjcr7vlA==",
"requires": {
"argv-tools": "0.1.1",
"array-back": "2.0.0",
@ -211,13 +193,13 @@
}
},
"command-line-usage": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-4.1.0.tgz",
"integrity": "sha512-MxS8Ad995KpdAC0Jopo/ovGIroV/m0KHwzKfXxKag6FHOkGsH8/lv5yjgablcRxCJJC0oJeUMuO/gmaq+Wq46g==",
"version": "5.0.4",
"resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-5.0.4.tgz",
"integrity": "sha512-h17lBwC5bl5RdukPbXji75+cg2/Qbny6kGsmLoy34s9DNH90RwRvJKb+VU5j4YY9HzYl7twLaOWDJQ4b9U+p/Q==",
"requires": {
"ansi-escape-sequences": "4.0.0",
"array-back": "2.0.0",
"table-layout": "0.4.2",
"chalk": "2.3.2",
"table-layout": "0.4.3",
"typical": "2.6.1"
}
},
@ -239,7 +221,7 @@
"resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz",
"integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==",
"requires": {
"hoek": "4.2.0"
"hoek": "4.2.1"
}
}
}
@ -279,6 +261,11 @@
"jsbn": "0.1.1"
}
},
"escape-regexp": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/escape-regexp/-/escape-regexp-0.0.1.tgz",
"integrity": "sha1-9EvaEtRbvfnLf4Yu5+SCez3TIlQ="
},
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
@ -290,12 +277,12 @@
"integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ="
},
"external-editor": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.1.0.tgz",
"integrity": "sha512-E44iT5QVOUJBKij4IIV3uvxuNlbKS38Tw1HiupxEIHPv9qtC2PrDYohbXV5U+1jnfIXttny8gUhj+oZvflFlzA==",
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz",
"integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==",
"requires": {
"chardet": "0.4.2",
"iconv-lite": "0.4.19",
"iconv-lite": "0.4.21",
"tmp": "0.0.33"
}
},
@ -305,9 +292,9 @@
"integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
},
"fast-deep-equal": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz",
"integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8="
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz",
"integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ="
},
"fast-json-stable-stringify": {
"version": "2.0.0",
@ -331,34 +318,38 @@
"test-value": "3.0.0"
}
},
"flac-metadata": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/flac-metadata/-/flac-metadata-0.1.1.tgz",
"integrity": "sha1-wC+KBtJL1bad4rhVEsbkW9j5F2w="
},
"forever-agent": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
"integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
},
"form-data": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz",
"integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=",
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz",
"integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=",
"requires": {
"asynckit": "0.4.0",
"combined-stream": "1.0.5",
"mime-types": "2.1.17"
"combined-stream": "1.0.6",
"mime-types": "2.1.18"
}
},
"fs-extra": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz",
"integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==",
"fs-finder": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/fs-finder/-/fs-finder-1.8.1.tgz",
"integrity": "sha1-EG/qiqidCvNDNgZj1YVYYsrhuHQ=",
"requires": {
"graceful-fs": "4.1.11",
"jsonfile": "4.0.0",
"universalify": "0.1.1"
"async": "0.2.10",
"escape-regexp": "0.0.1",
"moment": "2.5.1",
"operator-compare": "1.0.3",
"q": "1.0.1"
},
"dependencies": {
"async": {
"version": "0.2.10",
"resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz",
"integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E="
}
}
},
"getpass": {
@ -372,7 +363,8 @@
"graceful-fs": {
"version": "4.1.11",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
"integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg="
"integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
"optional": true
},
"har-schema": {
"version": "2.0.0",
@ -389,9 +381,9 @@
}
},
"has-flag": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
"integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE="
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
},
"hawk": {
"version": "6.0.2",
@ -400,14 +392,14 @@
"requires": {
"boom": "4.3.1",
"cryptiles": "3.1.2",
"hoek": "4.2.0",
"hoek": "4.2.1",
"sntp": "2.1.0"
}
},
"hoek": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz",
"integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ=="
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz",
"integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA=="
},
"http-signature": {
"version": "1.2.0",
@ -416,13 +408,16 @@
"requires": {
"assert-plus": "1.0.0",
"jsprim": "1.4.1",
"sshpk": "1.13.1"
"sshpk": "1.14.1"
}
},
"iconv-lite": {
"version": "0.4.19",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
"integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ=="
"version": "0.4.21",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.21.tgz",
"integrity": "sha512-En5V9za5mBt2oUA03WGD3TwDv0MKAruqsuxstbMUZaj9W9k/m1CV/9py3l0L5kw9Bln8fdHQmzHSYtvpvTLpKw==",
"requires": {
"safer-buffer": "2.1.2"
}
},
"inherits": {
"version": "2.0.1",
@ -430,20 +425,20 @@
"integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE="
},
"inquirer": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-5.0.1.tgz",
"integrity": "sha512-si5Jmjj6ngjkDSPt/MwuIysUNNKu8SGWnweZE2QXRfd5SKJgDown8IDbHQiS5WLxqEQDQC0Vjcgtpw1XyZJWpw==",
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-5.2.0.tgz",
"integrity": "sha512-E9BmnJbAKLPGonz0HeWHtbKf+EeSP93paWO3ZYoUpq/aowXvYGjjCSuashhXPpzbArIjBbji39THkxTz9ZeEUQ==",
"requires": {
"ansi-escapes": "3.0.0",
"chalk": "2.3.0",
"ansi-escapes": "3.1.0",
"chalk": "2.3.2",
"cli-cursor": "2.1.0",
"cli-width": "2.2.0",
"external-editor": "2.1.0",
"external-editor": "2.2.0",
"figures": "2.0.0",
"lodash": "4.17.4",
"lodash": "4.17.5",
"mute-stream": "0.0.7",
"run-async": "2.3.0",
"rxjs": "5.5.6",
"rxjs": "5.5.8",
"string-width": "2.1.1",
"strip-ansi": "4.0.0",
"through": "2.3.8"
@ -510,9 +505,9 @@
}
},
"lodash": {
"version": "4.17.4",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
"integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
"version": "4.17.5",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz",
"integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw=="
},
"lodash.camelcase": {
"version": "4.3.0",
@ -524,33 +519,44 @@
"resolved": "https://registry.npmjs.org/lodash.padend/-/lodash.padend-4.6.1.tgz",
"integrity": "sha1-U8y6BH0G4VjTEfRdpiX05J5vFm4="
},
"log": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/log/-/log-1.4.0.tgz",
"integrity": "sha1-S6HYkP3iSbAx3KA7w36q8yVlbxw="
},
"log-symbols": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz",
"integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==",
"requires": {
"chalk": "2.3.0"
"chalk": "2.3.2"
}
},
"lru-cache": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.0.tgz",
"integrity": "sha1-tcvwFVbBaWb+vlTO7A+03JDfbCg=",
"requires": {
"pseudomap": "1.0.2",
"yallist": "2.1.2"
}
},
"md5-file": {
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/md5-file/-/md5-file-3.2.3.tgz",
"integrity": "sha512-3Tkp1piAHaworfcCgH0jKbTvj1jWWFgbvh2cXaNCgHwyTCBxxvD1Y04rmfpvdPm1P4oXMOpm6+2H7sr7v9v8Fw==",
"requires": {
"buffer-alloc": "1.1.0"
}
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/md5-file/-/md5-file-4.0.0.tgz",
"integrity": "sha512-UC0qFwyAjn4YdPpKaDNw6gNxRf7Mcx7jC1UGCY4boCzgvU2Aoc1mOGzTtrjjLKhM5ivsnhoKpQVxKPp+1j1qwg=="
},
"mime-db": {
"version": "1.30.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz",
"integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE="
"version": "1.33.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz",
"integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ=="
},
"mime-types": {
"version": "2.1.17",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz",
"integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=",
"version": "2.1.18",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz",
"integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==",
"requires": {
"mime-db": "1.30.0"
"mime-db": "1.33.0"
}
},
"mimic-fn": {
@ -558,19 +564,16 @@
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz",
"integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg="
},
"moment": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.5.1.tgz",
"integrity": "sha1-cUajkAUzBkynmdXnkvTkgO4Ogrw="
},
"mute-stream": {
"version": "0.0.7",
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
"integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s="
},
"nano-cache": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/nano-cache/-/nano-cache-1.1.1.tgz",
"integrity": "sha1-UQbZXzkstENZZU4hzAFa4hjnVGY=",
"requires": {
"extend": "3.0.1"
}
},
"oauth-sign": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
@ -589,6 +592,11 @@
"resolved": "https://registry.npmjs.org/openurl/-/openurl-1.1.1.tgz",
"integrity": "sha1-OHW0sO96UsFW8NtB1GCduw+Us4c="
},
"operator-compare": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/operator-compare/-/operator-compare-1.0.3.tgz",
"integrity": "sha1-jQbQlLwbg6YH/JyfOABEeIZZGvk="
},
"ora": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ora/-/ora-2.0.0.tgz",
@ -645,11 +653,21 @@
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
"integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
},
"pseudomap": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
"integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM="
},
"punycode": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
"integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
},
"q": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/q/-/q-1.0.1.tgz",
"integrity": "sha1-EYcq7t7okmgRCxCnGESP+xARKhQ="
},
"qs": {
"version": "6.5.1",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
@ -661,41 +679,58 @@
"integrity": "sha1-JYx479FT3fk8tWEjf2EYTzaW4yc="
},
"request": {
"version": "2.83.0",
"resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz",
"integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==",
"version": "2.85.0",
"resolved": "https://registry.npmjs.org/request/-/request-2.85.0.tgz",
"integrity": "sha512-8H7Ehijd4js+s6wuVPLjwORxD4zeuyjYugprdOXlPSqaApmL/QOy+EB/beICHVCHkGMKNh5rvihb5ov+IDw4mg==",
"requires": {
"aws-sign2": "0.7.0",
"aws4": "1.6.0",
"aws4": "1.7.0",
"caseless": "0.12.0",
"combined-stream": "1.0.5",
"combined-stream": "1.0.6",
"extend": "3.0.1",
"forever-agent": "0.6.1",
"form-data": "2.3.1",
"form-data": "2.3.2",
"har-validator": "5.0.3",
"hawk": "6.0.2",
"http-signature": "1.2.0",
"is-typedarray": "1.0.0",
"isstream": "0.1.2",
"json-stringify-safe": "5.0.1",
"mime-types": "2.1.17",
"mime-types": "2.1.18",
"oauth-sign": "0.8.2",
"performance-now": "2.1.0",
"qs": "6.5.1",
"safe-buffer": "5.1.1",
"stringstream": "0.0.5",
"tough-cookie": "2.3.3",
"tough-cookie": "2.3.4",
"tunnel-agent": "0.6.0",
"uuid": "3.2.1"
}
},
"request-promise-cache": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/request-promise-cache/-/request-promise-cache-1.0.6.tgz",
"integrity": "sha1-d8opARFlG0UnLzFA6cDoNXCHiMM=",
"request-plus": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/request-plus/-/request-plus-1.0.1.tgz",
"integrity": "sha1-ANlMJReog5qdtP3PCq8WoP30ngs=",
"requires": {
"nano-cache": "1.1.1",
"request": "2.83.0"
"request-promise-native": "1.0.5"
}
},
"request-promise-core": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.1.tgz",
"integrity": "sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY=",
"requires": {
"lodash": "4.17.5"
}
},
"request-promise-native": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.5.tgz",
"integrity": "sha1-UoF3D2jgyXGeUWP9P6tIIhX0/aU=",
"requires": {
"request-promise-core": "1.1.1",
"stealthy-require": "1.1.1",
"tough-cookie": "2.3.4"
}
},
"restore-cursor": {
@ -716,9 +751,9 @@
}
},
"rxjs": {
"version": "5.5.6",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.6.tgz",
"integrity": "sha512-v4Q5HDC0FHAQ7zcBX7T2IL6O5ltl1a2GX4ENjPXg6SjDY69Cmx9v4113C99a4wGF16ClPv5Z8mghuYorVkg/kg==",
"version": "5.5.8",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.8.tgz",
"integrity": "sha512-Bz7qou7VAIoGiglJZbzbXa4vpX5BmTTN2Dj/se6+SwADtw4SihqBIiEa7VmTXJ8pynvq0iFr5Gx9VLyye1rIxQ==",
"requires": {
"symbol-observable": "1.0.1"
}
@ -728,6 +763,11 @@
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
"integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
},
"safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"sanitize-filename": {
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.1.tgz",
@ -746,13 +786,13 @@
"resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz",
"integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==",
"requires": {
"hoek": "4.2.0"
"hoek": "4.2.1"
}
},
"sshpk": {
"version": "1.13.1",
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz",
"integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=",
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.1.tgz",
"integrity": "sha1-Ew9Zde3a2WPx1W+SuaxsUfqfg+s=",
"requires": {
"asn1": "0.2.3",
"assert-plus": "1.0.0",
@ -764,6 +804,11 @@
"tweetnacl": "0.14.5"
}
},
"stealthy-require": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
"integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks="
},
"string-width": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
@ -787,11 +832,11 @@
}
},
"supports-color": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
"integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz",
"integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==",
"requires": {
"has-flag": "2.0.0"
"has-flag": "3.0.0"
}
},
"symbol-observable": {
@ -800,9 +845,9 @@
"integrity": "sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ="
},
"table-layout": {
"version": "0.4.2",
"resolved": "https://registry.npmjs.org/table-layout/-/table-layout-0.4.2.tgz",
"integrity": "sha512-tygyl5+eSHj4chpq5Zfy6cpc7MOUBClAW9ozghFH7hg9bAUzShOYn+/vUzTRkKOSLJWKfgYtP2tAU2c0oAD8eg==",
"version": "0.4.3",
"resolved": "https://registry.npmjs.org/table-layout/-/table-layout-0.4.3.tgz",
"integrity": "sha512-MIhflPM38ejKrFwWwC3P9x3eHvMo5G5AmNo29Qtz2HpBl5KD2GCcmOErjgNtUQLv/qaqVDagfJY3rJLPDvEgLg==",
"requires": {
"array-back": "2.0.0",
"deep-extend": "0.5.0",
@ -834,9 +879,9 @@
}
},
"tough-cookie": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz",
"integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=",
"version": "2.3.4",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz",
"integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==",
"requires": {
"punycode": "1.4.1"
}
@ -868,11 +913,6 @@
"resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz",
"integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0="
},
"universalify": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.1.tgz",
"integrity": "sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc="
},
"utf8-byte-length": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz",
@ -917,6 +957,11 @@
"reduce-flatten": "1.0.1",
"typical": "2.6.1"
}
},
"yallist": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
"integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI="
}
}
}

View File

@ -1,25 +1,33 @@
{
"name": "SMLoadr",
"version": "1.8.0",
"version": "1.9.0",
"description": "A streaming music downloader written in NodeJS.",
"author": "SMLoadrDev",
"license": "Unlicense",
"main": "SMLoadr.js",
"bin": "SMLoadr.js",
"repository": {
"type": "git",
"url": "https://git.teknik.io/SMLoadrDev/SMLoadr.git"
},
"engines": {
"node": ">=8.0.0"
},
"dependencies": {
"bluebird": "^3.5.1",
"browser-id3-writer": "^4.0.0",
"chalk": "^2.3.0",
"command-line-args": "^5.0.1",
"command-line-usage": "^4.1.0",
"flac-metadata": "^0.1.1",
"fs-extra": "^5.0.0",
"inquirer": "^5.0.1",
"cache-manager": "^2.9.0",
"chalk": "^2.3.2",
"command-line-args": "^5.0.2",
"command-line-usage": "^5.0.4",
"fs-finder": "^1.8.1",
"inquirer": "^5.2.0",
"jsonfile": "^4.0.0",
"md5-file": "^3.2.3",
"log": "^1.4.0",
"md5-file": "^4.0.0",
"openurl": "^1.1.1",
"ora": "^2.0.0",
"request-promise-cache": "^1.0.6",
"request": "^2.85.0",
"request-plus": "^1.0.1",
"sanitize-filename": "^1.6.1",
"util": "^0.10.3"
}