@infinito/id3
Version:
ID3 Tag Reader/Writer
169 lines (167 loc) • 5.01 kB
JavaScript
import {TextEncoder,TextDecoder} from 'text-encoding';
import id3Tag from './id3tag.js';
export default class id3v2_2Frame {
constructor(buf,pos) {
Object.defineProperties(this,{
FRAME_HEADER_SIZE_BYTES:{
value:6
},
FRAME_ID_SIZE_BYTES:{
value:3
},
FRAME_SIZE_BYTES:{
value:3
},
VALID_FRAMES:{
value:{
BUF:"Recommended buffer size",
CNT:"Play counter",
COM:"Comments",
CRA:"Audio encryption",
CRM:"Encrypted meta frame",
ETC:"Event timing codes",
EQU:"Equalization",
GEO:"General encapsulated object",
IPL:"Involved people list",
LNK:"Linked information",
MCI:"Music CD Identifier",
MLL:"MPEG location lookup table",
PIC:"Attached picture",
POP:"Popularimeter",
REV:"Reverb",
RVA:"Relative volume adjustment",
SLT:"Synchronized lyric/text",
STC:"Synced tempo codes",
TAL:"Album/Movie/Show title",
TBP:"BPM (Beats Per Minute)",
TCM:"Composer",
TCO:"Content type",
TCR:"Copyright message",
TDA:"Date",
TDY:"Playlist delay",
TEN:"Encoded by",
TFT:"File type",
TIM:"Time",
TKE:"Initial key",
TLA:"Language(s)",
TLE:"Length",
TMT:"Media type",
TOA:"Original artist(s)/performer(s)",
TOF:"Original filename",
TOL:"Original Lyricist(s)/text writer(s)",
TOR:"Original release year",
TOT:"Original album/Movie/Show title",
TP1:"Lead artist(s)/Lead performer(s)/Soloist(s)/Performing group",
TP2:"Band/Orchestra/Accompaniment",
TP3:"Conductor/Performer refinement",
TP4:"Interpreted, remixed, or otherwise modified by",
TPA:"Part of a set",
TPB:"Publisher",
TRC:"ISRC (International Standard Recording Code)",
TRD:"Recording dates",
TRK:"Track number/Position in set",
TSI:"Size",
TSS:"Software/hardware and settings used for encoding",
TT1:"Content group description",
TT2:"Title/Songname/Content description",
TT3:"Subtitle/Description refinement",
TXT:"Lyricist/text writer",
TXX:"User defined text information frame",
TYE:"Year",
UFI:"Unique file identifier",
ULT:"Unsychronized lyric/text transcription",
WAF:"Official audio file webpage",
WAR:"Official artist/performer webpage",
WAS:"Official audio source webpage",
WCM:"Commercial information",
WCP:"Copyright/Legal information",
WPB:"Publishers official webpage",
WXX:"User defined URL link frame"
}
},
USED_FRAMES:{
value:{
"Album/Movie/Show title":"album",
"Band/Orchestra/Accompaniment":"album_artist",
"Composer":"composer",
"Content type":"genre",
"Lead artist(s)/Lead performer(s)/Soloist(s)/Performing group":"artist",
"Length":"length",
"Part of a set":"set",
"Publisher":"publisher",
"Title/Songname/Content description":"title",
"Track number/Position in set":"track",
"Year":"year"
}
}
});
if(!(buf instanceof ArrayBuffer)) {
if(buf=='default') {
return;
}
throw new TypeError(`Invalid buffer passed to ${this.constructor.name}`);
}
this.id = new Uint8Array(buf,pos,this.FRAME_ID_SIZE_BYTES);
if(typeof this.VALID_FRAMES[this.frame()]=="undefined") {
throw new Error("Invalid frame detected");
}
pos += this.FRAME_ID_SIZE_BYTES;
/* Calculate size */
this.size = 0;
var tempbuf = new Uint8Array(buf,pos,this.FRAME_SIZE_BYTES);
for(var i=0;i<this.FRAME_SIZE_BYTES;i++) {
this.size<<=8;
this.size += tempbuf[i];
}
pos += this.FRAME_SIZE_BYTES;
/* Get encoding */
this.encoding = new Uint8Array(buf,pos,1)[0];
pos++;
/* Get data */
this.data = new Uint8Array(buf,pos,this.size-1);
/* Remove Unicode BOM (if necessary) */
/*if((this.data[0]==255)&&(this.data[1]==254)) {
this.data = new Uint8Array(buf,pos+2,this.size-3);
}*/
}
frame() {
return String.fromCharCode(this.id[0])+String.fromCharCode(this.id[1])+String.fromCharCode(this.id[2]);
}
tag_name() {
return this.VALID_FRAMES[this.frame()];
}
add_to_ID3(tags_obj) {
var tag_toset = this.USED_FRAMES[this.tag_name()];
if(typeof tag_toset=="undefined") {
return false;
}
if(!(tags_obj instanceof id3Tag)) {
throw new Error("Passed object invalid");
return false;
}
tags_obj[tag_toset] = this.content();
return true;
}
content() {
if(!(this.data instanceof Uint8Array)) {
return "";
}
if(this.data.size==0) {
return "";
}
switch(this.encoding) {
case 0:
var dec = new TextDecoder("windows-1252");
break;
case 1:
throw new Error("Not implemented");
return "";
//Should be unicode
//var dec = new TextDecoder("utf-8");
default:
throw new Error("Invalid encoding provided");
return "";
}
return dec.decode(this.data).replace(/\0/g,'');
}
}