Patch node-taglib-sharp with:
- Some utils with corrected types, narrow exports
- Read / Write support for file in buffer, detach
createFromPath
inFile
- Fresh dependencies and reduce
Node
dependencies - Provide
Vite
plugin for webapp
Backup your file!
Known issue:
-
Seems be solved, see original PRm4a
maybe corrupt after writing, see original issue
npm install node-taglib-sharp-extend
yarn add node-taglib-sharp-extend
pnpm add node-taglib-sharp-extend
import { createFileFromBuffer, createFileFromPath } from 'node-taglib-sharp-extend'
const localFile = await createFileFromPath('./samples/test.mp3')
const file = await createFileFromBuffer('test.mp3', buffer)
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 flusing, 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])
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 Metadata<T extends string | string[] = string[]> = {
tag: IAudioTag<T>
property: IAudioProperty
quality: AudioQualityType
pictures?: IParsedPicture[]
}
more utils are documented by JSDoc
if you want to run it in webapp, you need to do some polyfills for node modules
total size: ~250KB (minified + gzip)
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 */),
],
})
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
}
}
}
})
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()) {
// ...
}