@storyteller-platform/audiobook 0.3.6 → 0.3.8
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/ffmpeg.cjs +7 -1
- package/dist/ffmpeg.js +7 -1
- package/dist/index.cjs +56 -121
- package/dist/index.d.cts +2 -12
- package/dist/index.d.ts +2 -12
- package/dist/index.js +56 -99
- package/dist/mime.cjs +8 -1
- package/dist/mime.d.cts +13 -12
- package/dist/mime.d.ts +13 -12
- package/dist/mime.js +7 -1
- package/package.json +6 -4
package/dist/ffmpeg.cjs
CHANGED
|
@@ -53,12 +53,18 @@ async function execCmdBuffer(command, args) {
|
|
|
53
53
|
try {
|
|
54
54
|
const { stdout } = await execFilePromise(command, args, {
|
|
55
55
|
encoding: "buffer",
|
|
56
|
-
|
|
56
|
+
// let's be very generous
|
|
57
|
+
maxBuffer: 50 * 1024 * 1024,
|
|
57
58
|
cwd: process.cwd()
|
|
58
59
|
});
|
|
59
60
|
return stdout;
|
|
60
61
|
} catch (error) {
|
|
61
62
|
console.error(error);
|
|
63
|
+
if (error instanceof RangeError && error.message.includes("stdout maxBuffer length exceeded")) {
|
|
64
|
+
throw new Error(
|
|
65
|
+
"stdout maxBuffer length exceeded. This likely means that youre trying to process a very large file, and the ffmpeg process is running out of memory. Maybe check the image size of your cover art."
|
|
66
|
+
);
|
|
67
|
+
}
|
|
62
68
|
if (error && typeof error === "object" && "stdout" in error) {
|
|
63
69
|
console.warn((_a = error.stdout) == null ? void 0 : _a.toString());
|
|
64
70
|
throw new Error((_b = error.stdout) == null ? void 0 : _b.toString());
|
package/dist/ffmpeg.js
CHANGED
|
@@ -27,12 +27,18 @@ async function execCmdBuffer(command, args) {
|
|
|
27
27
|
try {
|
|
28
28
|
const { stdout } = await execFilePromise(command, args, {
|
|
29
29
|
encoding: "buffer",
|
|
30
|
-
|
|
30
|
+
// let's be very generous
|
|
31
|
+
maxBuffer: 50 * 1024 * 1024,
|
|
31
32
|
cwd: process.cwd()
|
|
32
33
|
});
|
|
33
34
|
return stdout;
|
|
34
35
|
} catch (error) {
|
|
35
36
|
console.error(error);
|
|
37
|
+
if (error instanceof RangeError && error.message.includes("stdout maxBuffer length exceeded")) {
|
|
38
|
+
throw new Error(
|
|
39
|
+
"stdout maxBuffer length exceeded. This likely means that youre trying to process a very large file, and the ffmpeg process is running out of memory. Maybe check the image size of your cover art."
|
|
40
|
+
);
|
|
41
|
+
}
|
|
36
42
|
if (error && typeof error === "object" && "stdout" in error) {
|
|
37
43
|
console.warn((_a = error.stdout) == null ? void 0 : _a.toString());
|
|
38
44
|
throw new Error((_b = error.stdout) == null ? void 0 : _b.toString());
|
package/dist/index.cjs
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __create = Object.create;
|
|
3
2
|
var __defProp = Object.defineProperty;
|
|
4
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
6
|
var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : Symbol.for("Symbol." + name);
|
|
9
7
|
var __typeError = (msg) => {
|
|
@@ -21,14 +19,6 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
21
19
|
}
|
|
22
20
|
return to;
|
|
23
21
|
};
|
|
24
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
25
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
26
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
27
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
28
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
29
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
30
|
-
mod
|
|
31
|
-
));
|
|
32
22
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
33
23
|
var __using = (stack, value, async) => {
|
|
34
24
|
if (value != null) {
|
|
@@ -73,77 +63,31 @@ var __callDispose = (stack, error, hasError) => {
|
|
|
73
63
|
};
|
|
74
64
|
var index_exports = {};
|
|
75
65
|
__export(index_exports, {
|
|
76
|
-
AAC_FILE_EXTENSIONS: () => AAC_FILE_EXTENSIONS,
|
|
77
|
-
AIFF_FILE_EXTENSIONS: () => AIFF_FILE_EXTENSIONS,
|
|
78
|
-
ALAC_FILE_EXTENSIONS: () => ALAC_FILE_EXTENSIONS,
|
|
66
|
+
AAC_FILE_EXTENSIONS: () => import_mime2.AAC_FILE_EXTENSIONS,
|
|
67
|
+
AIFF_FILE_EXTENSIONS: () => import_mime2.AIFF_FILE_EXTENSIONS,
|
|
79
68
|
Audiobook: () => Audiobook,
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
getAttachedImageFromPath: () => getAttachedImageFromPath
|
|
69
|
+
MP3_FILE_EXTENSIONS: () => import_mime2.MP3_FILE_EXTENSIONS,
|
|
70
|
+
MPEG4_FILE_EXTENSIONS: () => import_mime2.MPEG4_FILE_EXTENSIONS,
|
|
71
|
+
OGG_FILE_EXTENSIONS: () => import_mime2.OGG_FILE_EXTENSIONS,
|
|
72
|
+
OPUS_FILE_EXTENSIONS: () => import_mime2.OPUS_FILE_EXTENSIONS,
|
|
73
|
+
getAttachedImageFromPath: () => getAttachedImageFromPath,
|
|
74
|
+
isAudioFile: () => import_mime2.isAudioFile,
|
|
75
|
+
isZipArchive: () => import_mime2.isZipArchive,
|
|
76
|
+
lookupAudioMime: () => import_mime2.lookupAudioMime
|
|
89
77
|
});
|
|
90
78
|
module.exports = __toCommonJS(index_exports);
|
|
91
79
|
var import_node_crypto = require("node:crypto");
|
|
92
80
|
var import_node_fs = require("node:fs");
|
|
93
81
|
var import_promises = require("node:fs/promises");
|
|
94
82
|
var import_node_os = require("node:os");
|
|
95
|
-
var
|
|
83
|
+
var import_promises2 = require("node:stream/promises");
|
|
96
84
|
var import_mime_types = require("mime-types");
|
|
97
|
-
var
|
|
85
|
+
var import_yauzl_promise = require("yauzl-promise");
|
|
98
86
|
var import_yazl = require("yazl");
|
|
99
87
|
var import_path = require("@storyteller-platform/path");
|
|
100
88
|
var import_entry = require("./entry.cjs");
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
return new Promise(function(resolve, reject) {
|
|
104
|
-
api(arg, options, function(err, response) {
|
|
105
|
-
if (err) {
|
|
106
|
-
reject(err);
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
resolve(response);
|
|
110
|
-
});
|
|
111
|
-
});
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
const unzipFromPath = promisify(
|
|
115
|
-
(arg, options, callback) => {
|
|
116
|
-
import_yauzl.default.open(arg, options, callback);
|
|
117
|
-
}
|
|
118
|
-
);
|
|
119
|
-
const COVER_IMAGE_FILE_EXTENSIONS = [
|
|
120
|
-
".jpeg",
|
|
121
|
-
".jpg",
|
|
122
|
-
".png",
|
|
123
|
-
".svg"
|
|
124
|
-
];
|
|
125
|
-
const MP3_FILE_EXTENSIONS = [".mp3"];
|
|
126
|
-
const MPEG4_FILE_EXTENSIONS = [".mp4", ".m4a", ".m4b"];
|
|
127
|
-
const AAC_FILE_EXTENSIONS = [".aac"];
|
|
128
|
-
const OGG_FILE_EXTENSIONS = [".ogg", ".oga", ".mogg"];
|
|
129
|
-
const OPUS_FILE_EXTENSIONS = [".opus"];
|
|
130
|
-
const WAVE_FILE_EXTENSIONS = [".wav"];
|
|
131
|
-
const AIFF_FILE_EXTENSIONS = [".aiff"];
|
|
132
|
-
const FLAC_FILE_EXTENSIONS = [".flac"];
|
|
133
|
-
const ALAC_FILE_EXTENSIONS = [".alac"];
|
|
134
|
-
const WEBM_FILE_EXTENSIONS = [".weba"];
|
|
135
|
-
const AUDIO_FILE_EXTENSIONS = [
|
|
136
|
-
...MP3_FILE_EXTENSIONS,
|
|
137
|
-
...AAC_FILE_EXTENSIONS,
|
|
138
|
-
...MPEG4_FILE_EXTENSIONS,
|
|
139
|
-
...OPUS_FILE_EXTENSIONS,
|
|
140
|
-
...OGG_FILE_EXTENSIONS,
|
|
141
|
-
...WAVE_FILE_EXTENSIONS,
|
|
142
|
-
...AIFF_FILE_EXTENSIONS,
|
|
143
|
-
...FLAC_FILE_EXTENSIONS,
|
|
144
|
-
...ALAC_FILE_EXTENSIONS,
|
|
145
|
-
...WEBM_FILE_EXTENSIONS
|
|
146
|
-
];
|
|
89
|
+
var import_mime = require("./mime.cjs");
|
|
90
|
+
var import_mime2 = require("./mime.cjs");
|
|
147
91
|
class Audiobook {
|
|
148
92
|
metadata = {};
|
|
149
93
|
inputs;
|
|
@@ -162,54 +106,47 @@ class Audiobook {
|
|
|
162
106
|
}
|
|
163
107
|
async getEntries() {
|
|
164
108
|
if (this.isZip) {
|
|
165
|
-
|
|
109
|
+
const [first] = this.inputs;
|
|
110
|
+
const extractPath = (0, import_path.join)(
|
|
111
|
+
(0, import_node_os.tmpdir)(),
|
|
112
|
+
`storyteller-platform-audiobook-${(0, import_node_crypto.randomUUID)()}`
|
|
113
|
+
);
|
|
114
|
+
this.extractPath = extractPath;
|
|
115
|
+
const entries = [];
|
|
166
116
|
try {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
(0,
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
const openReadStream = util.promisify(
|
|
185
|
-
zipfile.openReadStream.bind(zipfile)
|
|
186
|
-
);
|
|
187
|
-
zipfile.readEntry();
|
|
188
|
-
zipfile.on("entry", async (entry) => {
|
|
189
|
-
if (entry.fileName.endsWith("/")) {
|
|
190
|
-
zipfile.readEntry();
|
|
191
|
-
} else {
|
|
192
|
-
entries.push(entry.fileName);
|
|
193
|
-
const readStream = await openReadStream(entry);
|
|
194
|
-
readStream.on("end", function() {
|
|
195
|
-
zipfile.readEntry();
|
|
196
|
-
});
|
|
197
|
-
const writePath = (0, import_path.join)(extractPath, entry.fileName);
|
|
198
|
-
await (0, import_promises.mkdir)((0, import_path.dirname)(writePath), { recursive: true });
|
|
199
|
-
readStream.pipe((0, import_node_fs.createWriteStream)(writePath));
|
|
117
|
+
var _stack = [];
|
|
118
|
+
try {
|
|
119
|
+
const zipfile = await (0, import_yauzl_promise.open)(first);
|
|
120
|
+
const stack = __using(_stack, new AsyncDisposableStack(), true);
|
|
121
|
+
stack.defer(async () => {
|
|
122
|
+
await zipfile.close();
|
|
123
|
+
});
|
|
124
|
+
for await (const entry of zipfile) {
|
|
125
|
+
if (entry.filename.endsWith("/")) {
|
|
126
|
+
} else {
|
|
127
|
+
entries.push(entry.filename);
|
|
128
|
+
const readStream = await entry.openReadStream();
|
|
129
|
+
const writePath = (0, import_path.join)(extractPath, entry.filename);
|
|
130
|
+
await (0, import_promises.mkdir)((0, import_path.dirname)(writePath), { recursive: true });
|
|
131
|
+
const writeStream = (0, import_node_fs.createWriteStream)(writePath);
|
|
132
|
+
await (0, import_promises2.pipeline)(readStream, writeStream);
|
|
133
|
+
}
|
|
200
134
|
}
|
|
201
|
-
})
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
(
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
} finally {
|
|
211
|
-
__callDispose(_stack, _error, _hasError);
|
|
135
|
+
} catch (_) {
|
|
136
|
+
var _error = _, _hasError = true;
|
|
137
|
+
} finally {
|
|
138
|
+
var _promise = __callDispose(_stack, _error, _hasError);
|
|
139
|
+
_promise && await _promise;
|
|
140
|
+
}
|
|
141
|
+
} catch (error) {
|
|
142
|
+
(0, import_node_fs.rmSync)(extractPath, { force: true, recursive: true });
|
|
143
|
+
throw error;
|
|
212
144
|
}
|
|
145
|
+
return entries.filter(
|
|
146
|
+
(entry) => import_mime.AUDIO_FILE_EXTENSIONS.includes(
|
|
147
|
+
(0, import_path.extname)(entry)
|
|
148
|
+
)
|
|
149
|
+
).map((entry) => new import_entry.AudiobookEntry((0, import_path.join)(extractPath, entry)));
|
|
213
150
|
} else {
|
|
214
151
|
return this.inputs.map((input) => new import_entry.AudiobookEntry(input));
|
|
215
152
|
}
|
|
@@ -429,15 +366,13 @@ async function getAttachedImageFromPath(path, kind = "coverFront", description)
|
|
|
429
366
|
0 && (module.exports = {
|
|
430
367
|
AAC_FILE_EXTENSIONS,
|
|
431
368
|
AIFF_FILE_EXTENSIONS,
|
|
432
|
-
ALAC_FILE_EXTENSIONS,
|
|
433
369
|
Audiobook,
|
|
434
|
-
COVER_IMAGE_FILE_EXTENSIONS,
|
|
435
|
-
FLAC_FILE_EXTENSIONS,
|
|
436
370
|
MP3_FILE_EXTENSIONS,
|
|
437
371
|
MPEG4_FILE_EXTENSIONS,
|
|
438
372
|
OGG_FILE_EXTENSIONS,
|
|
439
373
|
OPUS_FILE_EXTENSIONS,
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
374
|
+
getAttachedImageFromPath,
|
|
375
|
+
isAudioFile,
|
|
376
|
+
isZipArchive,
|
|
377
|
+
lookupAudioMime
|
|
443
378
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { AudiobookEntry } from './entry.cjs';
|
|
2
2
|
import { AttachedPic } from './ffmpeg.cjs';
|
|
3
3
|
import { AudiobookChapter, AudiobookResource } from './resources.cjs';
|
|
4
|
+
export { AAC_FILE_EXTENSIONS, AIFF_FILE_EXTENSIONS, MP3_FILE_EXTENSIONS, MPEG4_FILE_EXTENSIONS, OGG_FILE_EXTENSIONS, OPUS_FILE_EXTENSIONS, isAudioFile, isZipArchive, lookupAudioMime } from './mime.cjs';
|
|
4
5
|
|
|
5
6
|
interface AudiobookMetadata {
|
|
6
7
|
title?: string | null;
|
|
@@ -14,17 +15,6 @@ interface AudiobookMetadata {
|
|
|
14
15
|
publisher?: string | null;
|
|
15
16
|
releaseDate?: Date | null;
|
|
16
17
|
}
|
|
17
|
-
declare const COVER_IMAGE_FILE_EXTENSIONS: readonly [".jpeg", ".jpg", ".png", ".svg"];
|
|
18
|
-
declare const MP3_FILE_EXTENSIONS: readonly [".mp3"];
|
|
19
|
-
declare const MPEG4_FILE_EXTENSIONS: readonly [".mp4", ".m4a", ".m4b"];
|
|
20
|
-
declare const AAC_FILE_EXTENSIONS: readonly [".aac"];
|
|
21
|
-
declare const OGG_FILE_EXTENSIONS: readonly [".ogg", ".oga", ".mogg"];
|
|
22
|
-
declare const OPUS_FILE_EXTENSIONS: readonly [".opus"];
|
|
23
|
-
declare const WAVE_FILE_EXTENSIONS: readonly [".wav"];
|
|
24
|
-
declare const AIFF_FILE_EXTENSIONS: readonly [".aiff"];
|
|
25
|
-
declare const FLAC_FILE_EXTENSIONS: readonly [".flac"];
|
|
26
|
-
declare const ALAC_FILE_EXTENSIONS: readonly [".alac"];
|
|
27
|
-
declare const WEBM_FILE_EXTENSIONS: readonly [".weba"];
|
|
28
18
|
type AudiobookInputs = [string, ...string[]];
|
|
29
19
|
declare class Audiobook {
|
|
30
20
|
protected metadata: AudiobookMetadata;
|
|
@@ -63,4 +53,4 @@ declare class Audiobook {
|
|
|
63
53
|
}
|
|
64
54
|
declare function getAttachedImageFromPath(path: string, kind?: AttachedPic["kind"], description?: string): Promise<AttachedPic>;
|
|
65
55
|
|
|
66
|
-
export {
|
|
56
|
+
export { Audiobook, AudiobookChapter, type AudiobookInputs, type AudiobookMetadata, getAttachedImageFromPath };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { AudiobookEntry } from './entry.js';
|
|
2
2
|
import { AttachedPic } from './ffmpeg.js';
|
|
3
3
|
import { AudiobookChapter, AudiobookResource } from './resources.js';
|
|
4
|
+
export { AAC_FILE_EXTENSIONS, AIFF_FILE_EXTENSIONS, MP3_FILE_EXTENSIONS, MPEG4_FILE_EXTENSIONS, OGG_FILE_EXTENSIONS, OPUS_FILE_EXTENSIONS, isAudioFile, isZipArchive, lookupAudioMime } from './mime.js';
|
|
4
5
|
|
|
5
6
|
interface AudiobookMetadata {
|
|
6
7
|
title?: string | null;
|
|
@@ -14,17 +15,6 @@ interface AudiobookMetadata {
|
|
|
14
15
|
publisher?: string | null;
|
|
15
16
|
releaseDate?: Date | null;
|
|
16
17
|
}
|
|
17
|
-
declare const COVER_IMAGE_FILE_EXTENSIONS: readonly [".jpeg", ".jpg", ".png", ".svg"];
|
|
18
|
-
declare const MP3_FILE_EXTENSIONS: readonly [".mp3"];
|
|
19
|
-
declare const MPEG4_FILE_EXTENSIONS: readonly [".mp4", ".m4a", ".m4b"];
|
|
20
|
-
declare const AAC_FILE_EXTENSIONS: readonly [".aac"];
|
|
21
|
-
declare const OGG_FILE_EXTENSIONS: readonly [".ogg", ".oga", ".mogg"];
|
|
22
|
-
declare const OPUS_FILE_EXTENSIONS: readonly [".opus"];
|
|
23
|
-
declare const WAVE_FILE_EXTENSIONS: readonly [".wav"];
|
|
24
|
-
declare const AIFF_FILE_EXTENSIONS: readonly [".aiff"];
|
|
25
|
-
declare const FLAC_FILE_EXTENSIONS: readonly [".flac"];
|
|
26
|
-
declare const ALAC_FILE_EXTENSIONS: readonly [".alac"];
|
|
27
|
-
declare const WEBM_FILE_EXTENSIONS: readonly [".weba"];
|
|
28
18
|
type AudiobookInputs = [string, ...string[]];
|
|
29
19
|
declare class Audiobook {
|
|
30
20
|
protected metadata: AudiobookMetadata;
|
|
@@ -63,4 +53,4 @@ declare class Audiobook {
|
|
|
63
53
|
}
|
|
64
54
|
declare function getAttachedImageFromPath(path: string, kind?: AttachedPic["kind"], description?: string): Promise<AttachedPic>;
|
|
65
55
|
|
|
66
|
-
export {
|
|
56
|
+
export { Audiobook, AudiobookChapter, type AudiobookInputs, type AudiobookMetadata, getAttachedImageFromPath };
|
package/dist/index.js
CHANGED
|
@@ -6,58 +6,24 @@ import { randomUUID } from "node:crypto";
|
|
|
6
6
|
import { createWriteStream, rmSync } from "node:fs";
|
|
7
7
|
import { cp, mkdir, readFile, readdir, rm } from "node:fs/promises";
|
|
8
8
|
import { tmpdir } from "node:os";
|
|
9
|
-
import
|
|
9
|
+
import { pipeline } from "node:stream/promises";
|
|
10
10
|
import { lookup } from "mime-types";
|
|
11
|
-
import
|
|
11
|
+
import { open } from "yauzl-promise";
|
|
12
12
|
import { ZipFile } from "yazl";
|
|
13
13
|
import { basename, dirname, extname, join } from "@storyteller-platform/path";
|
|
14
14
|
import { AudiobookEntry } from "./entry.js";
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
28
|
-
const unzipFromPath = promisify(
|
|
29
|
-
(arg, options, callback) => {
|
|
30
|
-
yauzl.open(arg, options, callback);
|
|
31
|
-
}
|
|
32
|
-
);
|
|
33
|
-
const COVER_IMAGE_FILE_EXTENSIONS = [
|
|
34
|
-
".jpeg",
|
|
35
|
-
".jpg",
|
|
36
|
-
".png",
|
|
37
|
-
".svg"
|
|
38
|
-
];
|
|
39
|
-
const MP3_FILE_EXTENSIONS = [".mp3"];
|
|
40
|
-
const MPEG4_FILE_EXTENSIONS = [".mp4", ".m4a", ".m4b"];
|
|
41
|
-
const AAC_FILE_EXTENSIONS = [".aac"];
|
|
42
|
-
const OGG_FILE_EXTENSIONS = [".ogg", ".oga", ".mogg"];
|
|
43
|
-
const OPUS_FILE_EXTENSIONS = [".opus"];
|
|
44
|
-
const WAVE_FILE_EXTENSIONS = [".wav"];
|
|
45
|
-
const AIFF_FILE_EXTENSIONS = [".aiff"];
|
|
46
|
-
const FLAC_FILE_EXTENSIONS = [".flac"];
|
|
47
|
-
const ALAC_FILE_EXTENSIONS = [".alac"];
|
|
48
|
-
const WEBM_FILE_EXTENSIONS = [".weba"];
|
|
49
|
-
const AUDIO_FILE_EXTENSIONS = [
|
|
50
|
-
...MP3_FILE_EXTENSIONS,
|
|
51
|
-
...AAC_FILE_EXTENSIONS,
|
|
52
|
-
...MPEG4_FILE_EXTENSIONS,
|
|
53
|
-
...OPUS_FILE_EXTENSIONS,
|
|
54
|
-
...OGG_FILE_EXTENSIONS,
|
|
55
|
-
...WAVE_FILE_EXTENSIONS,
|
|
56
|
-
...AIFF_FILE_EXTENSIONS,
|
|
57
|
-
...FLAC_FILE_EXTENSIONS,
|
|
58
|
-
...ALAC_FILE_EXTENSIONS,
|
|
59
|
-
...WEBM_FILE_EXTENSIONS
|
|
60
|
-
];
|
|
15
|
+
import { AUDIO_FILE_EXTENSIONS } from "./mime.js";
|
|
16
|
+
import {
|
|
17
|
+
AAC_FILE_EXTENSIONS,
|
|
18
|
+
AIFF_FILE_EXTENSIONS,
|
|
19
|
+
MP3_FILE_EXTENSIONS,
|
|
20
|
+
MPEG4_FILE_EXTENSIONS,
|
|
21
|
+
OGG_FILE_EXTENSIONS,
|
|
22
|
+
OPUS_FILE_EXTENSIONS,
|
|
23
|
+
isAudioFile,
|
|
24
|
+
isZipArchive,
|
|
25
|
+
lookupAudioMime
|
|
26
|
+
} from "./mime.js";
|
|
61
27
|
class Audiobook {
|
|
62
28
|
metadata = {};
|
|
63
29
|
inputs;
|
|
@@ -76,54 +42,47 @@ class Audiobook {
|
|
|
76
42
|
}
|
|
77
43
|
async getEntries() {
|
|
78
44
|
if (this.isZip) {
|
|
79
|
-
|
|
45
|
+
const [first] = this.inputs;
|
|
46
|
+
const extractPath = join(
|
|
47
|
+
tmpdir(),
|
|
48
|
+
`storyteller-platform-audiobook-${randomUUID()}`
|
|
49
|
+
);
|
|
50
|
+
this.extractPath = extractPath;
|
|
51
|
+
const entries = [];
|
|
80
52
|
try {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
const openReadStream = util.promisify(
|
|
99
|
-
zipfile.openReadStream.bind(zipfile)
|
|
100
|
-
);
|
|
101
|
-
zipfile.readEntry();
|
|
102
|
-
zipfile.on("entry", async (entry) => {
|
|
103
|
-
if (entry.fileName.endsWith("/")) {
|
|
104
|
-
zipfile.readEntry();
|
|
105
|
-
} else {
|
|
106
|
-
entries.push(entry.fileName);
|
|
107
|
-
const readStream = await openReadStream(entry);
|
|
108
|
-
readStream.on("end", function() {
|
|
109
|
-
zipfile.readEntry();
|
|
110
|
-
});
|
|
111
|
-
const writePath = join(extractPath, entry.fileName);
|
|
112
|
-
await mkdir(dirname(writePath), { recursive: true });
|
|
113
|
-
readStream.pipe(createWriteStream(writePath));
|
|
53
|
+
var _stack = [];
|
|
54
|
+
try {
|
|
55
|
+
const zipfile = await open(first);
|
|
56
|
+
const stack = __using(_stack, new AsyncDisposableStack(), true);
|
|
57
|
+
stack.defer(async () => {
|
|
58
|
+
await zipfile.close();
|
|
59
|
+
});
|
|
60
|
+
for await (const entry of zipfile) {
|
|
61
|
+
if (entry.filename.endsWith("/")) {
|
|
62
|
+
} else {
|
|
63
|
+
entries.push(entry.filename);
|
|
64
|
+
const readStream = await entry.openReadStream();
|
|
65
|
+
const writePath = join(extractPath, entry.filename);
|
|
66
|
+
await mkdir(dirname(writePath), { recursive: true });
|
|
67
|
+
const writeStream = createWriteStream(writePath);
|
|
68
|
+
await pipeline(readStream, writeStream);
|
|
69
|
+
}
|
|
114
70
|
}
|
|
115
|
-
})
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
(
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
} finally {
|
|
125
|
-
__callDispose(_stack, _error, _hasError);
|
|
71
|
+
} catch (_) {
|
|
72
|
+
var _error = _, _hasError = true;
|
|
73
|
+
} finally {
|
|
74
|
+
var _promise = __callDispose(_stack, _error, _hasError);
|
|
75
|
+
_promise && await _promise;
|
|
76
|
+
}
|
|
77
|
+
} catch (error) {
|
|
78
|
+
rmSync(extractPath, { force: true, recursive: true });
|
|
79
|
+
throw error;
|
|
126
80
|
}
|
|
81
|
+
return entries.filter(
|
|
82
|
+
(entry) => AUDIO_FILE_EXTENSIONS.includes(
|
|
83
|
+
extname(entry)
|
|
84
|
+
)
|
|
85
|
+
).map((entry) => new AudiobookEntry(join(extractPath, entry)));
|
|
127
86
|
} else {
|
|
128
87
|
return this.inputs.map((input) => new AudiobookEntry(input));
|
|
129
88
|
}
|
|
@@ -342,15 +301,13 @@ async function getAttachedImageFromPath(path, kind = "coverFront", description)
|
|
|
342
301
|
export {
|
|
343
302
|
AAC_FILE_EXTENSIONS,
|
|
344
303
|
AIFF_FILE_EXTENSIONS,
|
|
345
|
-
ALAC_FILE_EXTENSIONS,
|
|
346
304
|
Audiobook,
|
|
347
|
-
COVER_IMAGE_FILE_EXTENSIONS,
|
|
348
|
-
FLAC_FILE_EXTENSIONS,
|
|
349
305
|
MP3_FILE_EXTENSIONS,
|
|
350
306
|
MPEG4_FILE_EXTENSIONS,
|
|
351
307
|
OGG_FILE_EXTENSIONS,
|
|
352
308
|
OPUS_FILE_EXTENSIONS,
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
309
|
+
getAttachedImageFromPath,
|
|
310
|
+
isAudioFile,
|
|
311
|
+
isZipArchive,
|
|
312
|
+
lookupAudioMime
|
|
356
313
|
};
|
package/dist/mime.cjs
CHANGED
|
@@ -21,6 +21,7 @@ __export(mime_exports, {
|
|
|
21
21
|
AAC_FILE_EXTENSIONS: () => AAC_FILE_EXTENSIONS,
|
|
22
22
|
AIFF_FILE_EXTENSIONS: () => AIFF_FILE_EXTENSIONS,
|
|
23
23
|
ALAC_FILE_EXTENSIONS: () => ALAC_FILE_EXTENSIONS,
|
|
24
|
+
AUDIO_FILE_EXTENSIONS: () => AUDIO_FILE_EXTENSIONS,
|
|
24
25
|
COVER_IMAGE_FILE_EXTENSIONS: () => COVER_IMAGE_FILE_EXTENSIONS,
|
|
25
26
|
FLAC_FILE_EXTENSIONS: () => FLAC_FILE_EXTENSIONS,
|
|
26
27
|
MP3_FILE_EXTENSIONS: () => MP3_FILE_EXTENSIONS,
|
|
@@ -34,7 +35,12 @@ __export(mime_exports, {
|
|
|
34
35
|
lookupAudioMime: () => lookupAudioMime
|
|
35
36
|
});
|
|
36
37
|
module.exports = __toCommonJS(mime_exports);
|
|
37
|
-
const COVER_IMAGE_FILE_EXTENSIONS = [
|
|
38
|
+
const COVER_IMAGE_FILE_EXTENSIONS = [
|
|
39
|
+
".jpeg",
|
|
40
|
+
".jpg",
|
|
41
|
+
".png",
|
|
42
|
+
".svg"
|
|
43
|
+
];
|
|
38
44
|
const MP3_FILE_EXTENSIONS = [".mp3"];
|
|
39
45
|
const MPEG4_FILE_EXTENSIONS = [".mp4", ".m4a", ".m4b"];
|
|
40
46
|
const AAC_FILE_EXTENSIONS = [".aac"];
|
|
@@ -98,6 +104,7 @@ function lookupAudioMime(filenameOrExt) {
|
|
|
98
104
|
AAC_FILE_EXTENSIONS,
|
|
99
105
|
AIFF_FILE_EXTENSIONS,
|
|
100
106
|
ALAC_FILE_EXTENSIONS,
|
|
107
|
+
AUDIO_FILE_EXTENSIONS,
|
|
101
108
|
COVER_IMAGE_FILE_EXTENSIONS,
|
|
102
109
|
FLAC_FILE_EXTENSIONS,
|
|
103
110
|
MP3_FILE_EXTENSIONS,
|
package/dist/mime.d.cts
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
declare const COVER_IMAGE_FILE_EXTENSIONS:
|
|
2
|
-
declare const MP3_FILE_EXTENSIONS:
|
|
3
|
-
declare const MPEG4_FILE_EXTENSIONS:
|
|
4
|
-
declare const AAC_FILE_EXTENSIONS:
|
|
5
|
-
declare const OGG_FILE_EXTENSIONS:
|
|
6
|
-
declare const OPUS_FILE_EXTENSIONS:
|
|
7
|
-
declare const WAVE_FILE_EXTENSIONS:
|
|
8
|
-
declare const AIFF_FILE_EXTENSIONS:
|
|
9
|
-
declare const FLAC_FILE_EXTENSIONS:
|
|
10
|
-
declare const ALAC_FILE_EXTENSIONS:
|
|
11
|
-
declare const WEBM_FILE_EXTENSIONS:
|
|
1
|
+
declare const COVER_IMAGE_FILE_EXTENSIONS: readonly [".jpeg", ".jpg", ".png", ".svg"];
|
|
2
|
+
declare const MP3_FILE_EXTENSIONS: readonly [".mp3"];
|
|
3
|
+
declare const MPEG4_FILE_EXTENSIONS: readonly [".mp4", ".m4a", ".m4b"];
|
|
4
|
+
declare const AAC_FILE_EXTENSIONS: readonly [".aac"];
|
|
5
|
+
declare const OGG_FILE_EXTENSIONS: readonly [".ogg", ".oga", ".mogg"];
|
|
6
|
+
declare const OPUS_FILE_EXTENSIONS: readonly [".opus"];
|
|
7
|
+
declare const WAVE_FILE_EXTENSIONS: readonly [".wav"];
|
|
8
|
+
declare const AIFF_FILE_EXTENSIONS: readonly [".aiff"];
|
|
9
|
+
declare const FLAC_FILE_EXTENSIONS: readonly [".flac"];
|
|
10
|
+
declare const ALAC_FILE_EXTENSIONS: readonly [".alac"];
|
|
11
|
+
declare const WEBM_FILE_EXTENSIONS: readonly [".weba"];
|
|
12
|
+
declare const AUDIO_FILE_EXTENSIONS: readonly [".mp3", ".aac", ".mp4", ".m4a", ".m4b", ".opus", ".ogg", ".oga", ".mogg", ".wav", ".aiff", ".flac", ".alac", ".weba"];
|
|
12
13
|
/**
|
|
13
14
|
* Determines if a file with the given name or extension might contain audio.
|
|
14
15
|
*
|
|
@@ -37,4 +38,4 @@ declare function isZipArchive(filenameOrExt: string): boolean;
|
|
|
37
38
|
*/
|
|
38
39
|
declare function lookupAudioMime(filenameOrExt: string): string | null;
|
|
39
40
|
|
|
40
|
-
export { AAC_FILE_EXTENSIONS, AIFF_FILE_EXTENSIONS, ALAC_FILE_EXTENSIONS, COVER_IMAGE_FILE_EXTENSIONS, FLAC_FILE_EXTENSIONS, MP3_FILE_EXTENSIONS, MPEG4_FILE_EXTENSIONS, OGG_FILE_EXTENSIONS, OPUS_FILE_EXTENSIONS, WAVE_FILE_EXTENSIONS, WEBM_FILE_EXTENSIONS, isAudioFile, isZipArchive, lookupAudioMime };
|
|
41
|
+
export { AAC_FILE_EXTENSIONS, AIFF_FILE_EXTENSIONS, ALAC_FILE_EXTENSIONS, AUDIO_FILE_EXTENSIONS, COVER_IMAGE_FILE_EXTENSIONS, FLAC_FILE_EXTENSIONS, MP3_FILE_EXTENSIONS, MPEG4_FILE_EXTENSIONS, OGG_FILE_EXTENSIONS, OPUS_FILE_EXTENSIONS, WAVE_FILE_EXTENSIONS, WEBM_FILE_EXTENSIONS, isAudioFile, isZipArchive, lookupAudioMime };
|
package/dist/mime.d.ts
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
declare const COVER_IMAGE_FILE_EXTENSIONS:
|
|
2
|
-
declare const MP3_FILE_EXTENSIONS:
|
|
3
|
-
declare const MPEG4_FILE_EXTENSIONS:
|
|
4
|
-
declare const AAC_FILE_EXTENSIONS:
|
|
5
|
-
declare const OGG_FILE_EXTENSIONS:
|
|
6
|
-
declare const OPUS_FILE_EXTENSIONS:
|
|
7
|
-
declare const WAVE_FILE_EXTENSIONS:
|
|
8
|
-
declare const AIFF_FILE_EXTENSIONS:
|
|
9
|
-
declare const FLAC_FILE_EXTENSIONS:
|
|
10
|
-
declare const ALAC_FILE_EXTENSIONS:
|
|
11
|
-
declare const WEBM_FILE_EXTENSIONS:
|
|
1
|
+
declare const COVER_IMAGE_FILE_EXTENSIONS: readonly [".jpeg", ".jpg", ".png", ".svg"];
|
|
2
|
+
declare const MP3_FILE_EXTENSIONS: readonly [".mp3"];
|
|
3
|
+
declare const MPEG4_FILE_EXTENSIONS: readonly [".mp4", ".m4a", ".m4b"];
|
|
4
|
+
declare const AAC_FILE_EXTENSIONS: readonly [".aac"];
|
|
5
|
+
declare const OGG_FILE_EXTENSIONS: readonly [".ogg", ".oga", ".mogg"];
|
|
6
|
+
declare const OPUS_FILE_EXTENSIONS: readonly [".opus"];
|
|
7
|
+
declare const WAVE_FILE_EXTENSIONS: readonly [".wav"];
|
|
8
|
+
declare const AIFF_FILE_EXTENSIONS: readonly [".aiff"];
|
|
9
|
+
declare const FLAC_FILE_EXTENSIONS: readonly [".flac"];
|
|
10
|
+
declare const ALAC_FILE_EXTENSIONS: readonly [".alac"];
|
|
11
|
+
declare const WEBM_FILE_EXTENSIONS: readonly [".weba"];
|
|
12
|
+
declare const AUDIO_FILE_EXTENSIONS: readonly [".mp3", ".aac", ".mp4", ".m4a", ".m4b", ".opus", ".ogg", ".oga", ".mogg", ".wav", ".aiff", ".flac", ".alac", ".weba"];
|
|
12
13
|
/**
|
|
13
14
|
* Determines if a file with the given name or extension might contain audio.
|
|
14
15
|
*
|
|
@@ -37,4 +38,4 @@ declare function isZipArchive(filenameOrExt: string): boolean;
|
|
|
37
38
|
*/
|
|
38
39
|
declare function lookupAudioMime(filenameOrExt: string): string | null;
|
|
39
40
|
|
|
40
|
-
export { AAC_FILE_EXTENSIONS, AIFF_FILE_EXTENSIONS, ALAC_FILE_EXTENSIONS, COVER_IMAGE_FILE_EXTENSIONS, FLAC_FILE_EXTENSIONS, MP3_FILE_EXTENSIONS, MPEG4_FILE_EXTENSIONS, OGG_FILE_EXTENSIONS, OPUS_FILE_EXTENSIONS, WAVE_FILE_EXTENSIONS, WEBM_FILE_EXTENSIONS, isAudioFile, isZipArchive, lookupAudioMime };
|
|
41
|
+
export { AAC_FILE_EXTENSIONS, AIFF_FILE_EXTENSIONS, ALAC_FILE_EXTENSIONS, AUDIO_FILE_EXTENSIONS, COVER_IMAGE_FILE_EXTENSIONS, FLAC_FILE_EXTENSIONS, MP3_FILE_EXTENSIONS, MPEG4_FILE_EXTENSIONS, OGG_FILE_EXTENSIONS, OPUS_FILE_EXTENSIONS, WAVE_FILE_EXTENSIONS, WEBM_FILE_EXTENSIONS, isAudioFile, isZipArchive, lookupAudioMime };
|
package/dist/mime.js
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import "./chunk-BIEQXUOY.js";
|
|
2
|
-
const COVER_IMAGE_FILE_EXTENSIONS = [
|
|
2
|
+
const COVER_IMAGE_FILE_EXTENSIONS = [
|
|
3
|
+
".jpeg",
|
|
4
|
+
".jpg",
|
|
5
|
+
".png",
|
|
6
|
+
".svg"
|
|
7
|
+
];
|
|
3
8
|
const MP3_FILE_EXTENSIONS = [".mp3"];
|
|
4
9
|
const MPEG4_FILE_EXTENSIONS = [".mp4", ".m4a", ".m4b"];
|
|
5
10
|
const AAC_FILE_EXTENSIONS = [".aac"];
|
|
@@ -62,6 +67,7 @@ export {
|
|
|
62
67
|
AAC_FILE_EXTENSIONS,
|
|
63
68
|
AIFF_FILE_EXTENSIONS,
|
|
64
69
|
ALAC_FILE_EXTENSIONS,
|
|
70
|
+
AUDIO_FILE_EXTENSIONS,
|
|
65
71
|
COVER_IMAGE_FILE_EXTENSIONS,
|
|
66
72
|
FLAC_FILE_EXTENSIONS,
|
|
67
73
|
MP3_FILE_EXTENSIONS,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@storyteller-platform/audiobook",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.8",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -32,7 +32,9 @@
|
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@storyteller-platform/tsup": "^0.1.0",
|
|
34
34
|
"@tsconfig/strictest": "^2.0.5",
|
|
35
|
+
"@types/yauzl-promise": "^4",
|
|
35
36
|
"@types/yazl": "^3",
|
|
37
|
+
"eslint": "^8.0.0",
|
|
36
38
|
"markdown-toc": "^1.2.0",
|
|
37
39
|
"remark-toc": "^9.0.0",
|
|
38
40
|
"tsup": "^8.5.0",
|
|
@@ -43,14 +45,14 @@
|
|
|
43
45
|
"typescript": "^5.9.2"
|
|
44
46
|
},
|
|
45
47
|
"dependencies": {
|
|
46
|
-
"@storyteller-platform/
|
|
48
|
+
"@storyteller-platform/eslint": "0.1.0",
|
|
49
|
+
"@storyteller-platform/fs": "^0.1.4",
|
|
47
50
|
"@storyteller-platform/path": "^0.1.1",
|
|
48
51
|
"@types/mime-types": "^2",
|
|
49
52
|
"@types/node": "^24.0.0",
|
|
50
|
-
"@types/yauzl": "^2.10.3",
|
|
51
53
|
"mime-types": "^3.0.1",
|
|
52
54
|
"music-metadata": "^11.9.0",
|
|
53
|
-
"yauzl": "^
|
|
55
|
+
"yauzl-promise": "^4.0.0",
|
|
54
56
|
"yazl": "^3.3.1"
|
|
55
57
|
},
|
|
56
58
|
"publishConfig": {
|