UNPKG

@infinito/id3

Version:
196 lines (193 loc) 5.95 kB
import {TextEncoder,TextDecoder} from 'text-encoding'; import id3Tag from './id3tag.js'; import getSyncSafe from '../get.syncsafe.js'; export default class id3v2_4Frame { constructor(buf,pos) { Object.defineProperties(this,{ FRAME_HEADER_SIZE_BYTES:{ value:10 }, FRAME_ID_SIZE_BYTES:{ value:4 }, FRAME_SIZE_BYTES:{ value:4 }, FRAME_FLAGS_BYTES:{ value:2 }, VALID_FRAMES:{ value:{ AENC:"Audio encryption", APIC:"Attached picture", ASPI:"Audio seek point index", COMM:"Comments", COMR:"Commercial frame", ENCR:"Encryption method registration", EQU2:"Equalisation (2)", ETCO:"Event timing codes", GEOB:"General encapsulated object", GRID:"Group identification registration", LINK:"Linked information", MCDI:"Music CD identifier", MLLT:"MPEG location lookup table", OWNE:"Ownership frame", PRIV:"Private frame", PCNT:"Play counter", POPM:"Popularimeter", POSS:"Position synchronisation frame", RBUF:"Recommended buffer size", RVA2:"Relative volume adjustment (2)", RVRB:"Reverb", SEEK:"Seek frame", SIGN:"Signature frame", SYLT:"Synchronised lyric/text", SYTC:"Synchronised tempo codes", TALB:"Album/Movie/Show title", TBPM:"BPM (beats per minute)", TCOM:"Composer", TCON:"Content type", TCOP:"Copyright message", TDEN:"Encoding time", TDLY:"Playlist delay", TDOR:"Original release time", TDRC:"Recording time", TDRL:"Release time", TDTG:"Tagging time", TENC:"Encoded by", TEXT:"Lyricist/Text writer", TFLT:"File type", TIPL:"Involved people list", TIT1:"Content group description", TIT2:"Title/songname/content description", TIT3:"Subtitle/Description refinement", TKEY:"Initial key", TLAN:"Language(s)", TLEN:"Length", TMCL:"Musician credits list", TMED:"Media type", TMOO:"Mood", TOAL:"Original album/movie/show title", TOFN:"Original filename", TOLY:"Original lyricist(s)/text writer(s)", TOPE:"Original artist(s)/performer(s)", TOWN:"File owner/licensee", TPE1:"Lead performer(s)/Soloist(s)", TPE2:"Band/orchestra/accompaniment", TPE3:"Conductor/performer refinement", TPE4:"Interpreted, remixed, or otherwise modified by", TPOS:"Part of a set", TPRO:"Produced notice", TPUB:"Publisher", TRCK:"Track number/Position in set", TRSN:"Internet radio station name", TRSO:"Internet radio station owner", TSOA:"Album sort order", TSOP:"Performer sort order", TSOT:"Title sort order", TSRC:"ISRC (international standard recording code)", TSSE:"Software/Hardware and settings used for encoding", TSST:"Set subtitle", TXXX:"User defined text information frame", UFID:"Unique file identifier", USER:"Terms of use", USLT:"Unsynchronised lyric/text transcription", 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", WXXX:"User defined URL link frame" } }, USED_FRAMES:{ value:{ "Album/Movie/Show title":"album", "Band/orchestra/accompaniment":"album_artist", "Composer":"composer", "Content type":"genre", "Lead performer(s)/Soloist(s)":"artist", "Length":"length", "Part of a set":"set", "Publisher":"publisher", "Title/songname/content description":"title", "Track number/Position in set":"track", "Recording time":"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 = getSyncSafe(new Uint8Array(buf,pos,this.FRAME_SIZE_BYTES)); pos += this.FRAME_SIZE_BYTES; /* Get flags */ this.flags = new Uint8Array(buf,pos,this.FRAME_FLAGS_BYTES); pos += this.FRAME_FLAGS_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])+String.fromCharCode(this.id[3]); } 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: var dec = new TextDecoder("utf-16"); break; case 2: var dec = new TextDecoder("utf-16be"); break; case 3: var dec = new TextDecoder("utf-8"); break; default: throw new Error("Invalid encoding provided"); return ""; } return dec.decode(this.data).replace(/\0/g,''); } }