@storyteller-platform/audiobook 0.1.0 → 0.2.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/dist/bufferEntry.cjs +59 -0
- package/dist/bufferEntry.d.cts +16 -0
- package/dist/bufferEntry.d.ts +16 -0
- package/dist/bufferEntry.js +35 -0
- package/dist/entry.cjs +259 -28
- package/dist/entry.d.cts +31 -11
- package/dist/entry.d.ts +31 -11
- package/dist/entry.js +273 -28
- package/dist/ffmpeg.cjs +84 -0
- package/dist/ffmpeg.d.cts +11 -0
- package/dist/ffmpeg.d.ts +11 -0
- package/dist/ffmpeg.js +58 -0
- package/dist/fileEntry.cjs +58 -0
- package/dist/fileEntry.d.cts +16 -0
- package/dist/fileEntry.d.ts +16 -0
- package/dist/fileEntry.js +34 -0
- package/dist/index.cjs +281 -35
- package/dist/index.d.cts +67 -11
- package/dist/index.d.ts +67 -11
- package/dist/index.js +269 -35
- package/dist/resources.cjs +16 -0
- package/dist/resources.d.cts +14 -0
- package/dist/resources.d.ts +14 -0
- package/dist/resources.js +0 -0
- package/dist/tagMaps.cjs +120 -0
- package/dist/tagMaps.d.cts +24 -0
- package/dist/tagMaps.d.ts +24 -0
- package/dist/tagMaps.js +95 -0
- package/dist/zipFsEntry.cjs +65 -0
- package/dist/zipFsEntry.d.cts +19 -0
- package/dist/zipFsEntry.d.ts +19 -0
- package/dist/zipFsEntry.js +41 -0
- package/package.json +24 -29
- package/dist/base.cjs +0 -248
- package/dist/base.d.cts +0 -67
- package/dist/base.d.ts +0 -67
- package/dist/base.js +0 -223
- package/dist/node/entry.cjs +0 -76
- package/dist/node/entry.d.cts +0 -18
- package/dist/node/entry.d.ts +0 -18
- package/dist/node/entry.js +0 -52
- package/dist/node/index.cjs +0 -107
- package/dist/node/index.d.cts +0 -17
- package/dist/node/index.d.ts +0 -17
- package/dist/node/index.js +0 -89
- package/dist/taglib/Uint8ArrayFileAbstraction.cjs +0 -128
- package/dist/taglib/Uint8ArrayFileAbstraction.d.cts +0 -26
- package/dist/taglib/Uint8ArrayFileAbstraction.d.ts +0 -26
- package/dist/taglib/Uint8ArrayFileAbstraction.js +0 -106
package/dist/index.js
CHANGED
|
@@ -1,45 +1,279 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { ZipFS } from "@yarnpkg/libzip";
|
|
3
|
+
import { lookup } from "mime-types";
|
|
4
|
+
import { basename, extname } from "@storyteller-platform/path";
|
|
5
|
+
import { BufferEntry } from "./bufferEntry.js";
|
|
6
|
+
import { FileEntry } from "./fileEntry.js";
|
|
7
|
+
import { ZipFSEntry } from "./zipFsEntry.js";
|
|
8
|
+
const COVER_IMAGE_FILE_EXTENSIONS = [
|
|
9
|
+
".jpeg",
|
|
10
|
+
".jpg",
|
|
11
|
+
".png",
|
|
12
|
+
".svg"
|
|
13
|
+
];
|
|
14
|
+
const MP3_FILE_EXTENSIONS = [".mp3"];
|
|
15
|
+
const MPEG4_FILE_EXTENSIONS = [".mp4", ".m4a", ".m4b"];
|
|
16
|
+
const AAC_FILE_EXTENSIONS = [".aac"];
|
|
17
|
+
const OGG_FILE_EXTENSIONS = [".ogg", ".oga", ".mogg"];
|
|
18
|
+
const OPUS_FILE_EXTENSIONS = [".opus"];
|
|
19
|
+
const WAVE_FILE_EXTENSIONS = [".wav"];
|
|
20
|
+
const AIFF_FILE_EXTENSIONS = [".aiff"];
|
|
21
|
+
const FLAC_FILE_EXTENSIONS = [".flac"];
|
|
22
|
+
const ALAC_FILE_EXTENSIONS = [".alac"];
|
|
23
|
+
const WEBM_FILE_EXTENSIONS = [".weba"];
|
|
24
|
+
const AUDIO_FILE_EXTENSIONS = [
|
|
25
|
+
...MP3_FILE_EXTENSIONS,
|
|
26
|
+
...AAC_FILE_EXTENSIONS,
|
|
27
|
+
...MPEG4_FILE_EXTENSIONS,
|
|
28
|
+
...OPUS_FILE_EXTENSIONS,
|
|
29
|
+
...OGG_FILE_EXTENSIONS,
|
|
30
|
+
...WAVE_FILE_EXTENSIONS,
|
|
31
|
+
...AIFF_FILE_EXTENSIONS,
|
|
32
|
+
...FLAC_FILE_EXTENSIONS,
|
|
33
|
+
...ALAC_FILE_EXTENSIONS,
|
|
34
|
+
...WEBM_FILE_EXTENSIONS
|
|
35
|
+
];
|
|
36
|
+
class Audiobook {
|
|
37
|
+
metadata = {};
|
|
38
|
+
inputs;
|
|
39
|
+
entries;
|
|
40
|
+
constructor(...inputs) {
|
|
41
|
+
this.inputs = inputs;
|
|
42
|
+
this.entries = this.getEntries();
|
|
43
|
+
}
|
|
44
|
+
isZip() {
|
|
45
|
+
const [first] = this.inputs;
|
|
46
|
+
return typeof first === "string" && (extname(first) === ".zip" || extname(first) === ".audiobook");
|
|
47
|
+
}
|
|
48
|
+
isFiles() {
|
|
49
|
+
const [first] = this.inputs;
|
|
50
|
+
return typeof first === "string" && !this.isZip();
|
|
51
|
+
}
|
|
52
|
+
isInMemory() {
|
|
53
|
+
const [first] = this.inputs;
|
|
54
|
+
return typeof first !== "string";
|
|
55
|
+
}
|
|
56
|
+
getEntries() {
|
|
57
|
+
if (this.isZip()) {
|
|
58
|
+
const [first] = this.inputs;
|
|
59
|
+
const zipFs = new ZipFS(first);
|
|
60
|
+
const entries = zipFs.getAllFiles();
|
|
61
|
+
return entries.filter(
|
|
62
|
+
(entry) => AUDIO_FILE_EXTENSIONS.includes(
|
|
63
|
+
extname(entry)
|
|
64
|
+
)
|
|
65
|
+
).map((entry) => new ZipFSEntry(zipFs, entry));
|
|
21
66
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
67
|
+
if (this.isFiles()) {
|
|
68
|
+
return this.inputs.map((input) => new FileEntry(input));
|
|
69
|
+
}
|
|
70
|
+
if (this.isInMemory()) {
|
|
71
|
+
return this.inputs.map(
|
|
72
|
+
(input) => new BufferEntry(input)
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
return [];
|
|
25
76
|
}
|
|
26
|
-
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
77
|
+
async getFirstValue(getter) {
|
|
78
|
+
for (const entry of this.entries) {
|
|
79
|
+
const value = await getter(entry);
|
|
80
|
+
if (value) return value;
|
|
81
|
+
}
|
|
82
|
+
return null;
|
|
30
83
|
}
|
|
31
|
-
async
|
|
84
|
+
async setValue(setter) {
|
|
32
85
|
for (const entry of this.entries) {
|
|
33
|
-
entry
|
|
86
|
+
await setter(entry);
|
|
34
87
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
88
|
+
}
|
|
89
|
+
async getTitle() {
|
|
90
|
+
this.metadata.title ??= await this.getFirstValue(
|
|
91
|
+
(entry) => entry.getTitle()
|
|
92
|
+
);
|
|
93
|
+
return this.metadata.title;
|
|
94
|
+
}
|
|
95
|
+
async setTitle(title) {
|
|
96
|
+
this.metadata.title = title;
|
|
97
|
+
await this.setValue((entry) => entry.setTitle(title));
|
|
98
|
+
}
|
|
99
|
+
async getSubtitle() {
|
|
100
|
+
this.metadata.subtitle ??= await this.getFirstValue(
|
|
101
|
+
(entry) => entry.getSubtitle()
|
|
102
|
+
);
|
|
103
|
+
return this.metadata.subtitle;
|
|
104
|
+
}
|
|
105
|
+
async setSubtitle(subtitle) {
|
|
106
|
+
this.metadata.subtitle = subtitle;
|
|
107
|
+
await this.setValue((entry) => entry.setSubtitle(subtitle));
|
|
108
|
+
}
|
|
109
|
+
async getDescription() {
|
|
110
|
+
this.metadata.description ??= await this.getFirstValue(
|
|
111
|
+
(entry) => entry.getDescription()
|
|
112
|
+
);
|
|
113
|
+
return this.metadata.description;
|
|
114
|
+
}
|
|
115
|
+
async setDescription(description) {
|
|
116
|
+
this.metadata.description = description;
|
|
117
|
+
await this.setValue((entry) => entry.setDescription(description));
|
|
118
|
+
}
|
|
119
|
+
async getAuthors() {
|
|
120
|
+
this.metadata.authors ??= await this.getFirstValue(
|
|
121
|
+
(entry) => entry.getAuthors()
|
|
122
|
+
);
|
|
123
|
+
return this.metadata.authors ?? [];
|
|
124
|
+
}
|
|
125
|
+
async setAuthors(authors) {
|
|
126
|
+
this.metadata.authors = authors;
|
|
127
|
+
await this.setValue((entry) => entry.setAuthors(authors));
|
|
128
|
+
}
|
|
129
|
+
async getNarrators() {
|
|
130
|
+
this.metadata.narrators ??= await this.getFirstValue(
|
|
131
|
+
(entry) => entry.getNarrators()
|
|
132
|
+
);
|
|
133
|
+
return this.metadata.narrators ?? [];
|
|
134
|
+
}
|
|
135
|
+
async setNarrators(narrators) {
|
|
136
|
+
this.metadata.narrators = narrators;
|
|
137
|
+
await this.setValue((entry) => entry.setNarrators(narrators));
|
|
138
|
+
}
|
|
139
|
+
async getCoverArt() {
|
|
140
|
+
this.metadata.coverArt ??= await this.getFirstValue(
|
|
141
|
+
(entry) => entry.getCoverArt()
|
|
142
|
+
);
|
|
143
|
+
return this.metadata.coverArt;
|
|
144
|
+
}
|
|
145
|
+
async setCoverArt(picture) {
|
|
146
|
+
this.metadata.coverArt = picture;
|
|
147
|
+
await this.setValue((entry) => entry.setCoverArt(picture));
|
|
148
|
+
}
|
|
149
|
+
async getPublisher() {
|
|
150
|
+
this.metadata.publisher ??= await this.getFirstValue(
|
|
151
|
+
(entry) => entry.getPublisher()
|
|
40
152
|
);
|
|
153
|
+
return this.metadata.publisher;
|
|
41
154
|
}
|
|
155
|
+
async setPublisher(publisher) {
|
|
156
|
+
this.metadata.publisher = publisher;
|
|
157
|
+
await this.setValue((entry) => entry.setPublisher(publisher));
|
|
158
|
+
}
|
|
159
|
+
async getReleaseDate() {
|
|
160
|
+
this.metadata.releaseDate ??= await this.getFirstValue(
|
|
161
|
+
(entry) => entry.getReleaseDate()
|
|
162
|
+
);
|
|
163
|
+
return this.metadata.releaseDate;
|
|
164
|
+
}
|
|
165
|
+
async setReleaseDate(date) {
|
|
166
|
+
this.metadata.releaseDate = date;
|
|
167
|
+
await this.setValue((entry) => entry.setReleaseDate(date));
|
|
168
|
+
}
|
|
169
|
+
async getDuration() {
|
|
170
|
+
let duration = 0;
|
|
171
|
+
for (const entry of this.entries) {
|
|
172
|
+
duration += await entry.getDuration();
|
|
173
|
+
}
|
|
174
|
+
return duration;
|
|
175
|
+
}
|
|
176
|
+
async getChapters() {
|
|
177
|
+
if (this.metadata.chapters) return this.metadata.chapters;
|
|
178
|
+
const chapters = [];
|
|
179
|
+
for (const entry of this.entries) {
|
|
180
|
+
const entryChapters = await entry.getChapters();
|
|
181
|
+
if (entryChapters.length) {
|
|
182
|
+
chapters.push(...entryChapters);
|
|
183
|
+
} else {
|
|
184
|
+
chapters.push({
|
|
185
|
+
filename: entry.filename,
|
|
186
|
+
start: 0,
|
|
187
|
+
title: await entry.getTrackTitle() ?? basename(entry.filename, extname(entry.filename))
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
this.metadata.chapters = chapters;
|
|
192
|
+
return chapters;
|
|
193
|
+
}
|
|
194
|
+
async getResources() {
|
|
195
|
+
if (this.metadata.resources) return this.metadata.resources;
|
|
196
|
+
const resources = [];
|
|
197
|
+
for (let i = 0; i < this.entries.length; i++) {
|
|
198
|
+
const entry = this.entries[i];
|
|
199
|
+
const resource = await entry.getResource();
|
|
200
|
+
if (!resource.title) {
|
|
201
|
+
resource.title = `Track ${i + 1}`;
|
|
202
|
+
}
|
|
203
|
+
resources.push(resource);
|
|
204
|
+
}
|
|
205
|
+
this.metadata.resources = resources;
|
|
206
|
+
return resources;
|
|
207
|
+
}
|
|
208
|
+
async getArraysAndClose() {
|
|
209
|
+
const output = [];
|
|
210
|
+
for (const entry of this.entries) {
|
|
211
|
+
output.push(await entry.getArrayAndClose());
|
|
212
|
+
}
|
|
213
|
+
if (this.isZip()) {
|
|
214
|
+
const zipFs = this.entries[0].zipFs;
|
|
215
|
+
zipFs.discardAndClose();
|
|
216
|
+
}
|
|
217
|
+
return output;
|
|
218
|
+
}
|
|
219
|
+
async saveAndClose() {
|
|
220
|
+
if (this.isZip()) {
|
|
221
|
+
for (const entry of this.entries) {
|
|
222
|
+
await entry.saveAndClose();
|
|
223
|
+
}
|
|
224
|
+
const zipFs = this.entries[0].zipFs;
|
|
225
|
+
zipFs.saveAndClose();
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
if (this.isFiles()) {
|
|
229
|
+
for (const entry of this.entries) {
|
|
230
|
+
await entry.saveAndClose();
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
if (this.isInMemory()) {
|
|
234
|
+
throw new Error(
|
|
235
|
+
`Cannot save in-memory Audiobooks. Use audiobook.getArraysAndClose() to access the updated array.`
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
discardAndClose() {
|
|
240
|
+
if (this.isZip()) {
|
|
241
|
+
const zipFs = this.entries[0].zipFs;
|
|
242
|
+
if (zipFs.ready) {
|
|
243
|
+
zipFs.discardAndClose();
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
this.inputs = [".mp3"];
|
|
247
|
+
this.entries = [];
|
|
248
|
+
}
|
|
249
|
+
[Symbol.dispose]() {
|
|
250
|
+
this.discardAndClose();
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
async function getAttachedImageFromPath(path, kind = "coverFront", description) {
|
|
254
|
+
const data = await readFile(path);
|
|
255
|
+
const name = basename(path);
|
|
256
|
+
const mimeType = lookup(path) || "";
|
|
257
|
+
return {
|
|
258
|
+
data: new Uint8Array(data),
|
|
259
|
+
name,
|
|
260
|
+
kind,
|
|
261
|
+
...description && { description },
|
|
262
|
+
mimeType
|
|
263
|
+
};
|
|
42
264
|
}
|
|
43
265
|
export {
|
|
44
|
-
|
|
266
|
+
AAC_FILE_EXTENSIONS,
|
|
267
|
+
AIFF_FILE_EXTENSIONS,
|
|
268
|
+
ALAC_FILE_EXTENSIONS,
|
|
269
|
+
Audiobook,
|
|
270
|
+
COVER_IMAGE_FILE_EXTENSIONS,
|
|
271
|
+
FLAC_FILE_EXTENSIONS,
|
|
272
|
+
MP3_FILE_EXTENSIONS,
|
|
273
|
+
MPEG4_FILE_EXTENSIONS,
|
|
274
|
+
OGG_FILE_EXTENSIONS,
|
|
275
|
+
OPUS_FILE_EXTENSIONS,
|
|
276
|
+
WAVE_FILE_EXTENSIONS,
|
|
277
|
+
WEBM_FILE_EXTENSIONS,
|
|
278
|
+
getAttachedImageFromPath
|
|
45
279
|
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __copyProps = (to, from, except, desc) => {
|
|
7
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
8
|
+
for (let key of __getOwnPropNames(from))
|
|
9
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
10
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
11
|
+
}
|
|
12
|
+
return to;
|
|
13
|
+
};
|
|
14
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
15
|
+
var resources_exports = {};
|
|
16
|
+
module.exports = __toCommonJS(resources_exports);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
interface AudiobookChapter {
|
|
2
|
+
filename: string;
|
|
3
|
+
start: number | null;
|
|
4
|
+
title: string;
|
|
5
|
+
}
|
|
6
|
+
interface AudiobookResource {
|
|
7
|
+
filename: string;
|
|
8
|
+
type: string;
|
|
9
|
+
bitrate: number | null;
|
|
10
|
+
duration: number;
|
|
11
|
+
title: string | null;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export type { AudiobookChapter, AudiobookResource };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
interface AudiobookChapter {
|
|
2
|
+
filename: string;
|
|
3
|
+
start: number | null;
|
|
4
|
+
title: string;
|
|
5
|
+
}
|
|
6
|
+
interface AudiobookResource {
|
|
7
|
+
filename: string;
|
|
8
|
+
type: string;
|
|
9
|
+
bitrate: number | null;
|
|
10
|
+
duration: number;
|
|
11
|
+
title: string | null;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export type { AudiobookChapter, AudiobookResource };
|
|
File without changes
|
package/dist/tagMaps.cjs
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var tagMaps_exports = {};
|
|
20
|
+
__export(tagMaps_exports, {
|
|
21
|
+
getWriteTags: () => getWriteTags,
|
|
22
|
+
readTagMap: () => readTagMap
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(tagMaps_exports);
|
|
25
|
+
var import_mediabunny = require("mediabunny");
|
|
26
|
+
const readTagMap = {
|
|
27
|
+
trackTitle: ["TT2", "TIT2", "\xA9nam"],
|
|
28
|
+
title: ["TAL", "TALB", "TT2", "TIT2", "\xA9alb", "\xA9nam"],
|
|
29
|
+
subtitle: ["TT3", "TIT3", "Subt", "----:com.apple.iTunes:SUBTITLE", "\xA9gen"],
|
|
30
|
+
description: [
|
|
31
|
+
"COM",
|
|
32
|
+
"TDES",
|
|
33
|
+
"COMM",
|
|
34
|
+
"\xA9des",
|
|
35
|
+
"ldes",
|
|
36
|
+
"desc",
|
|
37
|
+
"\xA9cmt",
|
|
38
|
+
"\xA9com",
|
|
39
|
+
"----:com.apple.iTunes:NOTES"
|
|
40
|
+
],
|
|
41
|
+
authors: [
|
|
42
|
+
// albumArtists
|
|
43
|
+
"TP2",
|
|
44
|
+
"TPE2",
|
|
45
|
+
"aART",
|
|
46
|
+
"----:com.apple.iTunes:Band",
|
|
47
|
+
// artists
|
|
48
|
+
"TP1",
|
|
49
|
+
"TPE1",
|
|
50
|
+
"TXXX:Artists",
|
|
51
|
+
"\xA9ART",
|
|
52
|
+
"----:com.apple.iTunes:ARTISTS"
|
|
53
|
+
],
|
|
54
|
+
narrators: [
|
|
55
|
+
// Narrator tag, almost never used
|
|
56
|
+
"\xA9nrt",
|
|
57
|
+
// composers
|
|
58
|
+
"TCM",
|
|
59
|
+
"TCOM",
|
|
60
|
+
"\xA9wrt",
|
|
61
|
+
// conductors
|
|
62
|
+
"TP3",
|
|
63
|
+
"TPE3",
|
|
64
|
+
"----:com.apple.iTunes:CONDUCTOR",
|
|
65
|
+
"\xA9con",
|
|
66
|
+
"cond"
|
|
67
|
+
],
|
|
68
|
+
publisher: ["\xA9pub"],
|
|
69
|
+
releaseDate: ["TDR", "TDRL", "rldt"]
|
|
70
|
+
};
|
|
71
|
+
const writeIdv3TagMap = {
|
|
72
|
+
title: ["TALB"],
|
|
73
|
+
subtitle: ["TIT3"],
|
|
74
|
+
description: ["TDES", "COMM"],
|
|
75
|
+
authors: ["TPE2", "TPE1", "TXXX:Artists"],
|
|
76
|
+
narrators: ["TCOM", "TPE3"],
|
|
77
|
+
publisher: [],
|
|
78
|
+
releaseDate: ["TDRL"]
|
|
79
|
+
};
|
|
80
|
+
const writeMp4TagMap = {
|
|
81
|
+
title: ["\xA9alb"],
|
|
82
|
+
subtitle: ["Subt", "----:com.apple.iTunes:SUBTITLE"],
|
|
83
|
+
description: [
|
|
84
|
+
"\xA9des",
|
|
85
|
+
"ldes",
|
|
86
|
+
"desc",
|
|
87
|
+
"\xA9cmt",
|
|
88
|
+
"\xA9com",
|
|
89
|
+
"----:com.apple.iTunes:NOTES"
|
|
90
|
+
],
|
|
91
|
+
authors: [
|
|
92
|
+
"aART",
|
|
93
|
+
"----:com.apple.iTunes:Band",
|
|
94
|
+
"\xA9ART",
|
|
95
|
+
"----:com.apple.iTunes:ARTISTS"
|
|
96
|
+
],
|
|
97
|
+
narrators: [
|
|
98
|
+
"\xA9nrt",
|
|
99
|
+
"\xA9wrt",
|
|
100
|
+
"----:com.apple.iTunes:CONDUCTOR",
|
|
101
|
+
"\xA9con",
|
|
102
|
+
"cond"
|
|
103
|
+
],
|
|
104
|
+
publisher: ["\xA9pub"],
|
|
105
|
+
releaseDate: ["rldt"]
|
|
106
|
+
};
|
|
107
|
+
function getWriteTags(format, tag) {
|
|
108
|
+
if (format === import_mediabunny.MP3) {
|
|
109
|
+
return writeIdv3TagMap[tag];
|
|
110
|
+
}
|
|
111
|
+
if (format === import_mediabunny.MP4) {
|
|
112
|
+
return writeMp4TagMap[tag];
|
|
113
|
+
}
|
|
114
|
+
return [];
|
|
115
|
+
}
|
|
116
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
117
|
+
0 && (module.exports = {
|
|
118
|
+
getWriteTags,
|
|
119
|
+
readTagMap
|
|
120
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { InputFormat } from 'mediabunny';
|
|
2
|
+
|
|
3
|
+
declare const readTagMap: {
|
|
4
|
+
trackTitle: string[];
|
|
5
|
+
title: string[];
|
|
6
|
+
subtitle: string[];
|
|
7
|
+
description: string[];
|
|
8
|
+
authors: string[];
|
|
9
|
+
narrators: string[];
|
|
10
|
+
publisher: string[];
|
|
11
|
+
releaseDate: string[];
|
|
12
|
+
};
|
|
13
|
+
declare const writeIdv3TagMap: {
|
|
14
|
+
title: string[];
|
|
15
|
+
subtitle: string[];
|
|
16
|
+
description: string[];
|
|
17
|
+
authors: string[];
|
|
18
|
+
narrators: string[];
|
|
19
|
+
publisher: never[];
|
|
20
|
+
releaseDate: string[];
|
|
21
|
+
};
|
|
22
|
+
declare function getWriteTags(format: InputFormat, tag: keyof typeof writeIdv3TagMap): string[];
|
|
23
|
+
|
|
24
|
+
export { getWriteTags, readTagMap };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { InputFormat } from 'mediabunny';
|
|
2
|
+
|
|
3
|
+
declare const readTagMap: {
|
|
4
|
+
trackTitle: string[];
|
|
5
|
+
title: string[];
|
|
6
|
+
subtitle: string[];
|
|
7
|
+
description: string[];
|
|
8
|
+
authors: string[];
|
|
9
|
+
narrators: string[];
|
|
10
|
+
publisher: string[];
|
|
11
|
+
releaseDate: string[];
|
|
12
|
+
};
|
|
13
|
+
declare const writeIdv3TagMap: {
|
|
14
|
+
title: string[];
|
|
15
|
+
subtitle: string[];
|
|
16
|
+
description: string[];
|
|
17
|
+
authors: string[];
|
|
18
|
+
narrators: string[];
|
|
19
|
+
publisher: never[];
|
|
20
|
+
releaseDate: string[];
|
|
21
|
+
};
|
|
22
|
+
declare function getWriteTags(format: InputFormat, tag: keyof typeof writeIdv3TagMap): string[];
|
|
23
|
+
|
|
24
|
+
export { getWriteTags, readTagMap };
|
package/dist/tagMaps.js
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { MP3, MP4 } from "mediabunny";
|
|
2
|
+
const readTagMap = {
|
|
3
|
+
trackTitle: ["TT2", "TIT2", "\xA9nam"],
|
|
4
|
+
title: ["TAL", "TALB", "TT2", "TIT2", "\xA9alb", "\xA9nam"],
|
|
5
|
+
subtitle: ["TT3", "TIT3", "Subt", "----:com.apple.iTunes:SUBTITLE", "\xA9gen"],
|
|
6
|
+
description: [
|
|
7
|
+
"COM",
|
|
8
|
+
"TDES",
|
|
9
|
+
"COMM",
|
|
10
|
+
"\xA9des",
|
|
11
|
+
"ldes",
|
|
12
|
+
"desc",
|
|
13
|
+
"\xA9cmt",
|
|
14
|
+
"\xA9com",
|
|
15
|
+
"----:com.apple.iTunes:NOTES"
|
|
16
|
+
],
|
|
17
|
+
authors: [
|
|
18
|
+
// albumArtists
|
|
19
|
+
"TP2",
|
|
20
|
+
"TPE2",
|
|
21
|
+
"aART",
|
|
22
|
+
"----:com.apple.iTunes:Band",
|
|
23
|
+
// artists
|
|
24
|
+
"TP1",
|
|
25
|
+
"TPE1",
|
|
26
|
+
"TXXX:Artists",
|
|
27
|
+
"\xA9ART",
|
|
28
|
+
"----:com.apple.iTunes:ARTISTS"
|
|
29
|
+
],
|
|
30
|
+
narrators: [
|
|
31
|
+
// Narrator tag, almost never used
|
|
32
|
+
"\xA9nrt",
|
|
33
|
+
// composers
|
|
34
|
+
"TCM",
|
|
35
|
+
"TCOM",
|
|
36
|
+
"\xA9wrt",
|
|
37
|
+
// conductors
|
|
38
|
+
"TP3",
|
|
39
|
+
"TPE3",
|
|
40
|
+
"----:com.apple.iTunes:CONDUCTOR",
|
|
41
|
+
"\xA9con",
|
|
42
|
+
"cond"
|
|
43
|
+
],
|
|
44
|
+
publisher: ["\xA9pub"],
|
|
45
|
+
releaseDate: ["TDR", "TDRL", "rldt"]
|
|
46
|
+
};
|
|
47
|
+
const writeIdv3TagMap = {
|
|
48
|
+
title: ["TALB"],
|
|
49
|
+
subtitle: ["TIT3"],
|
|
50
|
+
description: ["TDES", "COMM"],
|
|
51
|
+
authors: ["TPE2", "TPE1", "TXXX:Artists"],
|
|
52
|
+
narrators: ["TCOM", "TPE3"],
|
|
53
|
+
publisher: [],
|
|
54
|
+
releaseDate: ["TDRL"]
|
|
55
|
+
};
|
|
56
|
+
const writeMp4TagMap = {
|
|
57
|
+
title: ["\xA9alb"],
|
|
58
|
+
subtitle: ["Subt", "----:com.apple.iTunes:SUBTITLE"],
|
|
59
|
+
description: [
|
|
60
|
+
"\xA9des",
|
|
61
|
+
"ldes",
|
|
62
|
+
"desc",
|
|
63
|
+
"\xA9cmt",
|
|
64
|
+
"\xA9com",
|
|
65
|
+
"----:com.apple.iTunes:NOTES"
|
|
66
|
+
],
|
|
67
|
+
authors: [
|
|
68
|
+
"aART",
|
|
69
|
+
"----:com.apple.iTunes:Band",
|
|
70
|
+
"\xA9ART",
|
|
71
|
+
"----:com.apple.iTunes:ARTISTS"
|
|
72
|
+
],
|
|
73
|
+
narrators: [
|
|
74
|
+
"\xA9nrt",
|
|
75
|
+
"\xA9wrt",
|
|
76
|
+
"----:com.apple.iTunes:CONDUCTOR",
|
|
77
|
+
"\xA9con",
|
|
78
|
+
"cond"
|
|
79
|
+
],
|
|
80
|
+
publisher: ["\xA9pub"],
|
|
81
|
+
releaseDate: ["rldt"]
|
|
82
|
+
};
|
|
83
|
+
function getWriteTags(format, tag) {
|
|
84
|
+
if (format === MP3) {
|
|
85
|
+
return writeIdv3TagMap[tag];
|
|
86
|
+
}
|
|
87
|
+
if (format === MP4) {
|
|
88
|
+
return writeMp4TagMap[tag];
|
|
89
|
+
}
|
|
90
|
+
return [];
|
|
91
|
+
}
|
|
92
|
+
export {
|
|
93
|
+
getWriteTags,
|
|
94
|
+
readTagMap
|
|
95
|
+
};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var zipFsEntry_exports = {};
|
|
20
|
+
__export(zipFsEntry_exports, {
|
|
21
|
+
ZipFSEntry: () => ZipFSEntry
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(zipFsEntry_exports);
|
|
24
|
+
var import_mediabunny = require("mediabunny");
|
|
25
|
+
var import_entry = require("./entry.cjs");
|
|
26
|
+
var import_ffmpeg = require("./ffmpeg.cjs");
|
|
27
|
+
class ZipFSEntry extends import_entry.AudiobookEntry {
|
|
28
|
+
constructor(zipFs, filename) {
|
|
29
|
+
super();
|
|
30
|
+
this.zipFs = zipFs;
|
|
31
|
+
this.filename = filename;
|
|
32
|
+
}
|
|
33
|
+
input = null;
|
|
34
|
+
data = null;
|
|
35
|
+
async getInput() {
|
|
36
|
+
if (this.input) return this.input;
|
|
37
|
+
this.data ??= await this.zipFs.readFilePromise(this.filename);
|
|
38
|
+
this.input = new import_mediabunny.Input({
|
|
39
|
+
formats: import_mediabunny.ALL_FORMATS,
|
|
40
|
+
source: new import_mediabunny.BufferSource(this.data)
|
|
41
|
+
});
|
|
42
|
+
return this.input;
|
|
43
|
+
}
|
|
44
|
+
async getChapters() {
|
|
45
|
+
this.data ??= await this.zipFs.readFilePromise(this.filename);
|
|
46
|
+
const chapters = await (0, import_ffmpeg.getTrackChaptersFromBuffer)(this.data);
|
|
47
|
+
return chapters.map((chapter) => ({
|
|
48
|
+
filename: this.filename,
|
|
49
|
+
title: chapter.title,
|
|
50
|
+
start: chapter.startTime
|
|
51
|
+
}));
|
|
52
|
+
}
|
|
53
|
+
async saveAndClose() {
|
|
54
|
+
const { data } = await this.getArrayAndClose();
|
|
55
|
+
await this.zipFs.writeFilePromise(
|
|
56
|
+
this.filename,
|
|
57
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
58
|
+
new Uint8Array(data)
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
63
|
+
0 && (module.exports = {
|
|
64
|
+
ZipFSEntry
|
|
65
|
+
});
|