jsmediatags
Version:
Media Tags Reader (ID3, MP4)
242 lines (206 loc) • 7.06 kB
JavaScript
'use strict';
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
var StringUtils = require('./StringUtils');
var MediaFileReader = /*#__PURE__*/function () {
function MediaFileReader(path) {
_classCallCheck(this, MediaFileReader);
_defineProperty(this, "_isInitialized", void 0);
_defineProperty(this, "_size", void 0);
this._isInitialized = false;
this._size = 0;
}
/**
* Decides if this media file reader is able to read the given file.
*/
_createClass(MediaFileReader, [{
key: "init",
value:
/**
* This function needs to be called before any other function.
* Loads the necessary initial information from the file.
*/
function init(callbacks) {
var self = this;
if (this._isInitialized) {
setTimeout(callbacks.onSuccess, 1);
} else {
return this._init({
onSuccess: function onSuccess() {
self._isInitialized = true;
callbacks.onSuccess();
},
onError: callbacks.onError
});
}
}
}, {
key: "_init",
value: function _init(callbacks) {
throw new Error("Must implement init function");
}
/**
* @param range The start and end indexes of the range to load.
* Ex: [0, 7] load bytes 0 to 7 inclusive.
*/
}, {
key: "loadRange",
value: function loadRange(range, callbacks) {
throw new Error("Must implement loadRange function");
}
/**
* @return The size of the file in bytes.
*/
}, {
key: "getSize",
value: function getSize() {
if (!this._isInitialized) {
throw new Error("init() must be called first.");
}
return this._size;
}
}, {
key: "getByteAt",
value: function getByteAt(offset) {
throw new Error("Must implement getByteAt function");
}
}, {
key: "getBytesAt",
value: function getBytesAt(offset, length) {
var bytes = new Array(length);
for (var i = 0; i < length; i++) {
bytes[i] = this.getByteAt(offset + i);
}
return bytes;
}
}, {
key: "isBitSetAt",
value: function isBitSetAt(offset, bit) {
var iByte = this.getByteAt(offset);
return (iByte & 1 << bit) != 0;
}
}, {
key: "getSByteAt",
value: function getSByteAt(offset) {
var iByte = this.getByteAt(offset);
if (iByte > 127) {
return iByte - 256;
} else {
return iByte;
}
}
}, {
key: "getShortAt",
value: function getShortAt(offset, isBigEndian) {
var iShort = isBigEndian ? (this.getByteAt(offset) << 8) + this.getByteAt(offset + 1) : (this.getByteAt(offset + 1) << 8) + this.getByteAt(offset);
if (iShort < 0) {
iShort += 65536;
}
return iShort;
}
}, {
key: "getSShortAt",
value: function getSShortAt(offset, isBigEndian) {
var iUShort = this.getShortAt(offset, isBigEndian);
if (iUShort > 32767) {
return iUShort - 65536;
} else {
return iUShort;
}
}
}, {
key: "getLongAt",
value: function getLongAt(offset, isBigEndian) {
var iByte1 = this.getByteAt(offset),
iByte2 = this.getByteAt(offset + 1),
iByte3 = this.getByteAt(offset + 2),
iByte4 = this.getByteAt(offset + 3);
var iLong = isBigEndian ? (((iByte1 << 8) + iByte2 << 8) + iByte3 << 8) + iByte4 : (((iByte4 << 8) + iByte3 << 8) + iByte2 << 8) + iByte1;
if (iLong < 0) {
iLong += 4294967296;
}
return iLong;
}
}, {
key: "getSLongAt",
value: function getSLongAt(offset, isBigEndian) {
var iULong = this.getLongAt(offset, isBigEndian);
if (iULong > 2147483647) {
return iULong - 4294967296;
} else {
return iULong;
}
}
}, {
key: "getInteger24At",
value: function getInteger24At(offset, isBigEndian) {
var iByte1 = this.getByteAt(offset),
iByte2 = this.getByteAt(offset + 1),
iByte3 = this.getByteAt(offset + 2);
var iInteger = isBigEndian ? ((iByte1 << 8) + iByte2 << 8) + iByte3 : ((iByte3 << 8) + iByte2 << 8) + iByte1;
if (iInteger < 0) {
iInteger += 16777216;
}
return iInteger;
}
}, {
key: "getStringAt",
value: function getStringAt(offset, length) {
var string = [];
for (var i = offset, j = 0; i < offset + length; i++, j++) {
string[j] = String.fromCharCode(this.getByteAt(i));
}
return string.join("");
}
}, {
key: "getStringWithCharsetAt",
value: function getStringWithCharsetAt(offset, length, charset) {
var bytes = this.getBytesAt(offset, length);
var string;
switch ((charset || '').toLowerCase()) {
case "utf-16":
case "utf-16le":
case "utf-16be":
string = StringUtils.readUTF16String(bytes, charset === "utf-16be");
break;
case "utf-8":
string = StringUtils.readUTF8String(bytes);
break;
default:
string = StringUtils.readNullTerminatedString(bytes);
break;
}
return string;
}
}, {
key: "getCharAt",
value: function getCharAt(offset) {
return String.fromCharCode(this.getByteAt(offset));
}
/**
* The ID3v2 tag/frame size is encoded with four bytes where the most
* significant bit (bit 7) is set to zero in every byte, making a total of 28
* bits. The zeroed bits are ignored, so a 257 bytes long tag is represented
* as $00 00 02 01.
*/
}, {
key: "getSynchsafeInteger32At",
value: function getSynchsafeInteger32At(offset) {
var size1 = this.getByteAt(offset);
var size2 = this.getByteAt(offset + 1);
var size3 = this.getByteAt(offset + 2);
var size4 = this.getByteAt(offset + 3); // 0x7f = 0b01111111
var size = size4 & 0x7f | (size3 & 0x7f) << 7 | (size2 & 0x7f) << 14 | (size1 & 0x7f) << 21;
return size;
}
}], [{
key: "canReadFile",
value: function canReadFile(file) {
throw new Error("Must implement canReadFile function");
}
}]);
return MediaFileReader;
}();
module.exports = MediaFileReader;