Skip to content

subframe7536/node-taglib-sharp-extend

Repository files navigation

node-taglib-sharp-extend

Patch node-taglib-sharp with:

  • Some utils with corrected types, narrow exports
  • Read / Write support for file in buffer, detach createFromPath in File
  • Fresh dependencies and reduce Node dependencies
  • Provide Vite plugin for webapp

Backup your file!

Known issue:

Install

npm install node-taglib-sharp-extend
yarn add node-taglib-sharp-extend
pnpm add node-taglib-sharp-extend

Usage

import { createFileFromBuffer, createFileFromPath } from 'node-taglib-sharp-extend' const localFile = await createFileFromPath('./samples/test.mp3') const file = await createFileFromBuffer('test.mp3', buffer)

Utils

import { flushFile, getBufferFromFile, getFileFromBuffer, getPictureBase64, getPictureURL, parseMetadata, updatePicture, updateTag } from 'node-taglib-sharp-extend' let file = getFileFromBuffer('test.mp3', buffer) const { tag, property, pictures, quality, unwritableReason } = parseMetadata( file, arr => arr.flatMap(a => a.split('; ')).join('') ) updateTag(file, 'title', 'test') updatePicture(file, buffer) // if `File` is created from buffer and corrupt after flushing, throw `CorruptError` file = flushFile(file) console.log('file size:', getBufferFromFile(file).length) // browser only const [url, clean] = getPictureURL(pictures[0]) console.log(url) clean() const base64 = await getPictureBase64(pictures[0])

Types

export type IAudioTag<T extends string | string[] = string[]> = Partial<{ title: string artists: T album: string track: number trackTotal: number disk: number diskTotal: number year: number genres: T albumArtists: T composers: T comment: string lyrics: string }> export type IAudioProperty = { bitRate: number bitsPerSample: number sampleRate: number duration: number channels: number codecs: ICodec[] } export type AudioQualityType = 'HQ' | 'Hi-Res' | 'SQ' export type Metadata<T extends string | string[] = string[]> = { tag: IAudioTag<T> property: IAudioProperty quality: AudioQualityType pictures?: IParsedPicture[] }

more utils are documented by JSDoc

Run in browser

if you want to run it in webapp, you need to do some polyfills for node modules

total size: ~250KB (minified + gzip)

Polyfills

there is a built-in vite plugin for polyfill, and please ensure that vite-plugin-node-polyfills is installed

when dev, default includes: ['buffer', 'string_decoder', 'stream', 'crypto', 'fs', 'util']

when build, default includes: ['buffer', 'string_decoder'], other modules are manually transformed by the plugin

vite config:

import { polyfillTaglib } from 'node-taglib-sharp-extend/vite' import { defineConfig } from 'vite' export default defineConfig({ plugins: [ polyfillTaglib(/* options */), ], })

Manual Chunks

Built-in manualChunks config, split into 2 vendors: iconv and taglib

import { taglibManualChunksConfig } from 'node-taglib-sharp-extend/vite' import { defineConfig } from 'vite' export default defineConfig({ build: { rollupOptions: { output: { manualChunks: taglibManualChunksConfig } } } })

Web Worker support check

Matroska / WebM use node:crypto.randomFillSync() to generate random array, it is polyfilled to crypto.getRandomValues.

you can use built-in function to check if support in Web Worker:

import { checkWebWorkerSupport } from 'node-taglib-sharp-extend' // you can run in main thread or worker thread if (await checkWebWorkerSupport()) { // ... }

About

Read / Write music file metadata of various formats in Nodejs / Browser

Topics

Resources

License

Stars

Watchers

Forks