music-tag-native 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +207 -0
- package/browser.js +1 -0
- package/index.d.ts +300 -0
- package/index.js +576 -0
- package/package.json +103 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2020 N-API for Rust
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
# music-tag-native
|
|
2
|
+
|
|
3
|
+
A high-performance music metadata reader/writer for Node.js and browsers. Read and modify audio file tags (ID3, Vorbis, MP4, etc.) across multiple formats with native performance.
|
|
4
|
+
|
|
5
|
+
Powered by Rust's [`lofty`](https://github.com/Serial-ATA/lofty-rs) crate and [`napi-rs`](https://github.com/napi-rs/napi-rs) for native bindings, with WebAssembly support for browsers.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **Read/Write Metadata**: Title, artist, album, year, genre, track numbers, and more
|
|
10
|
+
- **Album Art Support**: Read and write embedded pictures with multiple formats
|
|
11
|
+
- **Audio Properties**: Bitrate, sample rate, bit depth, channels, duration
|
|
12
|
+
- **Audio Quality Classification**: Automatic HQ/SQ/HiRes detection
|
|
13
|
+
- **ReplayGain Support**: Read and write ReplayGain tags
|
|
14
|
+
- **Cross-Platform**: Native binaries for macOS, Linux, Windows, Android + WASM for browsers
|
|
15
|
+
- **Multiple Formats**: MP3, FLAC, M4A, WAV, OGG, and more
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
```sh
|
|
20
|
+
npm install music-tag-native
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
yarn add music-tag-native
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
```sh
|
|
28
|
+
pnpm add music-tag-native
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
```sh
|
|
32
|
+
bun add music-tag-native
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Usage
|
|
36
|
+
|
|
37
|
+
### Node.js
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
import { MusicTagger } from 'music-tag-native'
|
|
41
|
+
|
|
42
|
+
const tagger = new MusicTagger()
|
|
43
|
+
|
|
44
|
+
// Load from file path
|
|
45
|
+
tagger.loadPath('/path/to/audio/file.mp3')
|
|
46
|
+
|
|
47
|
+
// Read metadata
|
|
48
|
+
console.log(tagger.title)
|
|
49
|
+
console.log(tagger.artist)
|
|
50
|
+
console.log(tagger.album)
|
|
51
|
+
|
|
52
|
+
// Modify metadata
|
|
53
|
+
tagger.title = 'New Title'
|
|
54
|
+
tagger.artist = 'New Artist'
|
|
55
|
+
tagger.year = 2024
|
|
56
|
+
|
|
57
|
+
// Remove a tag (set to null)
|
|
58
|
+
tagger.albumArtist = null
|
|
59
|
+
|
|
60
|
+
// Save changes back to file
|
|
61
|
+
tagger.save()
|
|
62
|
+
|
|
63
|
+
// Clean up resources
|
|
64
|
+
tagger.dispose()
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Browser
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
import { MusicTagger } from 'music-tag-native'
|
|
71
|
+
|
|
72
|
+
const tagger = new MusicTagger()
|
|
73
|
+
|
|
74
|
+
// Load from buffer
|
|
75
|
+
const response = await fetch('/path/to/audio/file.mp3')
|
|
76
|
+
const arrayBuffer = await response.arrayBuffer()
|
|
77
|
+
const buffer = new Uint8Array(arrayBuffer)
|
|
78
|
+
|
|
79
|
+
tagger.loadBuffer(buffer)
|
|
80
|
+
|
|
81
|
+
// Read and modify metadata
|
|
82
|
+
console.log(tagger.title)
|
|
83
|
+
tagger.title = 'New Title'
|
|
84
|
+
|
|
85
|
+
// Get modified buffer
|
|
86
|
+
const modifiedBuffer = tagger.save()
|
|
87
|
+
|
|
88
|
+
// Display album art
|
|
89
|
+
const pictures = tagger.pictures
|
|
90
|
+
if (pictures.length > 0) {
|
|
91
|
+
const picture = pictures[0]
|
|
92
|
+
const blob = new Blob([picture.data], { type: picture.mimeType })
|
|
93
|
+
const url = URL.createObjectURL(blob)
|
|
94
|
+
document.querySelector('img').src = url
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
tagger.dispose()
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## API Reference
|
|
101
|
+
|
|
102
|
+
### MusicTagger
|
|
103
|
+
|
|
104
|
+
#### Loading Files
|
|
105
|
+
|
|
106
|
+
- `loadPath(path: string): void` - Load audio file from path (Node.js only)
|
|
107
|
+
- `loadBuffer(buffer: Uint8Array): void` - Load audio file from buffer
|
|
108
|
+
|
|
109
|
+
#### Saving Changes
|
|
110
|
+
|
|
111
|
+
- `save(): Uint8Array | undefined` - Save changes. Returns buffer in browser, undefined in Node.js (saves to original path)
|
|
112
|
+
|
|
113
|
+
#### Resource Management
|
|
114
|
+
|
|
115
|
+
- `dispose(): void` - Clean up resources. Always call when done with the tagger instance
|
|
116
|
+
|
|
117
|
+
#### Metadata Properties (Read/Write)
|
|
118
|
+
|
|
119
|
+
All properties can be read and written. Set to `null` to remove a tag.
|
|
120
|
+
|
|
121
|
+
- `title: string | null`
|
|
122
|
+
- `artist: string | null`
|
|
123
|
+
- `album: string | null`
|
|
124
|
+
- `albumArtist: string | null`
|
|
125
|
+
- `genre: string | null`
|
|
126
|
+
- `composer: string | null`
|
|
127
|
+
- `comment: string | null`
|
|
128
|
+
- `year: number | null`
|
|
129
|
+
- `trackNumber: number | null`
|
|
130
|
+
- `trackTotal: number | null`
|
|
131
|
+
- `discNumber: number | null`
|
|
132
|
+
- `discTotal: number | null`
|
|
133
|
+
|
|
134
|
+
#### Audio Properties (Read-Only)
|
|
135
|
+
|
|
136
|
+
- `duration: number` - Duration in seconds
|
|
137
|
+
- `overallBitrate: number` - Overall bitrate in kbps
|
|
138
|
+
- `audioBitrate: number` - Audio bitrate in kbps
|
|
139
|
+
- `sampleRate: number` - Sample rate in Hz
|
|
140
|
+
- `bitDepth: number` - Bit depth
|
|
141
|
+
- `channels: number` - Number of channels
|
|
142
|
+
- `audioQuality: 'HQ' | 'SQ' | 'HiRes' | null` - Audio quality classification
|
|
143
|
+
|
|
144
|
+
#### Album Art
|
|
145
|
+
|
|
146
|
+
- `pictures: MetaPicture[]` - Array of embedded pictures
|
|
147
|
+
- `setPictures(pictures: MetaPicture[]): void` - Replace all pictures
|
|
148
|
+
|
|
149
|
+
#### ReplayGain
|
|
150
|
+
|
|
151
|
+
- `replayGainTrackGain: number | null`
|
|
152
|
+
- `replayGainTrackPeak: number | null`
|
|
153
|
+
- `replayGainAlbumGain: number | null`
|
|
154
|
+
- `replayGainAlbumPeak: number | null`
|
|
155
|
+
|
|
156
|
+
### MetaPicture
|
|
157
|
+
|
|
158
|
+
Properties for album art and embedded images:
|
|
159
|
+
|
|
160
|
+
- `pictureType: PictureType` - Type of picture (e.g., 'CoverFront', 'CoverBack')
|
|
161
|
+
- `mimeType: string` - MIME type (e.g., 'image/jpeg', 'image/png')
|
|
162
|
+
- `description: string | null` - Optional description
|
|
163
|
+
- `data: Uint8Array` - Image data
|
|
164
|
+
|
|
165
|
+
#### PictureType Values
|
|
166
|
+
|
|
167
|
+
`'Other'`, `'Icon'`, `'OtherIcon'`, `'CoverFront'`, `'CoverBack'`, `'Leaflet'`, `'Media'`, `'LeadArtist'`, `'Artist'`, `'Conductor'`, `'Band'`, `'Composer'`, `'Lyricist'`, `'RecordingLocation'`, `'DuringRecording'`, `'DuringPerformance'`, `'ScreenCapture'`, `'BrightFish'`, `'Illustration'`, `'BandLogo'`, `'PublisherLogo'`, `'Undefined'`
|
|
168
|
+
|
|
169
|
+
## Platform Support
|
|
170
|
+
|
|
171
|
+
Native binaries are automatically installed for:
|
|
172
|
+
|
|
173
|
+
- macOS (x64, ARM64)
|
|
174
|
+
- Linux (x64, ARM64 - GNU and musl)
|
|
175
|
+
- Windows (x64, ia32, ARM64)
|
|
176
|
+
- Android (ARM64)
|
|
177
|
+
|
|
178
|
+
WebAssembly fallback is available for unsupported platforms and browsers.
|
|
179
|
+
|
|
180
|
+
## Development
|
|
181
|
+
|
|
182
|
+
```sh
|
|
183
|
+
# Install dependencies
|
|
184
|
+
pnpm install
|
|
185
|
+
|
|
186
|
+
# Build native addon for current platform
|
|
187
|
+
pnpm build
|
|
188
|
+
|
|
189
|
+
# Build WASM target
|
|
190
|
+
pnpm build:wasm
|
|
191
|
+
|
|
192
|
+
# Run tests
|
|
193
|
+
pnpm test
|
|
194
|
+
|
|
195
|
+
# Run playground
|
|
196
|
+
pnpm play
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
See [package.json](./package.json) for all available scripts.
|
|
200
|
+
|
|
201
|
+
## Type Definitions
|
|
202
|
+
|
|
203
|
+
Full TypeScript definitions are available in [index.d.ts](./index.d.ts).
|
|
204
|
+
|
|
205
|
+
## License
|
|
206
|
+
|
|
207
|
+
MIT
|
package/browser.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from 'music-tag-native-wasm32-wasi'
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
/* auto-generated by NAPI-RS */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
export declare class MetaPicture {
|
|
4
|
+
coverType: string
|
|
5
|
+
mimeType?: string
|
|
6
|
+
description?: string
|
|
7
|
+
data: Uint8Array
|
|
8
|
+
constructor(mime: string, data: Uint8Array, desc?: string | undefined | null)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export declare class MusicTagger {
|
|
12
|
+
/**
|
|
13
|
+
* @constructor
|
|
14
|
+
* Creates a new MusicTagger instance
|
|
15
|
+
*
|
|
16
|
+
* The instance starts in an uninitialized state. You must call either
|
|
17
|
+
* `loadBuffer()` (Browser) or `loadPath()` (Node.js) to load an audio
|
|
18
|
+
* file before using other methods.
|
|
19
|
+
*/
|
|
20
|
+
constructor()
|
|
21
|
+
/**
|
|
22
|
+
* Load music file from a byte buffer (dispose the old one before)
|
|
23
|
+
*
|
|
24
|
+
* @param buffer A Uint8Array containing the audio file data
|
|
25
|
+
*
|
|
26
|
+
* @throws If the buffer doesn't contain a valid audio file
|
|
27
|
+
* @throws If the file doesn't contain any metadata tags
|
|
28
|
+
*/
|
|
29
|
+
loadBuffer(buffer: Uint8Array): void
|
|
30
|
+
/**
|
|
31
|
+
* Load music file from a file path (dispose the old one before)
|
|
32
|
+
*
|
|
33
|
+
* @param path The file system path to the audio file
|
|
34
|
+
*
|
|
35
|
+
* @throws If the path doesn't exist or isn't accessible
|
|
36
|
+
* @throws If the file doesn't contain a valid audio format
|
|
37
|
+
* @throws If the file doesn't contain any metadata tags
|
|
38
|
+
* @throws If runs in WebAssembly environments (due to file system restrictions).
|
|
39
|
+
*/
|
|
40
|
+
loadPath(path: string): void
|
|
41
|
+
/**
|
|
42
|
+
* Dispose of the currently loaded file
|
|
43
|
+
*
|
|
44
|
+
* Releases all resources associated with the loaded audio file.
|
|
45
|
+
* After calling this method, the instance returns to an uninitialized state.
|
|
46
|
+
*
|
|
47
|
+
* @note Any unsaved changes will be lost when disposing.
|
|
48
|
+
*/
|
|
49
|
+
dispose(): void
|
|
50
|
+
/**
|
|
51
|
+
* Check if the current file is disposed. Use this method to verify
|
|
52
|
+
* if the instance is ready for operations before calling other methods.
|
|
53
|
+
*
|
|
54
|
+
* @returns `true` if no file is currently loaded, `false` otherwise
|
|
55
|
+
*/
|
|
56
|
+
isDisposed(): boolean
|
|
57
|
+
/**
|
|
58
|
+
* Save metadata changes back to the internal buffer
|
|
59
|
+
*
|
|
60
|
+
* @throws If no file or buffer loaded
|
|
61
|
+
* @throws If saving fails due to file format constraints
|
|
62
|
+
*/
|
|
63
|
+
save(): void
|
|
64
|
+
/**
|
|
65
|
+
* Current audio file buffer as a `Uint8Array`
|
|
66
|
+
*
|
|
67
|
+
* @throws If no file or buffer loaded
|
|
68
|
+
*
|
|
69
|
+
* @note For files loaded via `loadBuffer()`, call `save()` first to ensure
|
|
70
|
+
* metadata changes are applied. For files loaded via `loadPath()`, this
|
|
71
|
+
* returns an empty buffer.
|
|
72
|
+
*/
|
|
73
|
+
get buffer(): Uint8Array
|
|
74
|
+
/**
|
|
75
|
+
* Audio quality classification ("HQ", "SQ", or "HiRes")
|
|
76
|
+
*
|
|
77
|
+
* @throws If no file or buffer loaded
|
|
78
|
+
*
|
|
79
|
+
* Quality is determined based on file format, sample rate, and bit depth:
|
|
80
|
+
* - HQ: Lossy formats (MP3, AAC, etc.)
|
|
81
|
+
* - SQ: Lossless formats at CD quality (44.1kHz, 16-bit)
|
|
82
|
+
* - HiRes: Lossless formats exceeding CD quality (>44.1kHz, >=16-bit)
|
|
83
|
+
*/
|
|
84
|
+
get quality(): string
|
|
85
|
+
/**
|
|
86
|
+
* Audio bit depth in bits, or `null` if not available
|
|
87
|
+
*
|
|
88
|
+
* @throws If no file or buffer loaded
|
|
89
|
+
*
|
|
90
|
+
* Common values: 16 (CD quality), 24 (Hi-Res), 32 (studio quality)
|
|
91
|
+
*/
|
|
92
|
+
get bitDepth(): number | null
|
|
93
|
+
/**
|
|
94
|
+
* Audio bit rate in kbps, or `null` if not available
|
|
95
|
+
*
|
|
96
|
+
* @throws If no file or buffer loaded
|
|
97
|
+
*
|
|
98
|
+
* @note If the audio properties don't provide a bitrate, this method calculates
|
|
99
|
+
* an approximate bitrate based on file size and duration, including metadata.
|
|
100
|
+
* The calculated bitrate is constrained between MIN_BITRATE and MAX_BITRATE.
|
|
101
|
+
*/
|
|
102
|
+
get bitRate(): number | null
|
|
103
|
+
/**
|
|
104
|
+
* Audio sample rate in Hz, or `null` if not available
|
|
105
|
+
*
|
|
106
|
+
* @throws If no file or buffer loaded
|
|
107
|
+
*
|
|
108
|
+
* Common values: 44100 (CD), 48000 (DVD), 96000, 192000 (Hi-Res)
|
|
109
|
+
*/
|
|
110
|
+
get sampleRate(): number | null
|
|
111
|
+
/**
|
|
112
|
+
* Number of audio channels, or `null` if not available
|
|
113
|
+
*
|
|
114
|
+
* @throws If no file or buffer loaded
|
|
115
|
+
*
|
|
116
|
+
* Common values: 1 (mono), 2 (stereo), 6 (5.1 surround)
|
|
117
|
+
* Common values: 1 (mono), 2 (stereo), 6 (5.1 surround), 8 (7.1 surround)
|
|
118
|
+
*/
|
|
119
|
+
get channels(): number | null
|
|
120
|
+
/**
|
|
121
|
+
* Audio duration in seconds, or `null` if not available
|
|
122
|
+
*
|
|
123
|
+
* @throws If no file or buffer loaded
|
|
124
|
+
*/
|
|
125
|
+
get duration(): number
|
|
126
|
+
/**
|
|
127
|
+
* File's metadata tag type, or `null` if not recognized
|
|
128
|
+
*
|
|
129
|
+
* Supported tag types: "ID3V1", "ID3V2", "APE", "VORBIS", "MP4", "AIFF", "RIFF"
|
|
130
|
+
*
|
|
131
|
+
* @throws If no file or buffer loaded
|
|
132
|
+
*/
|
|
133
|
+
get tagType(): string | null
|
|
134
|
+
/**
|
|
135
|
+
* Title, or `null` if not set
|
|
136
|
+
*
|
|
137
|
+
* @throws If no file or buffer loaded
|
|
138
|
+
*/
|
|
139
|
+
get title(): string | null
|
|
140
|
+
set title(title: string | null)
|
|
141
|
+
/**
|
|
142
|
+
* Artist, or `null` if not set
|
|
143
|
+
*
|
|
144
|
+
* @throws If no file or buffer loaded
|
|
145
|
+
*/
|
|
146
|
+
get artist(): string | null
|
|
147
|
+
set artist(artist: string | null)
|
|
148
|
+
/**
|
|
149
|
+
* Album, or `null` if not set
|
|
150
|
+
*
|
|
151
|
+
* @throws If no file or buffer loaded
|
|
152
|
+
*/
|
|
153
|
+
get album(): string | null
|
|
154
|
+
set album(album: string | null)
|
|
155
|
+
/**
|
|
156
|
+
* Year, or `null` if not set
|
|
157
|
+
*
|
|
158
|
+
* @throws If no file or buffer loaded
|
|
159
|
+
*/
|
|
160
|
+
get year(): number | null
|
|
161
|
+
set year(year: number | null)
|
|
162
|
+
/**
|
|
163
|
+
* Genre, or `null` if not set
|
|
164
|
+
*
|
|
165
|
+
* @throws If no file or buffer loaded
|
|
166
|
+
*/
|
|
167
|
+
get genre(): string | null
|
|
168
|
+
set genre(genre: string | null)
|
|
169
|
+
/**
|
|
170
|
+
* Track number, or `null` if not set
|
|
171
|
+
*
|
|
172
|
+
* @throws If no file or buffer loaded
|
|
173
|
+
*/
|
|
174
|
+
get trackNumber(): number | null
|
|
175
|
+
set trackNumber(trackNumber: number | null)
|
|
176
|
+
/**
|
|
177
|
+
* Disc number, or `null` if not set
|
|
178
|
+
*
|
|
179
|
+
* @throws If no file or buffer loaded
|
|
180
|
+
*/
|
|
181
|
+
get discNumber(): number | null
|
|
182
|
+
set discNumber(discNumber: number | null)
|
|
183
|
+
/**
|
|
184
|
+
* Total number of tracks in the album, or `null` if not set
|
|
185
|
+
*
|
|
186
|
+
* @throws If no file or buffer loaded
|
|
187
|
+
*/
|
|
188
|
+
get trackTotal(): number | null
|
|
189
|
+
set trackTotal(trackTotal: number | null)
|
|
190
|
+
/**
|
|
191
|
+
* Total number of discs in the album, or `null` if not set
|
|
192
|
+
*
|
|
193
|
+
* @throws If no file or buffer loaded
|
|
194
|
+
*/
|
|
195
|
+
get discsTotal(): number | null
|
|
196
|
+
set discsTotal(discsTotal: number | null)
|
|
197
|
+
/**
|
|
198
|
+
* Comment, or `null` if not set
|
|
199
|
+
*
|
|
200
|
+
* @throws If no file or buffer loaded
|
|
201
|
+
*/
|
|
202
|
+
get comment(): string | null
|
|
203
|
+
set comment(comment: string | null)
|
|
204
|
+
/**
|
|
205
|
+
* Album artist, or `null` if not set
|
|
206
|
+
*
|
|
207
|
+
* @throws If no file or buffer loaded
|
|
208
|
+
*
|
|
209
|
+
* @note Album artist differs from track artist and represents the primary artist for the entire album.
|
|
210
|
+
*/
|
|
211
|
+
get albumArtist(): string | null
|
|
212
|
+
set albumArtist(albumArtist: string | null)
|
|
213
|
+
/**
|
|
214
|
+
* Composer, or `null` if not set
|
|
215
|
+
*
|
|
216
|
+
* @throws If no file or buffer loaded
|
|
217
|
+
*/
|
|
218
|
+
get composer(): string | null
|
|
219
|
+
set composer(composer: string | null)
|
|
220
|
+
/**
|
|
221
|
+
* Conductor, or `null` if not set
|
|
222
|
+
*
|
|
223
|
+
* @throws If no file or buffer loaded
|
|
224
|
+
*/
|
|
225
|
+
get conductor(): string | null
|
|
226
|
+
set conductor(conductor: string | null)
|
|
227
|
+
/**
|
|
228
|
+
* Lyricist, or `null` if not set
|
|
229
|
+
*
|
|
230
|
+
* @throws If no file or buffer loaded
|
|
231
|
+
*/
|
|
232
|
+
get lyricist(): string | null
|
|
233
|
+
set lyricist(lyricist: string | null)
|
|
234
|
+
/**
|
|
235
|
+
* Publisher, or `null` if not set
|
|
236
|
+
*
|
|
237
|
+
* @throws If no file or buffer loaded
|
|
238
|
+
*/
|
|
239
|
+
get publisher(): string | null
|
|
240
|
+
set publisher(publisher: string | null)
|
|
241
|
+
/**
|
|
242
|
+
* Lyrics, or `null` if not set
|
|
243
|
+
*
|
|
244
|
+
* @throws If no file or buffer loaded
|
|
245
|
+
*/
|
|
246
|
+
get lyrics(): string | null
|
|
247
|
+
set lyrics(lyrics: string | null)
|
|
248
|
+
/**
|
|
249
|
+
* Copyright information, or `null` if not set
|
|
250
|
+
*
|
|
251
|
+
* @throws If no file or buffer loaded
|
|
252
|
+
*/
|
|
253
|
+
get copyright(): string | null
|
|
254
|
+
set copyright(copyright: string | null)
|
|
255
|
+
/**
|
|
256
|
+
* Track replay gain in dB, or `null` if not set
|
|
257
|
+
*
|
|
258
|
+
* @throws If no file or buffer loaded
|
|
259
|
+
*
|
|
260
|
+
* @note Replay gain is used to normalize playback volume across different tracks.
|
|
261
|
+
*/
|
|
262
|
+
get trackReplayGain(): number | null
|
|
263
|
+
set trackReplayGain(trackReplayGain: number | null)
|
|
264
|
+
/**
|
|
265
|
+
* Track replay peak value, or `null` if not set
|
|
266
|
+
*
|
|
267
|
+
* @throws If no file or buffer loaded
|
|
268
|
+
*
|
|
269
|
+
* @note Replay peak represents the maximum amplitude level in the track.
|
|
270
|
+
*/
|
|
271
|
+
get trackReplayPeak(): number | null
|
|
272
|
+
set trackReplayPeak(trackReplayPeak: number | null)
|
|
273
|
+
/**
|
|
274
|
+
* Album replay gain in dB, or `null` if not set
|
|
275
|
+
*
|
|
276
|
+
* @throws If no file or buffer loaded
|
|
277
|
+
*
|
|
278
|
+
* @note Album replay gain normalizes playback volume across different albums.
|
|
279
|
+
*/
|
|
280
|
+
get albumReplayGain(): number | null
|
|
281
|
+
set albumReplayGain(albumReplayGain: number | null)
|
|
282
|
+
/**
|
|
283
|
+
* Album replay peak value, or `null` if not set
|
|
284
|
+
*
|
|
285
|
+
* @throws If no file or buffer loaded
|
|
286
|
+
*
|
|
287
|
+
* @note Album replay peak represents the maximum amplitude level in the album.
|
|
288
|
+
*/
|
|
289
|
+
get albumReplayPeak(): number | null
|
|
290
|
+
set albumReplayPeak(albumReplayPeak: number | null)
|
|
291
|
+
/**
|
|
292
|
+
* Embedded pictures/album art list, or `null` if no picture is embedded
|
|
293
|
+
*
|
|
294
|
+
* @throws If no file or buffer loaded
|
|
295
|
+
*
|
|
296
|
+
* @note Returns all embedded pictures including album art, artist photos, etc.
|
|
297
|
+
*/
|
|
298
|
+
get pictures(): Array<MetaPicture> | null
|
|
299
|
+
set pictures(pictures: Array<MetaPicture> | null)
|
|
300
|
+
}
|
package/index.js
ADDED
|
@@ -0,0 +1,576 @@
|
|
|
1
|
+
// prettier-ignore
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
// @ts-nocheck
|
|
4
|
+
/* auto-generated by NAPI-RS */
|
|
5
|
+
|
|
6
|
+
const { readFileSync } = require('node:fs')
|
|
7
|
+
let nativeBinding = null
|
|
8
|
+
const loadErrors = []
|
|
9
|
+
|
|
10
|
+
const isMusl = () => {
|
|
11
|
+
let musl = false
|
|
12
|
+
if (process.platform === 'linux') {
|
|
13
|
+
musl = isMuslFromFilesystem()
|
|
14
|
+
if (musl === null) {
|
|
15
|
+
musl = isMuslFromReport()
|
|
16
|
+
}
|
|
17
|
+
if (musl === null) {
|
|
18
|
+
musl = isMuslFromChildProcess()
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return musl
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const isFileMusl = (f) => f.includes('libc.musl-') || f.includes('ld-musl-')
|
|
25
|
+
|
|
26
|
+
const isMuslFromFilesystem = () => {
|
|
27
|
+
try {
|
|
28
|
+
return readFileSync('/usr/bin/ldd', 'utf-8').includes('musl')
|
|
29
|
+
} catch {
|
|
30
|
+
return null
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const isMuslFromReport = () => {
|
|
35
|
+
let report = null
|
|
36
|
+
if (typeof process.report?.getReport === 'function') {
|
|
37
|
+
process.report.excludeNetwork = true
|
|
38
|
+
report = process.report.getReport()
|
|
39
|
+
}
|
|
40
|
+
if (!report) {
|
|
41
|
+
return null
|
|
42
|
+
}
|
|
43
|
+
if (report.header && report.header.glibcVersionRuntime) {
|
|
44
|
+
return false
|
|
45
|
+
}
|
|
46
|
+
if (Array.isArray(report.sharedObjects)) {
|
|
47
|
+
if (report.sharedObjects.some(isFileMusl)) {
|
|
48
|
+
return true
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return false
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const isMuslFromChildProcess = () => {
|
|
55
|
+
try {
|
|
56
|
+
return require('child_process').execSync('ldd --version', { encoding: 'utf8' }).includes('musl')
|
|
57
|
+
} catch (e) {
|
|
58
|
+
// If we reach this case, we don't know if the system is musl or not, so is better to just fallback to false
|
|
59
|
+
return false
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function requireNative() {
|
|
64
|
+
if (process.env.NAPI_RS_NATIVE_LIBRARY_PATH) {
|
|
65
|
+
try {
|
|
66
|
+
return require(process.env.NAPI_RS_NATIVE_LIBRARY_PATH);
|
|
67
|
+
} catch (err) {
|
|
68
|
+
loadErrors.push(err)
|
|
69
|
+
}
|
|
70
|
+
} else if (process.platform === 'android') {
|
|
71
|
+
if (process.arch === 'arm64') {
|
|
72
|
+
try {
|
|
73
|
+
return require('./music-tag-native.android-arm64.node')
|
|
74
|
+
} catch (e) {
|
|
75
|
+
loadErrors.push(e)
|
|
76
|
+
}
|
|
77
|
+
try {
|
|
78
|
+
const binding = require('music-tag-native-android-arm64')
|
|
79
|
+
const bindingPackageVersion = require('music-tag-native-android-arm64/package.json').version
|
|
80
|
+
if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
81
|
+
throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
82
|
+
}
|
|
83
|
+
return binding
|
|
84
|
+
} catch (e) {
|
|
85
|
+
loadErrors.push(e)
|
|
86
|
+
}
|
|
87
|
+
} else if (process.arch === 'arm') {
|
|
88
|
+
try {
|
|
89
|
+
return require('./music-tag-native.android-arm-eabi.node')
|
|
90
|
+
} catch (e) {
|
|
91
|
+
loadErrors.push(e)
|
|
92
|
+
}
|
|
93
|
+
try {
|
|
94
|
+
const binding = require('music-tag-native-android-arm-eabi')
|
|
95
|
+
const bindingPackageVersion = require('music-tag-native-android-arm-eabi/package.json').version
|
|
96
|
+
if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
97
|
+
throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
98
|
+
}
|
|
99
|
+
return binding
|
|
100
|
+
} catch (e) {
|
|
101
|
+
loadErrors.push(e)
|
|
102
|
+
}
|
|
103
|
+
} else {
|
|
104
|
+
loadErrors.push(new Error(`Unsupported architecture on Android ${process.arch}`))
|
|
105
|
+
}
|
|
106
|
+
} else if (process.platform === 'win32') {
|
|
107
|
+
if (process.arch === 'x64') {
|
|
108
|
+
if (process.config?.variables?.shlib_suffix === 'dll.a' || process.config?.variables?.node_target_type === 'shared_library') {
|
|
109
|
+
try {
|
|
110
|
+
return require('./music-tag-native.win32-x64-gnu.node')
|
|
111
|
+
} catch (e) {
|
|
112
|
+
loadErrors.push(e)
|
|
113
|
+
}
|
|
114
|
+
try {
|
|
115
|
+
const binding = require('music-tag-native-win32-x64-gnu')
|
|
116
|
+
const bindingPackageVersion = require('music-tag-native-win32-x64-gnu/package.json').version
|
|
117
|
+
if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
118
|
+
throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
119
|
+
}
|
|
120
|
+
return binding
|
|
121
|
+
} catch (e) {
|
|
122
|
+
loadErrors.push(e)
|
|
123
|
+
}
|
|
124
|
+
} else {
|
|
125
|
+
try {
|
|
126
|
+
return require('./music-tag-native.win32-x64-msvc.node')
|
|
127
|
+
} catch (e) {
|
|
128
|
+
loadErrors.push(e)
|
|
129
|
+
}
|
|
130
|
+
try {
|
|
131
|
+
const binding = require('music-tag-native-win32-x64-msvc')
|
|
132
|
+
const bindingPackageVersion = require('music-tag-native-win32-x64-msvc/package.json').version
|
|
133
|
+
if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
134
|
+
throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
135
|
+
}
|
|
136
|
+
return binding
|
|
137
|
+
} catch (e) {
|
|
138
|
+
loadErrors.push(e)
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
} else if (process.arch === 'ia32') {
|
|
142
|
+
try {
|
|
143
|
+
return require('./music-tag-native.win32-ia32-msvc.node')
|
|
144
|
+
} catch (e) {
|
|
145
|
+
loadErrors.push(e)
|
|
146
|
+
}
|
|
147
|
+
try {
|
|
148
|
+
const binding = require('music-tag-native-win32-ia32-msvc')
|
|
149
|
+
const bindingPackageVersion = require('music-tag-native-win32-ia32-msvc/package.json').version
|
|
150
|
+
if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
151
|
+
throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
152
|
+
}
|
|
153
|
+
return binding
|
|
154
|
+
} catch (e) {
|
|
155
|
+
loadErrors.push(e)
|
|
156
|
+
}
|
|
157
|
+
} else if (process.arch === 'arm64') {
|
|
158
|
+
try {
|
|
159
|
+
return require('./music-tag-native.win32-arm64-msvc.node')
|
|
160
|
+
} catch (e) {
|
|
161
|
+
loadErrors.push(e)
|
|
162
|
+
}
|
|
163
|
+
try {
|
|
164
|
+
const binding = require('music-tag-native-win32-arm64-msvc')
|
|
165
|
+
const bindingPackageVersion = require('music-tag-native-win32-arm64-msvc/package.json').version
|
|
166
|
+
if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
167
|
+
throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
168
|
+
}
|
|
169
|
+
return binding
|
|
170
|
+
} catch (e) {
|
|
171
|
+
loadErrors.push(e)
|
|
172
|
+
}
|
|
173
|
+
} else {
|
|
174
|
+
loadErrors.push(new Error(`Unsupported architecture on Windows: ${process.arch}`))
|
|
175
|
+
}
|
|
176
|
+
} else if (process.platform === 'darwin') {
|
|
177
|
+
try {
|
|
178
|
+
return require('./music-tag-native.darwin-universal.node')
|
|
179
|
+
} catch (e) {
|
|
180
|
+
loadErrors.push(e)
|
|
181
|
+
}
|
|
182
|
+
try {
|
|
183
|
+
const binding = require('music-tag-native-darwin-universal')
|
|
184
|
+
const bindingPackageVersion = require('music-tag-native-darwin-universal/package.json').version
|
|
185
|
+
if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
186
|
+
throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
187
|
+
}
|
|
188
|
+
return binding
|
|
189
|
+
} catch (e) {
|
|
190
|
+
loadErrors.push(e)
|
|
191
|
+
}
|
|
192
|
+
if (process.arch === 'x64') {
|
|
193
|
+
try {
|
|
194
|
+
return require('./music-tag-native.darwin-x64.node')
|
|
195
|
+
} catch (e) {
|
|
196
|
+
loadErrors.push(e)
|
|
197
|
+
}
|
|
198
|
+
try {
|
|
199
|
+
const binding = require('music-tag-native-darwin-x64')
|
|
200
|
+
const bindingPackageVersion = require('music-tag-native-darwin-x64/package.json').version
|
|
201
|
+
if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
202
|
+
throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
203
|
+
}
|
|
204
|
+
return binding
|
|
205
|
+
} catch (e) {
|
|
206
|
+
loadErrors.push(e)
|
|
207
|
+
}
|
|
208
|
+
} else if (process.arch === 'arm64') {
|
|
209
|
+
try {
|
|
210
|
+
return require('./music-tag-native.darwin-arm64.node')
|
|
211
|
+
} catch (e) {
|
|
212
|
+
loadErrors.push(e)
|
|
213
|
+
}
|
|
214
|
+
try {
|
|
215
|
+
const binding = require('music-tag-native-darwin-arm64')
|
|
216
|
+
const bindingPackageVersion = require('music-tag-native-darwin-arm64/package.json').version
|
|
217
|
+
if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
218
|
+
throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
219
|
+
}
|
|
220
|
+
return binding
|
|
221
|
+
} catch (e) {
|
|
222
|
+
loadErrors.push(e)
|
|
223
|
+
}
|
|
224
|
+
} else {
|
|
225
|
+
loadErrors.push(new Error(`Unsupported architecture on macOS: ${process.arch}`))
|
|
226
|
+
}
|
|
227
|
+
} else if (process.platform === 'freebsd') {
|
|
228
|
+
if (process.arch === 'x64') {
|
|
229
|
+
try {
|
|
230
|
+
return require('./music-tag-native.freebsd-x64.node')
|
|
231
|
+
} catch (e) {
|
|
232
|
+
loadErrors.push(e)
|
|
233
|
+
}
|
|
234
|
+
try {
|
|
235
|
+
const binding = require('music-tag-native-freebsd-x64')
|
|
236
|
+
const bindingPackageVersion = require('music-tag-native-freebsd-x64/package.json').version
|
|
237
|
+
if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
238
|
+
throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
239
|
+
}
|
|
240
|
+
return binding
|
|
241
|
+
} catch (e) {
|
|
242
|
+
loadErrors.push(e)
|
|
243
|
+
}
|
|
244
|
+
} else if (process.arch === 'arm64') {
|
|
245
|
+
try {
|
|
246
|
+
return require('./music-tag-native.freebsd-arm64.node')
|
|
247
|
+
} catch (e) {
|
|
248
|
+
loadErrors.push(e)
|
|
249
|
+
}
|
|
250
|
+
try {
|
|
251
|
+
const binding = require('music-tag-native-freebsd-arm64')
|
|
252
|
+
const bindingPackageVersion = require('music-tag-native-freebsd-arm64/package.json').version
|
|
253
|
+
if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
254
|
+
throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
255
|
+
}
|
|
256
|
+
return binding
|
|
257
|
+
} catch (e) {
|
|
258
|
+
loadErrors.push(e)
|
|
259
|
+
}
|
|
260
|
+
} else {
|
|
261
|
+
loadErrors.push(new Error(`Unsupported architecture on FreeBSD: ${process.arch}`))
|
|
262
|
+
}
|
|
263
|
+
} else if (process.platform === 'linux') {
|
|
264
|
+
if (process.arch === 'x64') {
|
|
265
|
+
if (isMusl()) {
|
|
266
|
+
try {
|
|
267
|
+
return require('./music-tag-native.linux-x64-musl.node')
|
|
268
|
+
} catch (e) {
|
|
269
|
+
loadErrors.push(e)
|
|
270
|
+
}
|
|
271
|
+
try {
|
|
272
|
+
const binding = require('music-tag-native-linux-x64-musl')
|
|
273
|
+
const bindingPackageVersion = require('music-tag-native-linux-x64-musl/package.json').version
|
|
274
|
+
if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
275
|
+
throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
276
|
+
}
|
|
277
|
+
return binding
|
|
278
|
+
} catch (e) {
|
|
279
|
+
loadErrors.push(e)
|
|
280
|
+
}
|
|
281
|
+
} else {
|
|
282
|
+
try {
|
|
283
|
+
return require('./music-tag-native.linux-x64-gnu.node')
|
|
284
|
+
} catch (e) {
|
|
285
|
+
loadErrors.push(e)
|
|
286
|
+
}
|
|
287
|
+
try {
|
|
288
|
+
const binding = require('music-tag-native-linux-x64-gnu')
|
|
289
|
+
const bindingPackageVersion = require('music-tag-native-linux-x64-gnu/package.json').version
|
|
290
|
+
if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
291
|
+
throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
292
|
+
}
|
|
293
|
+
return binding
|
|
294
|
+
} catch (e) {
|
|
295
|
+
loadErrors.push(e)
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
} else if (process.arch === 'arm64') {
|
|
299
|
+
if (isMusl()) {
|
|
300
|
+
try {
|
|
301
|
+
return require('./music-tag-native.linux-arm64-musl.node')
|
|
302
|
+
} catch (e) {
|
|
303
|
+
loadErrors.push(e)
|
|
304
|
+
}
|
|
305
|
+
try {
|
|
306
|
+
const binding = require('music-tag-native-linux-arm64-musl')
|
|
307
|
+
const bindingPackageVersion = require('music-tag-native-linux-arm64-musl/package.json').version
|
|
308
|
+
if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
309
|
+
throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
310
|
+
}
|
|
311
|
+
return binding
|
|
312
|
+
} catch (e) {
|
|
313
|
+
loadErrors.push(e)
|
|
314
|
+
}
|
|
315
|
+
} else {
|
|
316
|
+
try {
|
|
317
|
+
return require('./music-tag-native.linux-arm64-gnu.node')
|
|
318
|
+
} catch (e) {
|
|
319
|
+
loadErrors.push(e)
|
|
320
|
+
}
|
|
321
|
+
try {
|
|
322
|
+
const binding = require('music-tag-native-linux-arm64-gnu')
|
|
323
|
+
const bindingPackageVersion = require('music-tag-native-linux-arm64-gnu/package.json').version
|
|
324
|
+
if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
325
|
+
throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
326
|
+
}
|
|
327
|
+
return binding
|
|
328
|
+
} catch (e) {
|
|
329
|
+
loadErrors.push(e)
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
} else if (process.arch === 'arm') {
|
|
333
|
+
if (isMusl()) {
|
|
334
|
+
try {
|
|
335
|
+
return require('./music-tag-native.linux-arm-musleabihf.node')
|
|
336
|
+
} catch (e) {
|
|
337
|
+
loadErrors.push(e)
|
|
338
|
+
}
|
|
339
|
+
try {
|
|
340
|
+
const binding = require('music-tag-native-linux-arm-musleabihf')
|
|
341
|
+
const bindingPackageVersion = require('music-tag-native-linux-arm-musleabihf/package.json').version
|
|
342
|
+
if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
343
|
+
throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
344
|
+
}
|
|
345
|
+
return binding
|
|
346
|
+
} catch (e) {
|
|
347
|
+
loadErrors.push(e)
|
|
348
|
+
}
|
|
349
|
+
} else {
|
|
350
|
+
try {
|
|
351
|
+
return require('./music-tag-native.linux-arm-gnueabihf.node')
|
|
352
|
+
} catch (e) {
|
|
353
|
+
loadErrors.push(e)
|
|
354
|
+
}
|
|
355
|
+
try {
|
|
356
|
+
const binding = require('music-tag-native-linux-arm-gnueabihf')
|
|
357
|
+
const bindingPackageVersion = require('music-tag-native-linux-arm-gnueabihf/package.json').version
|
|
358
|
+
if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
359
|
+
throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
360
|
+
}
|
|
361
|
+
return binding
|
|
362
|
+
} catch (e) {
|
|
363
|
+
loadErrors.push(e)
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
} else if (process.arch === 'loong64') {
|
|
367
|
+
if (isMusl()) {
|
|
368
|
+
try {
|
|
369
|
+
return require('./music-tag-native.linux-loong64-musl.node')
|
|
370
|
+
} catch (e) {
|
|
371
|
+
loadErrors.push(e)
|
|
372
|
+
}
|
|
373
|
+
try {
|
|
374
|
+
const binding = require('music-tag-native-linux-loong64-musl')
|
|
375
|
+
const bindingPackageVersion = require('music-tag-native-linux-loong64-musl/package.json').version
|
|
376
|
+
if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
377
|
+
throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
378
|
+
}
|
|
379
|
+
return binding
|
|
380
|
+
} catch (e) {
|
|
381
|
+
loadErrors.push(e)
|
|
382
|
+
}
|
|
383
|
+
} else {
|
|
384
|
+
try {
|
|
385
|
+
return require('./music-tag-native.linux-loong64-gnu.node')
|
|
386
|
+
} catch (e) {
|
|
387
|
+
loadErrors.push(e)
|
|
388
|
+
}
|
|
389
|
+
try {
|
|
390
|
+
const binding = require('music-tag-native-linux-loong64-gnu')
|
|
391
|
+
const bindingPackageVersion = require('music-tag-native-linux-loong64-gnu/package.json').version
|
|
392
|
+
if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
393
|
+
throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
394
|
+
}
|
|
395
|
+
return binding
|
|
396
|
+
} catch (e) {
|
|
397
|
+
loadErrors.push(e)
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
} else if (process.arch === 'riscv64') {
|
|
401
|
+
if (isMusl()) {
|
|
402
|
+
try {
|
|
403
|
+
return require('./music-tag-native.linux-riscv64-musl.node')
|
|
404
|
+
} catch (e) {
|
|
405
|
+
loadErrors.push(e)
|
|
406
|
+
}
|
|
407
|
+
try {
|
|
408
|
+
const binding = require('music-tag-native-linux-riscv64-musl')
|
|
409
|
+
const bindingPackageVersion = require('music-tag-native-linux-riscv64-musl/package.json').version
|
|
410
|
+
if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
411
|
+
throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
412
|
+
}
|
|
413
|
+
return binding
|
|
414
|
+
} catch (e) {
|
|
415
|
+
loadErrors.push(e)
|
|
416
|
+
}
|
|
417
|
+
} else {
|
|
418
|
+
try {
|
|
419
|
+
return require('./music-tag-native.linux-riscv64-gnu.node')
|
|
420
|
+
} catch (e) {
|
|
421
|
+
loadErrors.push(e)
|
|
422
|
+
}
|
|
423
|
+
try {
|
|
424
|
+
const binding = require('music-tag-native-linux-riscv64-gnu')
|
|
425
|
+
const bindingPackageVersion = require('music-tag-native-linux-riscv64-gnu/package.json').version
|
|
426
|
+
if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
427
|
+
throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
428
|
+
}
|
|
429
|
+
return binding
|
|
430
|
+
} catch (e) {
|
|
431
|
+
loadErrors.push(e)
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
} else if (process.arch === 'ppc64') {
|
|
435
|
+
try {
|
|
436
|
+
return require('./music-tag-native.linux-ppc64-gnu.node')
|
|
437
|
+
} catch (e) {
|
|
438
|
+
loadErrors.push(e)
|
|
439
|
+
}
|
|
440
|
+
try {
|
|
441
|
+
const binding = require('music-tag-native-linux-ppc64-gnu')
|
|
442
|
+
const bindingPackageVersion = require('music-tag-native-linux-ppc64-gnu/package.json').version
|
|
443
|
+
if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
444
|
+
throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
445
|
+
}
|
|
446
|
+
return binding
|
|
447
|
+
} catch (e) {
|
|
448
|
+
loadErrors.push(e)
|
|
449
|
+
}
|
|
450
|
+
} else if (process.arch === 's390x') {
|
|
451
|
+
try {
|
|
452
|
+
return require('./music-tag-native.linux-s390x-gnu.node')
|
|
453
|
+
} catch (e) {
|
|
454
|
+
loadErrors.push(e)
|
|
455
|
+
}
|
|
456
|
+
try {
|
|
457
|
+
const binding = require('music-tag-native-linux-s390x-gnu')
|
|
458
|
+
const bindingPackageVersion = require('music-tag-native-linux-s390x-gnu/package.json').version
|
|
459
|
+
if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
460
|
+
throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
461
|
+
}
|
|
462
|
+
return binding
|
|
463
|
+
} catch (e) {
|
|
464
|
+
loadErrors.push(e)
|
|
465
|
+
}
|
|
466
|
+
} else {
|
|
467
|
+
loadErrors.push(new Error(`Unsupported architecture on Linux: ${process.arch}`))
|
|
468
|
+
}
|
|
469
|
+
} else if (process.platform === 'openharmony') {
|
|
470
|
+
if (process.arch === 'arm64') {
|
|
471
|
+
try {
|
|
472
|
+
return require('./music-tag-native.openharmony-arm64.node')
|
|
473
|
+
} catch (e) {
|
|
474
|
+
loadErrors.push(e)
|
|
475
|
+
}
|
|
476
|
+
try {
|
|
477
|
+
const binding = require('music-tag-native-openharmony-arm64')
|
|
478
|
+
const bindingPackageVersion = require('music-tag-native-openharmony-arm64/package.json').version
|
|
479
|
+
if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
480
|
+
throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
481
|
+
}
|
|
482
|
+
return binding
|
|
483
|
+
} catch (e) {
|
|
484
|
+
loadErrors.push(e)
|
|
485
|
+
}
|
|
486
|
+
} else if (process.arch === 'x64') {
|
|
487
|
+
try {
|
|
488
|
+
return require('./music-tag-native.openharmony-x64.node')
|
|
489
|
+
} catch (e) {
|
|
490
|
+
loadErrors.push(e)
|
|
491
|
+
}
|
|
492
|
+
try {
|
|
493
|
+
const binding = require('music-tag-native-openharmony-x64')
|
|
494
|
+
const bindingPackageVersion = require('music-tag-native-openharmony-x64/package.json').version
|
|
495
|
+
if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
496
|
+
throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
497
|
+
}
|
|
498
|
+
return binding
|
|
499
|
+
} catch (e) {
|
|
500
|
+
loadErrors.push(e)
|
|
501
|
+
}
|
|
502
|
+
} else if (process.arch === 'arm') {
|
|
503
|
+
try {
|
|
504
|
+
return require('./music-tag-native.openharmony-arm.node')
|
|
505
|
+
} catch (e) {
|
|
506
|
+
loadErrors.push(e)
|
|
507
|
+
}
|
|
508
|
+
try {
|
|
509
|
+
const binding = require('music-tag-native-openharmony-arm')
|
|
510
|
+
const bindingPackageVersion = require('music-tag-native-openharmony-arm/package.json').version
|
|
511
|
+
if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
512
|
+
throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
513
|
+
}
|
|
514
|
+
return binding
|
|
515
|
+
} catch (e) {
|
|
516
|
+
loadErrors.push(e)
|
|
517
|
+
}
|
|
518
|
+
} else {
|
|
519
|
+
loadErrors.push(new Error(`Unsupported architecture on OpenHarmony: ${process.arch}`))
|
|
520
|
+
}
|
|
521
|
+
} else {
|
|
522
|
+
loadErrors.push(new Error(`Unsupported OS: ${process.platform}, architecture: ${process.arch}`))
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
nativeBinding = requireNative()
|
|
527
|
+
|
|
528
|
+
if (!nativeBinding || process.env.NAPI_RS_FORCE_WASI) {
|
|
529
|
+
let wasiBinding = null
|
|
530
|
+
let wasiBindingError = null
|
|
531
|
+
try {
|
|
532
|
+
wasiBinding = require('./music-tag-native.wasi.cjs')
|
|
533
|
+
nativeBinding = wasiBinding
|
|
534
|
+
} catch (err) {
|
|
535
|
+
if (process.env.NAPI_RS_FORCE_WASI) {
|
|
536
|
+
wasiBindingError = err
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
if (!nativeBinding) {
|
|
540
|
+
try {
|
|
541
|
+
wasiBinding = require('music-tag-native-wasm32-wasi')
|
|
542
|
+
nativeBinding = wasiBinding
|
|
543
|
+
} catch (err) {
|
|
544
|
+
if (process.env.NAPI_RS_FORCE_WASI) {
|
|
545
|
+
wasiBindingError.cause = err
|
|
546
|
+
loadErrors.push(err)
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
if (process.env.NAPI_RS_FORCE_WASI === 'error' && !wasiBinding) {
|
|
551
|
+
const error = new Error('WASI binding not found and NAPI_RS_FORCE_WASI is set to error')
|
|
552
|
+
error.cause = wasiBindingError
|
|
553
|
+
throw error
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
if (!nativeBinding) {
|
|
558
|
+
if (loadErrors.length > 0) {
|
|
559
|
+
throw new Error(
|
|
560
|
+
`Cannot find native binding. ` +
|
|
561
|
+
`npm has a bug related to optional dependencies (https://github.com/npm/cli/issues/4828). ` +
|
|
562
|
+
'Please try `npm i` again after removing both package-lock.json and node_modules directory.',
|
|
563
|
+
{
|
|
564
|
+
cause: loadErrors.reduce((err, cur) => {
|
|
565
|
+
cur.cause = err
|
|
566
|
+
return cur
|
|
567
|
+
}),
|
|
568
|
+
},
|
|
569
|
+
)
|
|
570
|
+
}
|
|
571
|
+
throw new Error(`Failed to load native binding`)
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
module.exports = nativeBinding
|
|
575
|
+
module.exports.MetaPicture = nativeBinding.MetaPicture
|
|
576
|
+
module.exports.MusicTagger = nativeBinding.MusicTagger
|
package/package.json
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "music-tag-native",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Music tag reader / writter in Node.js / Browser, powered by napi-rs and lofty",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"types": "index.d.ts",
|
|
7
|
+
"browser": "browser.js",
|
|
8
|
+
"repository": {
|
|
9
|
+
"url": "git+ssh://git@github.com/subframe7536/music-tag-native.git",
|
|
10
|
+
"type": "git"
|
|
11
|
+
},
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"keywords": [
|
|
14
|
+
"napi-rs",
|
|
15
|
+
"NAPI",
|
|
16
|
+
"N-API",
|
|
17
|
+
"Rust",
|
|
18
|
+
"node-addon",
|
|
19
|
+
"node-addon-api",
|
|
20
|
+
"music",
|
|
21
|
+
"tags",
|
|
22
|
+
"MP3",
|
|
23
|
+
"M4A",
|
|
24
|
+
"FLAC",
|
|
25
|
+
"WAV",
|
|
26
|
+
"ID3",
|
|
27
|
+
"Vorbis"
|
|
28
|
+
],
|
|
29
|
+
"files": [
|
|
30
|
+
"index.d.ts",
|
|
31
|
+
"index.js",
|
|
32
|
+
"browser.js"
|
|
33
|
+
],
|
|
34
|
+
"napi": {
|
|
35
|
+
"binaryName": "music-tag-native",
|
|
36
|
+
"targets": [
|
|
37
|
+
"x86_64-unknown-linux-gnu",
|
|
38
|
+
"x86_64-unknown-linux-musl",
|
|
39
|
+
"x86_64-apple-darwin",
|
|
40
|
+
"x86_64-pc-windows-msvc",
|
|
41
|
+
"i686-pc-windows-msvc",
|
|
42
|
+
"aarch64-unknown-linux-gnu",
|
|
43
|
+
"aarch64-linux-android",
|
|
44
|
+
"aarch64-unknown-linux-musl",
|
|
45
|
+
"aarch64-apple-darwin",
|
|
46
|
+
"aarch64-pc-windows-msvc",
|
|
47
|
+
"wasm32-wasi-preview1-threads"
|
|
48
|
+
]
|
|
49
|
+
},
|
|
50
|
+
"engines": {
|
|
51
|
+
"node": ">= 10"
|
|
52
|
+
},
|
|
53
|
+
"publishConfig": {
|
|
54
|
+
"registry": "https://registry.npmjs.org/",
|
|
55
|
+
"access": "public"
|
|
56
|
+
},
|
|
57
|
+
"scripts": {
|
|
58
|
+
"artifacts": "napi artifacts",
|
|
59
|
+
"dev": "napi build --watch --target wasm32-wasip1-threads",
|
|
60
|
+
"build": "napi build --platform --release --strip",
|
|
61
|
+
"build:wasm": "napi build --release --target wasm32-wasip1-threads",
|
|
62
|
+
"build:debug": "napi build --platform",
|
|
63
|
+
"lint": "oxlint",
|
|
64
|
+
"test": "vitest run",
|
|
65
|
+
"play": "vite serve playground",
|
|
66
|
+
"test:watch": "vitest",
|
|
67
|
+
"prepublishOnly": "napi prepublish -t npm",
|
|
68
|
+
"release": "pnpm build && pnpm test && bumpp --all"
|
|
69
|
+
},
|
|
70
|
+
"devDependencies": {
|
|
71
|
+
"@emnapi/core": "^1.7.1",
|
|
72
|
+
"@emnapi/runtime": "^1.7.1",
|
|
73
|
+
"@napi-rs/cli": "^3.5.0",
|
|
74
|
+
"@napi-rs/wasm-runtime": "^1.1.0",
|
|
75
|
+
"@tybys/wasm-util": "^0.10.1",
|
|
76
|
+
"@types/node": "^24.10.1",
|
|
77
|
+
"bumpp": "^10.3.2",
|
|
78
|
+
"emnapi": "^1.7.1",
|
|
79
|
+
"oxlint": "^1.31.0",
|
|
80
|
+
"typescript": "^5.9.3",
|
|
81
|
+
"vite": "^7.2.7",
|
|
82
|
+
"vitest": "^4.0.15"
|
|
83
|
+
},
|
|
84
|
+
"packageManager": "pnpm@10.24.0",
|
|
85
|
+
"pnpm": {
|
|
86
|
+
"onlyBuiltDependencies": [
|
|
87
|
+
"esbuild"
|
|
88
|
+
]
|
|
89
|
+
},
|
|
90
|
+
"optionalDependencies": {
|
|
91
|
+
"music-tag-native-linux-x64-gnu": "0.1.0",
|
|
92
|
+
"music-tag-native-linux-x64-musl": "0.1.0",
|
|
93
|
+
"music-tag-native-darwin-x64": "0.1.0",
|
|
94
|
+
"music-tag-native-win32-x64-msvc": "0.1.0",
|
|
95
|
+
"music-tag-native-win32-ia32-msvc": "0.1.0",
|
|
96
|
+
"music-tag-native-linux-arm64-gnu": "0.1.0",
|
|
97
|
+
"music-tag-native-android-arm64": "0.1.0",
|
|
98
|
+
"music-tag-native-linux-arm64-musl": "0.1.0",
|
|
99
|
+
"music-tag-native-darwin-arm64": "0.1.0",
|
|
100
|
+
"music-tag-native-win32-arm64-msvc": "0.1.0",
|
|
101
|
+
"music-tag-native-wasm32-wasi": "0.1.0"
|
|
102
|
+
}
|
|
103
|
+
}
|