@storyteller-platform/audiobook 0.3.6 → 0.3.7
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 +40 -75
- package/dist/index.js +40 -65
- 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) {
|
|
@@ -92,30 +82,12 @@ var import_node_crypto = require("node:crypto");
|
|
|
92
82
|
var import_node_fs = require("node:fs");
|
|
93
83
|
var import_promises = require("node:fs/promises");
|
|
94
84
|
var import_node_os = require("node:os");
|
|
95
|
-
var
|
|
85
|
+
var import_promises2 = require("node:stream/promises");
|
|
96
86
|
var import_mime_types = require("mime-types");
|
|
97
|
-
var
|
|
87
|
+
var import_yauzl_promise = require("yauzl-promise");
|
|
98
88
|
var import_yazl = require("yazl");
|
|
99
89
|
var import_path = require("@storyteller-platform/path");
|
|
100
90
|
var import_entry = require("./entry.cjs");
|
|
101
|
-
function promisify(api) {
|
|
102
|
-
return function(arg, options) {
|
|
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
91
|
const COVER_IMAGE_FILE_EXTENSIONS = [
|
|
120
92
|
".jpeg",
|
|
121
93
|
".jpg",
|
|
@@ -162,54 +134,47 @@ class Audiobook {
|
|
|
162
134
|
}
|
|
163
135
|
async getEntries() {
|
|
164
136
|
if (this.isZip) {
|
|
165
|
-
|
|
137
|
+
const [first] = this.inputs;
|
|
138
|
+
const extractPath = (0, import_path.join)(
|
|
139
|
+
(0, import_node_os.tmpdir)(),
|
|
140
|
+
`storyteller-platform-audiobook-${(0, import_node_crypto.randomUUID)()}`
|
|
141
|
+
);
|
|
142
|
+
this.extractPath = extractPath;
|
|
143
|
+
const entries = [];
|
|
166
144
|
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));
|
|
145
|
+
var _stack = [];
|
|
146
|
+
try {
|
|
147
|
+
const zipfile = await (0, import_yauzl_promise.open)(first);
|
|
148
|
+
const stack = __using(_stack, new AsyncDisposableStack(), true);
|
|
149
|
+
stack.defer(async () => {
|
|
150
|
+
await zipfile.close();
|
|
151
|
+
});
|
|
152
|
+
for await (const entry of zipfile) {
|
|
153
|
+
if (entry.filename.endsWith("/")) {
|
|
154
|
+
} else {
|
|
155
|
+
entries.push(entry.filename);
|
|
156
|
+
const readStream = await entry.openReadStream();
|
|
157
|
+
const writePath = (0, import_path.join)(extractPath, entry.filename);
|
|
158
|
+
await (0, import_promises.mkdir)((0, import_path.dirname)(writePath), { recursive: true });
|
|
159
|
+
const writeStream = (0, import_node_fs.createWriteStream)(writePath);
|
|
160
|
+
await (0, import_promises2.pipeline)(readStream, writeStream);
|
|
161
|
+
}
|
|
200
162
|
}
|
|
201
|
-
})
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
(
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
} finally {
|
|
211
|
-
__callDispose(_stack, _error, _hasError);
|
|
163
|
+
} catch (_) {
|
|
164
|
+
var _error = _, _hasError = true;
|
|
165
|
+
} finally {
|
|
166
|
+
var _promise = __callDispose(_stack, _error, _hasError);
|
|
167
|
+
_promise && await _promise;
|
|
168
|
+
}
|
|
169
|
+
} catch (error) {
|
|
170
|
+
(0, import_node_fs.rmSync)(extractPath, { force: true, recursive: true });
|
|
171
|
+
throw error;
|
|
212
172
|
}
|
|
173
|
+
return entries.filter(
|
|
174
|
+
(entry) => AUDIO_FILE_EXTENSIONS.includes(
|
|
175
|
+
(0, import_path.extname)(entry)
|
|
176
|
+
)
|
|
177
|
+
).map((entry) => new import_entry.AudiobookEntry((0, import_path.join)(extractPath, entry)));
|
|
213
178
|
} else {
|
|
214
179
|
return this.inputs.map((input) => new import_entry.AudiobookEntry(input));
|
|
215
180
|
}
|
package/dist/index.js
CHANGED
|
@@ -6,30 +6,12 @@ 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
|
-
function promisify(api) {
|
|
16
|
-
return function(arg, options) {
|
|
17
|
-
return new Promise(function(resolve, reject) {
|
|
18
|
-
api(arg, options, function(err, response) {
|
|
19
|
-
if (err) {
|
|
20
|
-
reject(err);
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
resolve(response);
|
|
24
|
-
});
|
|
25
|
-
});
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
const unzipFromPath = promisify(
|
|
29
|
-
(arg, options, callback) => {
|
|
30
|
-
yauzl.open(arg, options, callback);
|
|
31
|
-
}
|
|
32
|
-
);
|
|
33
15
|
const COVER_IMAGE_FILE_EXTENSIONS = [
|
|
34
16
|
".jpeg",
|
|
35
17
|
".jpg",
|
|
@@ -76,54 +58,47 @@ class Audiobook {
|
|
|
76
58
|
}
|
|
77
59
|
async getEntries() {
|
|
78
60
|
if (this.isZip) {
|
|
79
|
-
|
|
61
|
+
const [first] = this.inputs;
|
|
62
|
+
const extractPath = join(
|
|
63
|
+
tmpdir(),
|
|
64
|
+
`storyteller-platform-audiobook-${randomUUID()}`
|
|
65
|
+
);
|
|
66
|
+
this.extractPath = extractPath;
|
|
67
|
+
const entries = [];
|
|
80
68
|
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));
|
|
69
|
+
var _stack = [];
|
|
70
|
+
try {
|
|
71
|
+
const zipfile = await open(first);
|
|
72
|
+
const stack = __using(_stack, new AsyncDisposableStack(), true);
|
|
73
|
+
stack.defer(async () => {
|
|
74
|
+
await zipfile.close();
|
|
75
|
+
});
|
|
76
|
+
for await (const entry of zipfile) {
|
|
77
|
+
if (entry.filename.endsWith("/")) {
|
|
78
|
+
} else {
|
|
79
|
+
entries.push(entry.filename);
|
|
80
|
+
const readStream = await entry.openReadStream();
|
|
81
|
+
const writePath = join(extractPath, entry.filename);
|
|
82
|
+
await mkdir(dirname(writePath), { recursive: true });
|
|
83
|
+
const writeStream = createWriteStream(writePath);
|
|
84
|
+
await pipeline(readStream, writeStream);
|
|
85
|
+
}
|
|
114
86
|
}
|
|
115
|
-
})
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
(
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
} finally {
|
|
125
|
-
__callDispose(_stack, _error, _hasError);
|
|
87
|
+
} catch (_) {
|
|
88
|
+
var _error = _, _hasError = true;
|
|
89
|
+
} finally {
|
|
90
|
+
var _promise = __callDispose(_stack, _error, _hasError);
|
|
91
|
+
_promise && await _promise;
|
|
92
|
+
}
|
|
93
|
+
} catch (error) {
|
|
94
|
+
rmSync(extractPath, { force: true, recursive: true });
|
|
95
|
+
throw error;
|
|
126
96
|
}
|
|
97
|
+
return entries.filter(
|
|
98
|
+
(entry) => AUDIO_FILE_EXTENSIONS.includes(
|
|
99
|
+
extname(entry)
|
|
100
|
+
)
|
|
101
|
+
).map((entry) => new AudiobookEntry(join(extractPath, entry)));
|
|
127
102
|
} else {
|
|
128
103
|
return this.inputs.map((input) => new AudiobookEntry(input));
|
|
129
104
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@storyteller-platform/audiobook",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.7",
|
|
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": {
|