VulpesOS/assets/webapps/music-oga.gaiamobile.org/js/metadata/id3v1.js
OverSu b38dea0597 Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
2026-09-30 23:13:03 +02:00

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
};
})();