main
ts 19 lines 1.05 KB
Raw
1 export async function getId3Tags(url: string) {
2 const buf = await fetch(url, { headers: { Range: 'bytes=0-2047' } }).then(x => x.arrayBuffer())
3 const dv = new DataView(buf)
4 if (dv.getUint32(0) !== 0x49443303) return // ID3 identifier
5 const tags: Record<string, string> = {}
6 let index = 10
7 while (index < buf.byteLength) {
8 const frameId = String.fromCharCode(dv.getUint8(index++), dv.getUint8(index++), dv.getUint8(index++), dv.getUint8(index++))
9 if (frameId === '\0\0\0\0') break
10 const frameSize = dv.getUint32(index)
11 index += 6 // skip size + flags
12 const enc = !dv.getUint8(index++) ? 'ISO-8859-1' // 1 is for unicode
13 : { 239: 'utf-8', 255: 'utf-16le', 254: 'utf-16be' }[dv.getUint8(index)] // decode bom
14 tags[frameId] = new TextDecoder(enc).decode(buf.slice(index, index += frameSize - 1))
15 }
16 for (const [k, v] of Object.entries({ TALB: 'album', TIT2: 'title', TPE1: 'artist', TYER: 'year', TRCK: 'track' })) // easier access to main fields
17 tags[v] = tags[k]
18 return tags
19 }