Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
79 lines
2.1 KiB
JavaScript
79 lines
2.1 KiB
JavaScript
/* global BlobView */
|
|
/* exported ID3v1Metadata */
|
|
'use strict';
|
|
|
|
/**
|
|
* Parse files with ID3v1 metadata. Metadata includes title, artist, album,
|
|
* and possibly the track number. Year, comment and genre are ignored.
|
|
*
|
|
* Format information:
|
|
* http://www.id3.org/ID3v1
|
|
* http://en.wikipedia.org/wiki/ID3
|
|
*/
|
|
var ID3v1Metadata = (function() {
|
|
/**
|
|
* Parse a file and return a Promise with the metadata.
|
|
*
|
|
* @param {BlobView} blobview The audio file to parse.
|
|
* @return {Promise} A Promise returning the parsed metadata object.
|
|
*/
|
|
function parse(blobview) {
|
|
return new Promise(function(resolve, reject) {
|
|
var blob = blobview.blob;
|
|
BlobView.get(blob, blob.size - 128, 128, function(footer, error) {
|
|
if (error) {
|
|
reject(error);
|
|
return;
|
|
}
|
|
|
|
try {
|
|
var magic = footer.getBinaryText(0, 3);
|
|
if (magic === 'TAG') {
|
|
// It's an MP3 file with an ID3v1 tag.
|
|
resolve(parseID3v1Metadata(footer));
|
|
} else {
|
|
// It's an MP3 file with no metadata. Just resolve to an empty
|
|
// metatada object.
|
|
resolve({});
|
|
}
|
|
} catch (e) {
|
|
reject(e);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Parse ID3v1 metadata from the 128 bytes footer at the end of a file.
|
|
*
|
|
* @param {BlobView} footer The last 128 bytes of the file.
|
|
* @return {Metadata} The parsed metadata object.
|
|
*/
|
|
function parseID3v1Metadata(footer) {
|
|
footer.seek(3); // Skip the "TAG" prefix.
|
|
var title = footer.readNullTerminatedLatin1Text(30, true);
|
|
var artist = footer.readNullTerminatedLatin1Text(30, true);
|
|
var album = footer.readNullTerminatedLatin1Text(30, true);
|
|
|
|
footer.advance(32); // Skip year and comment.
|
|
var zerobyte = footer.readUnsignedByte();
|
|
var track = footer.readUnsignedByte();
|
|
|
|
var metadata = {
|
|
tag_format: 'id3v1',
|
|
title: title || undefined,
|
|
artist: artist || undefined,
|
|
album: album || undefined
|
|
};
|
|
if (zerobyte === 0 && track !== 0) {
|
|
metadata.tracknum = track;
|
|
}
|
|
|
|
return metadata;
|
|
}
|
|
|
|
return {
|
|
parse: parse
|
|
};
|
|
|
|
})();
|