@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.
Files changed (49) hide show
  1. package/dist/bufferEntry.cjs +59 -0
  2. package/dist/bufferEntry.d.cts +16 -0
  3. package/dist/bufferEntry.d.ts +16 -0
  4. package/dist/bufferEntry.js +35 -0
  5. package/dist/entry.cjs +259 -28
  6. package/dist/entry.d.cts +31 -11
  7. package/dist/entry.d.ts +31 -11
  8. package/dist/entry.js +273 -28
  9. package/dist/ffmpeg.cjs +84 -0
  10. package/dist/ffmpeg.d.cts +11 -0
  11. package/dist/ffmpeg.d.ts +11 -0
  12. package/dist/ffmpeg.js +58 -0
  13. package/dist/fileEntry.cjs +58 -0
  14. package/dist/fileEntry.d.cts +16 -0
  15. package/dist/fileEntry.d.ts +16 -0
  16. package/dist/fileEntry.js +34 -0
  17. package/dist/index.cjs +281 -35
  18. package/dist/index.d.cts +67 -11
  19. package/dist/index.d.ts +67 -11
  20. package/dist/index.js +269 -35
  21. package/dist/resources.cjs +16 -0
  22. package/dist/resources.d.cts +14 -0
  23. package/dist/resources.d.ts +14 -0
  24. package/dist/resources.js +0 -0
  25. package/dist/tagMaps.cjs +120 -0
  26. package/dist/tagMaps.d.cts +24 -0
  27. package/dist/tagMaps.d.ts +24 -0
  28. package/dist/tagMaps.js +95 -0
  29. package/dist/zipFsEntry.cjs +65 -0
  30. package/dist/zipFsEntry.d.cts +19 -0
  31. package/dist/zipFsEntry.d.ts +19 -0
  32. package/dist/zipFsEntry.js +41 -0
  33. package/package.json +24 -29
  34. package/dist/base.cjs +0 -248
  35. package/dist/base.d.cts +0 -67
  36. package/dist/base.d.ts +0 -67
  37. package/dist/base.js +0 -223
  38. package/dist/node/entry.cjs +0 -76
  39. package/dist/node/entry.d.cts +0 -18
  40. package/dist/node/entry.d.ts +0 -18
  41. package/dist/node/entry.js +0 -52
  42. package/dist/node/index.cjs +0 -107
  43. package/dist/node/index.d.cts +0 -17
  44. package/dist/node/index.d.ts +0 -17
  45. package/dist/node/index.js +0 -89
  46. package/dist/taglib/Uint8ArrayFileAbstraction.cjs +0 -128
  47. package/dist/taglib/Uint8ArrayFileAbstraction.d.cts +0 -26
  48. package/dist/taglib/Uint8ArrayFileAbstraction.d.ts +0 -26
  49. package/dist/taglib/Uint8ArrayFileAbstraction.js +0 -106
package/dist/index.js CHANGED
@@ -1,45 +1,279 @@
1
- import { Uint8ArrayReader, ZipReader } from "@zip.js/zip.js";
2
- import { extname } from "@storyteller-platform/path";
3
- import { BaseAudiobook } from "./base.js";
4
- import { AudiobookEntry } from "./entry.js";
5
- class Audiobook extends BaseAudiobook {
6
- constructor(entries) {
7
- super();
8
- this.entries = entries;
9
- }
10
- static async from(pathOrPathsOrData) {
11
- if (!Array.isArray(pathOrPathsOrData)) {
12
- const ext = extname(pathOrPathsOrData.filename);
13
- if (ext === ".zip") {
14
- const dataReader = new Uint8ArrayReader(pathOrPathsOrData.data);
15
- const zipReader = new ZipReader(dataReader);
16
- const zipEntries = await zipReader.getEntries();
17
- const entries = zipEntries.map((entry) => new AudiobookEntry(entry));
18
- return new Audiobook(entries);
19
- }
20
- return new Audiobook([new AudiobookEntry(pathOrPathsOrData)]);
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
- return new Audiobook(
23
- pathOrPathsOrData.map((path) => new AudiobookEntry(path))
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
- static create(metadata) {
27
- const audiobook = new Audiobook([]);
28
- audiobook.metadata = metadata;
29
- return audiobook;
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 save() {
84
+ async setValue(setter) {
32
85
  for (const entry of this.entries) {
33
- entry.save();
86
+ await setter(entry);
34
87
  }
35
- return await Promise.all(
36
- this.entries.map(async (entry) => ({
37
- filename: entry.filename,
38
- data: await entry.getData()
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
- Audiobook
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
@@ -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 };
@@ -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
+ });