@storyteller-platform/align 0.1.56 → 0.1.58
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/align/align.cjs +38 -19
- package/dist/align/align.d.cts +12 -1
- package/dist/align/align.d.ts +12 -1
- package/dist/align/align.js +38 -19
- package/dist/align/ctc/Aligner.cjs +800 -0
- package/dist/align/ctc/Aligner.d.cts +56 -0
- package/dist/align/ctc/Aligner.d.ts +56 -0
- package/dist/align/ctc/Aligner.js +789 -0
- package/dist/align/ctc/align.cjs +189 -0
- package/dist/align/ctc/align.d.cts +14 -0
- package/dist/align/ctc/align.d.ts +14 -0
- package/dist/align/ctc/align.js +132 -0
- package/dist/{process/mime.cjs → align/ctc/emissions.cjs} +7 -20
- package/dist/align/ctc/emissions.d.cts +6 -0
- package/dist/align/ctc/emissions.d.ts +6 -0
- package/dist/align/ctc/emissions.js +7 -0
- package/dist/align/ctc/forcedAlign.cjs +273 -0
- package/dist/align/ctc/forcedAlign.d.cts +21 -0
- package/dist/align/ctc/forcedAlign.d.ts +21 -0
- package/dist/align/ctc/forcedAlign.js +248 -0
- package/dist/align/ctc/greedyDecode.cjs +61 -0
- package/dist/align/ctc/greedyDecode.d.cts +15 -0
- package/dist/align/ctc/greedyDecode.d.ts +15 -0
- package/dist/align/ctc/greedyDecode.js +37 -0
- package/dist/align/ctc/mediaOverlay.cjs +248 -0
- package/dist/align/ctc/mediaOverlay.d.cts +16 -0
- package/dist/align/ctc/mediaOverlay.d.ts +16 -0
- package/dist/align/ctc/mediaOverlay.js +224 -0
- package/dist/align/ctc/report.cjs +66 -0
- package/dist/align/ctc/report.d.cts +79 -0
- package/dist/align/ctc/report.d.ts +79 -0
- package/dist/align/ctc/report.js +42 -0
- package/dist/align/ctc/search.cjs +437 -0
- package/dist/align/ctc/search.d.cts +46 -0
- package/dist/align/ctc/search.d.ts +46 -0
- package/dist/align/ctc/search.js +412 -0
- package/dist/align/getSentenceRanges.cjs +9 -3
- package/dist/align/getSentenceRanges.d.cts +1 -0
- package/dist/align/getSentenceRanges.d.ts +1 -0
- package/dist/align/getSentenceRanges.js +9 -3
- package/dist/align/parse.cjs +17 -4
- package/dist/align/parse.d.cts +8 -4
- package/dist/align/parse.d.ts +8 -4
- package/dist/align/parse.js +19 -4
- package/dist/align/search.cjs +76 -23
- package/dist/align/search.d.cts +8 -4
- package/dist/align/search.d.ts +8 -4
- package/dist/align/search.js +76 -24
- package/dist/align/slugify.cjs +3 -2
- package/dist/align/slugify.d.cts +1 -1
- package/dist/align/slugify.d.ts +1 -1
- package/dist/align/slugify.js +3 -2
- package/dist/cli/bin.cjs +204 -114
- package/dist/cli/bin.js +194 -103
- package/dist/common/ffmpeg.cjs +10 -5
- package/dist/common/ffmpeg.js +10 -5
- package/dist/common/logging.cjs +33 -1
- package/dist/common/logging.js +33 -1
- package/dist/emit/emit.cjs +105 -0
- package/dist/emit/emit.d.cts +15 -0
- package/dist/emit/emit.d.ts +15 -0
- package/dist/emit/emit.js +86 -0
- package/dist/emit/fs.cjs +227 -0
- package/dist/emit/fs.d.cts +22 -0
- package/dist/emit/fs.d.ts +22 -0
- package/dist/emit/fs.js +162 -0
- package/dist/emit/parse.cjs +68 -0
- package/dist/emit/parse.d.cts +26 -0
- package/dist/emit/parse.d.ts +26 -0
- package/dist/emit/parse.js +58 -0
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/markup/model.cjs +0 -16
- package/dist/markup/model.d.cts +1 -1
- package/dist/markup/model.d.ts +1 -1
- package/dist/markup/model.js +0 -12
- package/dist/markup/parseDom.cjs +13 -14
- package/dist/markup/parseDom.d.cts +2 -2
- package/dist/markup/parseDom.d.ts +2 -2
- package/dist/markup/parseDom.js +13 -18
- package/dist/markup/resolvedPos.d.cts +1 -1
- package/dist/markup/resolvedPos.d.ts +1 -1
- package/dist/markup/segmentation.cjs +3 -1
- package/dist/markup/segmentation.js +3 -1
- package/dist/markup/serializeDom.cjs +1 -1
- package/dist/markup/serializeDom.d.cts +1 -1
- package/dist/markup/serializeDom.d.ts +1 -1
- package/dist/markup/serializeDom.js +1 -1
- package/dist/markup/transform.cjs +5 -2
- package/dist/markup/transform.d.cts +1 -1
- package/dist/markup/transform.d.ts +1 -1
- package/dist/markup/transform.js +5 -4
- package/dist/{model-CZ2mMHJO.d.cts → model-CeOMDDgt.d.cts} +3 -11
- package/dist/{model-CZ2mMHJO.d.ts → model-CeOMDDgt.d.ts} +3 -11
- package/dist/process/processAudiobook.cjs +12 -23
- package/dist/process/processAudiobook.js +14 -30
- package/dist/process/ranges.cjs +2 -2
- package/dist/process/ranges.js +2 -2
- package/dist/readium/guidedNavigation.cjs +8 -8
- package/dist/readium/guidedNavigation.js +8 -8
- package/dist/readium/manifest.cjs +5 -4
- package/dist/readium/manifest.js +5 -4
- package/dist/snapshot/ctc/snapshot.cjs +261 -0
- package/dist/snapshot/ctc/snapshot.d.cts +6 -0
- package/dist/snapshot/ctc/snapshot.d.ts +6 -0
- package/dist/snapshot/ctc/snapshot.js +200 -0
- package/dist/snapshot/parse.cjs +29 -16
- package/dist/snapshot/parse.d.cts +14 -10
- package/dist/snapshot/parse.d.ts +14 -10
- package/dist/snapshot/parse.js +32 -17
- package/dist/transcribe/parse.d.cts +6 -6
- package/dist/transcribe/parse.d.ts +6 -6
- package/dist/transcribe/transcribe.cjs +4 -2
- package/dist/transcribe/transcribe.js +4 -2
- package/package.json +6 -4
- package/dist/process/mime.d.cts +0 -3
- package/dist/process/mime.d.ts +0 -3
- package/dist/process/mime.js +0 -24
|
@@ -0,0 +1,189 @@
|
|
|
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 __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : Symbol.for("Symbol." + name);
|
|
7
|
+
var __typeError = (msg) => {
|
|
8
|
+
throw TypeError(msg);
|
|
9
|
+
};
|
|
10
|
+
var __export = (target, all) => {
|
|
11
|
+
for (var name in all)
|
|
12
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
13
|
+
};
|
|
14
|
+
var __copyProps = (to, from, except, desc) => {
|
|
15
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
16
|
+
for (let key of __getOwnPropNames(from))
|
|
17
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
18
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
19
|
+
}
|
|
20
|
+
return to;
|
|
21
|
+
};
|
|
22
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
23
|
+
var __using = (stack, value, async) => {
|
|
24
|
+
if (value != null) {
|
|
25
|
+
if (typeof value !== "object" && typeof value !== "function") __typeError("Object expected");
|
|
26
|
+
var dispose, inner;
|
|
27
|
+
if (async) dispose = value[__knownSymbol("asyncDispose")];
|
|
28
|
+
if (dispose === void 0) {
|
|
29
|
+
dispose = value[__knownSymbol("dispose")];
|
|
30
|
+
if (async) inner = dispose;
|
|
31
|
+
}
|
|
32
|
+
if (typeof dispose !== "function") __typeError("Object not disposable");
|
|
33
|
+
if (inner) dispose = function() {
|
|
34
|
+
try {
|
|
35
|
+
inner.call(this);
|
|
36
|
+
} catch (e) {
|
|
37
|
+
return Promise.reject(e);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
stack.push([async, dispose, value]);
|
|
41
|
+
} else if (async) {
|
|
42
|
+
stack.push([async]);
|
|
43
|
+
}
|
|
44
|
+
return value;
|
|
45
|
+
};
|
|
46
|
+
var __callDispose = (stack, error, hasError) => {
|
|
47
|
+
var E = typeof SuppressedError === "function" ? SuppressedError : function(e, s, m, _) {
|
|
48
|
+
return _ = Error(m), _.name = "SuppressedError", _.error = e, _.suppressed = s, _;
|
|
49
|
+
};
|
|
50
|
+
var fail = (e) => error = hasError ? new E(e, error, "An error was suppressed during disposal") : (hasError = true, e);
|
|
51
|
+
var next = (it) => {
|
|
52
|
+
while (it = stack.pop()) {
|
|
53
|
+
try {
|
|
54
|
+
var result = it[1] && it[1].call(it[2]);
|
|
55
|
+
if (it[0]) return Promise.resolve(result).then(next, (e) => (fail(e), next()));
|
|
56
|
+
} catch (e) {
|
|
57
|
+
fail(e);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (hasError) throw error;
|
|
61
|
+
};
|
|
62
|
+
return next();
|
|
63
|
+
};
|
|
64
|
+
var align_exports = {};
|
|
65
|
+
__export(align_exports, {
|
|
66
|
+
ctcAlign: () => ctcAlign
|
|
67
|
+
});
|
|
68
|
+
module.exports = __toCommonJS(align_exports);
|
|
69
|
+
var import_node_crypto = require("node:crypto");
|
|
70
|
+
var import_node_fs = require("node:fs");
|
|
71
|
+
var import_promises = require("node:fs/promises");
|
|
72
|
+
var import_node_path = require("node:path");
|
|
73
|
+
var import_shared = require("@readium/shared");
|
|
74
|
+
var import_yazl = require("yazl");
|
|
75
|
+
var import_epub = require("@storyteller-platform/epub");
|
|
76
|
+
var import_fs = require("@storyteller-platform/fs");
|
|
77
|
+
var import_media_types = require("@storyteller-platform/media-types");
|
|
78
|
+
var import_fs2 = require("../../emit/fs.cjs");
|
|
79
|
+
var import_guidedNavigation = require("../../readium/guidedNavigation.cjs");
|
|
80
|
+
var import_Aligner = require("./Aligner.cjs");
|
|
81
|
+
async function ctcAlign(input, output, emissionsDir, audiobookDir, options) {
|
|
82
|
+
var _stack2 = [];
|
|
83
|
+
try {
|
|
84
|
+
const outFormat = options.outFormat ?? "epub";
|
|
85
|
+
const epubPath = outFormat === "epub" ? (0, import_fs.scratchPath)(
|
|
86
|
+
`storyteller-platform-align-${(0, import_node_crypto.randomUUID)()}`,
|
|
87
|
+
(0, import_node_path.basename)(output)
|
|
88
|
+
) : input;
|
|
89
|
+
const stack = __using(_stack2, new DisposableStack());
|
|
90
|
+
stack.defer(() => {
|
|
91
|
+
if (outFormat === "epub") {
|
|
92
|
+
try {
|
|
93
|
+
(0, import_node_fs.rmSync)((0, import_node_path.dirname)(epubPath), { recursive: true, force: true });
|
|
94
|
+
} catch {
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
if (outFormat === "epub") {
|
|
99
|
+
await (0, import_promises.mkdir)((0, import_node_path.dirname)(epubPath), { recursive: true });
|
|
100
|
+
await (0, import_promises.copyFile)(input, epubPath);
|
|
101
|
+
}
|
|
102
|
+
const audiobookFiles = await (0, import_promises.readdir)(audiobookDir).then(
|
|
103
|
+
(filenames) => filenames.filter((f) => import_media_types.MediaType.fromPath(f)?.kind === "audio").toSorted().map((f) => (0, import_node_path.join)(audiobookDir, f))
|
|
104
|
+
);
|
|
105
|
+
const epub = __using(_stack2, await import_epub.Epub.from(epubPath));
|
|
106
|
+
const emissions = await import_fs2.EmissionsReader.from(emissionsDir);
|
|
107
|
+
const aligner = new import_Aligner.Aligner(
|
|
108
|
+
epub,
|
|
109
|
+
audiobookFiles,
|
|
110
|
+
emissions,
|
|
111
|
+
options.granularity,
|
|
112
|
+
options.textRef,
|
|
113
|
+
options.primaryLocale,
|
|
114
|
+
options.logger
|
|
115
|
+
);
|
|
116
|
+
const timing = await aligner.alignBook(options.onProgress);
|
|
117
|
+
if (outFormat === "epub") {
|
|
118
|
+
await epub.saveAndClose();
|
|
119
|
+
await (0, import_promises.mkdir)((0, import_node_path.dirname)(output), { recursive: true });
|
|
120
|
+
await (0, import_promises.copyFile)(epubPath, output);
|
|
121
|
+
} else {
|
|
122
|
+
var _stack = [];
|
|
123
|
+
try {
|
|
124
|
+
const guidedNavigationDocuments = await (0, import_guidedNavigation.generateGuidedNavigationDocuments)(epub);
|
|
125
|
+
const manifest = (0, import_guidedNavigation.generateGuidedNavigationManifest)(
|
|
126
|
+
new import_shared.LocalizedString(
|
|
127
|
+
await epub.getTitle() ?? (0, import_node_path.basename)(input, (0, import_node_path.extname)(input))
|
|
128
|
+
),
|
|
129
|
+
guidedNavigationDocuments
|
|
130
|
+
);
|
|
131
|
+
const tmpArchivePath = (0, import_fs.scratchPath)(
|
|
132
|
+
`storyteller-platform-epub-${(0, import_node_crypto.randomUUID)()}`
|
|
133
|
+
);
|
|
134
|
+
const { promise, resolve } = Promise.withResolvers();
|
|
135
|
+
const zipfile = new import_yazl.ZipFile();
|
|
136
|
+
const writeStream = (0, import_node_fs.createWriteStream)(tmpArchivePath);
|
|
137
|
+
writeStream.on("close", () => {
|
|
138
|
+
resolve();
|
|
139
|
+
});
|
|
140
|
+
const stack2 = __using(_stack, new AsyncDisposableStack(), true);
|
|
141
|
+
stack2.defer(async () => {
|
|
142
|
+
writeStream.close();
|
|
143
|
+
await (0, import_promises.rm)(tmpArchivePath, { force: true });
|
|
144
|
+
});
|
|
145
|
+
zipfile.outputStream.pipe(writeStream);
|
|
146
|
+
zipfile.addBuffer(
|
|
147
|
+
Buffer.from(JSON.stringify(manifest.serialize())),
|
|
148
|
+
"manifest.json"
|
|
149
|
+
);
|
|
150
|
+
for (const doc of guidedNavigationDocuments) {
|
|
151
|
+
const selfLink = doc.links?.findWithRel("self");
|
|
152
|
+
if (!selfLink) continue;
|
|
153
|
+
zipfile.addBuffer(
|
|
154
|
+
Buffer.from(JSON.stringify(doc.serialize())),
|
|
155
|
+
selfLink.href
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
zipfile.end();
|
|
159
|
+
await promise;
|
|
160
|
+
await (0, import_promises.cp)(tmpArchivePath, output);
|
|
161
|
+
epub.discardAndClose();
|
|
162
|
+
} catch (_) {
|
|
163
|
+
var _error = _, _hasError = true;
|
|
164
|
+
} finally {
|
|
165
|
+
var _promise = __callDispose(_stack, _error, _hasError);
|
|
166
|
+
_promise && await _promise;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
if (options.reportsPath) {
|
|
170
|
+
await (0, import_promises.mkdir)((0, import_node_path.dirname)(options.reportsPath), { recursive: true });
|
|
171
|
+
await (0, import_promises.writeFile)(
|
|
172
|
+
options.reportsPath,
|
|
173
|
+
JSON.stringify(aligner.report, null, 2),
|
|
174
|
+
{
|
|
175
|
+
encoding: "utf-8"
|
|
176
|
+
}
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
return timing;
|
|
180
|
+
} catch (_2) {
|
|
181
|
+
var _error2 = _2, _hasError2 = true;
|
|
182
|
+
} finally {
|
|
183
|
+
__callDispose(_stack2, _error2, _hasError2);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
187
|
+
0 && (module.exports = {
|
|
188
|
+
ctcAlign
|
|
189
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as _storyteller_platform_ghost_story from '@storyteller-platform/ghost-story';
|
|
2
|
+
import { AlignOptions } from './Aligner.cjs';
|
|
3
|
+
import 'pino';
|
|
4
|
+
import '@storyteller-platform/epub';
|
|
5
|
+
import '../../emit/fs.cjs';
|
|
6
|
+
import './emissions.cjs';
|
|
7
|
+
import './report.cjs';
|
|
8
|
+
import '../getSentenceRanges.cjs';
|
|
9
|
+
import '@echogarden/text-segmentation';
|
|
10
|
+
import '@storyteller-platform/mapping';
|
|
11
|
+
|
|
12
|
+
declare function ctcAlign(input: string, output: string, emissionsDir: string, audiobookDir: string, options: AlignOptions): Promise<_storyteller_platform_ghost_story.TimingAggregator>;
|
|
13
|
+
|
|
14
|
+
export { ctcAlign };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as _storyteller_platform_ghost_story from '@storyteller-platform/ghost-story';
|
|
2
|
+
import { AlignOptions } from './Aligner.js';
|
|
3
|
+
import 'pino';
|
|
4
|
+
import '@storyteller-platform/epub';
|
|
5
|
+
import '../../emit/fs.js';
|
|
6
|
+
import './emissions.js';
|
|
7
|
+
import './report.js';
|
|
8
|
+
import '../getSentenceRanges.js';
|
|
9
|
+
import '@echogarden/text-segmentation';
|
|
10
|
+
import '@storyteller-platform/mapping';
|
|
11
|
+
|
|
12
|
+
declare function ctcAlign(input: string, output: string, emissionsDir: string, audiobookDir: string, options: AlignOptions): Promise<_storyteller_platform_ghost_story.TimingAggregator>;
|
|
13
|
+
|
|
14
|
+
export { ctcAlign };
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__callDispose,
|
|
3
|
+
__using
|
|
4
|
+
} from "../../chunk-BIEQXUOY.js";
|
|
5
|
+
import { randomUUID } from "node:crypto";
|
|
6
|
+
import { createWriteStream, rmSync } from "node:fs";
|
|
7
|
+
import { copyFile, cp, mkdir, readdir, rm, writeFile } from "node:fs/promises";
|
|
8
|
+
import {
|
|
9
|
+
basename as autoBasename,
|
|
10
|
+
dirname as autoDirname,
|
|
11
|
+
extname,
|
|
12
|
+
join as autoJoin
|
|
13
|
+
} from "node:path";
|
|
14
|
+
import { LocalizedString } from "@readium/shared";
|
|
15
|
+
import { ZipFile } from "yazl";
|
|
16
|
+
import { Epub } from "@storyteller-platform/epub";
|
|
17
|
+
import { scratchPath } from "@storyteller-platform/fs";
|
|
18
|
+
import { MediaType } from "@storyteller-platform/media-types";
|
|
19
|
+
import { EmissionsReader } from "../../emit/fs.js";
|
|
20
|
+
import {
|
|
21
|
+
generateGuidedNavigationDocuments,
|
|
22
|
+
generateGuidedNavigationManifest
|
|
23
|
+
} from "../../readium/guidedNavigation.js";
|
|
24
|
+
import { Aligner } from "./Aligner.js";
|
|
25
|
+
async function ctcAlign(input, output, emissionsDir, audiobookDir, options) {
|
|
26
|
+
var _stack2 = [];
|
|
27
|
+
try {
|
|
28
|
+
const outFormat = options.outFormat ?? "epub";
|
|
29
|
+
const epubPath = outFormat === "epub" ? scratchPath(
|
|
30
|
+
`storyteller-platform-align-${randomUUID()}`,
|
|
31
|
+
autoBasename(output)
|
|
32
|
+
) : input;
|
|
33
|
+
const stack = __using(_stack2, new DisposableStack());
|
|
34
|
+
stack.defer(() => {
|
|
35
|
+
if (outFormat === "epub") {
|
|
36
|
+
try {
|
|
37
|
+
rmSync(autoDirname(epubPath), { recursive: true, force: true });
|
|
38
|
+
} catch {
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
if (outFormat === "epub") {
|
|
43
|
+
await mkdir(autoDirname(epubPath), { recursive: true });
|
|
44
|
+
await copyFile(input, epubPath);
|
|
45
|
+
}
|
|
46
|
+
const audiobookFiles = await readdir(audiobookDir).then(
|
|
47
|
+
(filenames) => filenames.filter((f) => MediaType.fromPath(f)?.kind === "audio").toSorted().map((f) => autoJoin(audiobookDir, f))
|
|
48
|
+
);
|
|
49
|
+
const epub = __using(_stack2, await Epub.from(epubPath));
|
|
50
|
+
const emissions = await EmissionsReader.from(emissionsDir);
|
|
51
|
+
const aligner = new Aligner(
|
|
52
|
+
epub,
|
|
53
|
+
audiobookFiles,
|
|
54
|
+
emissions,
|
|
55
|
+
options.granularity,
|
|
56
|
+
options.textRef,
|
|
57
|
+
options.primaryLocale,
|
|
58
|
+
options.logger
|
|
59
|
+
);
|
|
60
|
+
const timing = await aligner.alignBook(options.onProgress);
|
|
61
|
+
if (outFormat === "epub") {
|
|
62
|
+
await epub.saveAndClose();
|
|
63
|
+
await mkdir(autoDirname(output), { recursive: true });
|
|
64
|
+
await copyFile(epubPath, output);
|
|
65
|
+
} else {
|
|
66
|
+
var _stack = [];
|
|
67
|
+
try {
|
|
68
|
+
const guidedNavigationDocuments = await generateGuidedNavigationDocuments(epub);
|
|
69
|
+
const manifest = generateGuidedNavigationManifest(
|
|
70
|
+
new LocalizedString(
|
|
71
|
+
await epub.getTitle() ?? autoBasename(input, extname(input))
|
|
72
|
+
),
|
|
73
|
+
guidedNavigationDocuments
|
|
74
|
+
);
|
|
75
|
+
const tmpArchivePath = scratchPath(
|
|
76
|
+
`storyteller-platform-epub-${randomUUID()}`
|
|
77
|
+
);
|
|
78
|
+
const { promise, resolve } = Promise.withResolvers();
|
|
79
|
+
const zipfile = new ZipFile();
|
|
80
|
+
const writeStream = createWriteStream(tmpArchivePath);
|
|
81
|
+
writeStream.on("close", () => {
|
|
82
|
+
resolve();
|
|
83
|
+
});
|
|
84
|
+
const stack2 = __using(_stack, new AsyncDisposableStack(), true);
|
|
85
|
+
stack2.defer(async () => {
|
|
86
|
+
writeStream.close();
|
|
87
|
+
await rm(tmpArchivePath, { force: true });
|
|
88
|
+
});
|
|
89
|
+
zipfile.outputStream.pipe(writeStream);
|
|
90
|
+
zipfile.addBuffer(
|
|
91
|
+
Buffer.from(JSON.stringify(manifest.serialize())),
|
|
92
|
+
"manifest.json"
|
|
93
|
+
);
|
|
94
|
+
for (const doc of guidedNavigationDocuments) {
|
|
95
|
+
const selfLink = doc.links?.findWithRel("self");
|
|
96
|
+
if (!selfLink) continue;
|
|
97
|
+
zipfile.addBuffer(
|
|
98
|
+
Buffer.from(JSON.stringify(doc.serialize())),
|
|
99
|
+
selfLink.href
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
zipfile.end();
|
|
103
|
+
await promise;
|
|
104
|
+
await cp(tmpArchivePath, output);
|
|
105
|
+
epub.discardAndClose();
|
|
106
|
+
} catch (_) {
|
|
107
|
+
var _error = _, _hasError = true;
|
|
108
|
+
} finally {
|
|
109
|
+
var _promise = __callDispose(_stack, _error, _hasError);
|
|
110
|
+
_promise && await _promise;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
if (options.reportsPath) {
|
|
114
|
+
await mkdir(autoDirname(options.reportsPath), { recursive: true });
|
|
115
|
+
await writeFile(
|
|
116
|
+
options.reportsPath,
|
|
117
|
+
JSON.stringify(aligner.report, null, 2),
|
|
118
|
+
{
|
|
119
|
+
encoding: "utf-8"
|
|
120
|
+
}
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
return timing;
|
|
124
|
+
} catch (_2) {
|
|
125
|
+
var _error2 = _2, _hasError2 = true;
|
|
126
|
+
} finally {
|
|
127
|
+
__callDispose(_stack2, _error2, _hasError2);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
export {
|
|
131
|
+
ctcAlign
|
|
132
|
+
};
|
|
@@ -16,28 +16,15 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
16
16
|
return to;
|
|
17
17
|
};
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
-
var
|
|
20
|
-
__export(
|
|
21
|
-
|
|
19
|
+
var emissions_exports = {};
|
|
20
|
+
__export(emissions_exports, {
|
|
21
|
+
framesToSeconds: () => framesToSeconds
|
|
22
22
|
});
|
|
23
|
-
module.exports = __toCommonJS(
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
if (filepathA === filepathB) {
|
|
27
|
-
return true;
|
|
28
|
-
}
|
|
29
|
-
if (import_audiobook.MPEG4_FILE_EXTENSIONS.some((ext) => filepathA.endsWith(ext)) && import_audiobook.MPEG4_FILE_EXTENSIONS.some((ext) => filepathB.endsWith(ext))) {
|
|
30
|
-
return true;
|
|
31
|
-
}
|
|
32
|
-
if (import_audiobook.MP3_FILE_EXTENSIONS.some((ext) => filepathA.endsWith(ext)) && import_audiobook.MP3_FILE_EXTENSIONS.some((ext) => filepathB.endsWith(ext))) {
|
|
33
|
-
return true;
|
|
34
|
-
}
|
|
35
|
-
if (import_audiobook.OPUS_FILE_EXTENSIONS.some((ext) => filepathA.endsWith(ext)) && import_audiobook.OPUS_FILE_EXTENSIONS.some((ext) => filepathB.endsWith(ext))) {
|
|
36
|
-
return true;
|
|
37
|
-
}
|
|
38
|
-
return false;
|
|
23
|
+
module.exports = __toCommonJS(emissions_exports);
|
|
24
|
+
function framesToSeconds(frames, emissionTimings) {
|
|
25
|
+
return Math.floor(frames / emissionTimings.framesPerChunk) * emissionTimings.secondsPerChunk + frames % emissionTimings.framesPerChunk * emissionTimings.secondsPerFrame;
|
|
39
26
|
}
|
|
40
27
|
// Annotate the CommonJS export names for ESM import in node:
|
|
41
28
|
0 && (module.exports = {
|
|
42
|
-
|
|
29
|
+
framesToSeconds
|
|
43
30
|
});
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { EmissionResult } from '@storyteller-platform/ghost-story';
|
|
2
|
+
|
|
3
|
+
type EmissionTimings = Pick<EmissionResult, "secondsPerChunk" | "secondsPerFrame" | "framesPerChunk">;
|
|
4
|
+
declare function framesToSeconds(frames: number, emissionTimings: EmissionTimings): number;
|
|
5
|
+
|
|
6
|
+
export { type EmissionTimings, framesToSeconds };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { EmissionResult } from '@storyteller-platform/ghost-story';
|
|
2
|
+
|
|
3
|
+
type EmissionTimings = Pick<EmissionResult, "secondsPerChunk" | "secondsPerFrame" | "framesPerChunk">;
|
|
4
|
+
declare function framesToSeconds(frames: number, emissionTimings: EmissionTimings): number;
|
|
5
|
+
|
|
6
|
+
export { type EmissionTimings, framesToSeconds };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import "../../chunk-BIEQXUOY.js";
|
|
2
|
+
function framesToSeconds(frames, emissionTimings) {
|
|
3
|
+
return Math.floor(frames / emissionTimings.framesPerChunk) * emissionTimings.secondsPerChunk + frames % emissionTimings.framesPerChunk * emissionTimings.secondsPerFrame;
|
|
4
|
+
}
|
|
5
|
+
export {
|
|
6
|
+
framesToSeconds
|
|
7
|
+
};
|
|
@@ -0,0 +1,273 @@
|
|
|
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 forcedAlign_exports = {};
|
|
20
|
+
__export(forcedAlign_exports, {
|
|
21
|
+
ctcForcedAlign: () => ctcForcedAlign,
|
|
22
|
+
ctcViterbiAlign: () => ctcViterbiAlign,
|
|
23
|
+
detectDroppedLabels: () => detectDroppedLabels
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(forcedAlign_exports);
|
|
26
|
+
var import_itertools = require("itertools");
|
|
27
|
+
function buildStateGraph(labels, starId, blankId) {
|
|
28
|
+
const tokens = [blankId].concat(labels.flatMap((l) => [l, blankId]));
|
|
29
|
+
const skipLegal = tokens.map(
|
|
30
|
+
(t, i) => i >= 2 && (t !== tokens[i - 2] || t === starId)
|
|
31
|
+
);
|
|
32
|
+
return { tokens, skipLegal };
|
|
33
|
+
}
|
|
34
|
+
function ctcViterbiAlign(emissions, labels, blankId, starId, starScore) {
|
|
35
|
+
if (!labels.length) return [];
|
|
36
|
+
function emitScore(row, token) {
|
|
37
|
+
return token === starId ? starScore : row[token];
|
|
38
|
+
}
|
|
39
|
+
const { tokens, skipLegal } = buildStateGraph(labels, starId, blankId);
|
|
40
|
+
const numStates = tokens.length;
|
|
41
|
+
const numFrames = emissions.length;
|
|
42
|
+
if (!numFrames) return [];
|
|
43
|
+
let prevScores = new Float32Array(numStates).fill(-Infinity);
|
|
44
|
+
const backpointers = new Uint8Array(numFrames * numStates);
|
|
45
|
+
prevScores[0] = emissions[0][blankId];
|
|
46
|
+
prevScores[1] = emitScore(emissions[0], tokens[1]);
|
|
47
|
+
if (labels[0] === starId) {
|
|
48
|
+
prevScores[2] = emissions[0][blankId];
|
|
49
|
+
prevScores[3] = emitScore(emissions[0], tokens[3]);
|
|
50
|
+
}
|
|
51
|
+
for (let t = 1; t < numFrames; t++) {
|
|
52
|
+
const row = emissions[t];
|
|
53
|
+
const currScores = new Float32Array(numStates).fill(-Infinity);
|
|
54
|
+
for (let s = 0; s < numStates; s++) {
|
|
55
|
+
const token = tokens[s];
|
|
56
|
+
let best = prevScores[s];
|
|
57
|
+
let bestOp = 0;
|
|
58
|
+
if (s > 0) {
|
|
59
|
+
const move = prevScores[s - 1];
|
|
60
|
+
if (move > best) {
|
|
61
|
+
best = move;
|
|
62
|
+
bestOp = 1;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (skipLegal[s]) {
|
|
66
|
+
const move = prevScores[s - 2];
|
|
67
|
+
if (move > best) {
|
|
68
|
+
best = move;
|
|
69
|
+
bestOp = 2;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
currScores[s] = emitScore(row, token) + best;
|
|
73
|
+
backpointers[t * numStates + s] = bestOp;
|
|
74
|
+
}
|
|
75
|
+
prevScores = currScores;
|
|
76
|
+
}
|
|
77
|
+
const terminalCandidates = [
|
|
78
|
+
numStates - 1,
|
|
79
|
+
numStates - 2,
|
|
80
|
+
// Same as above, only allow skipping the last label
|
|
81
|
+
// if it's a star
|
|
82
|
+
...labels.at(-1) === starId ? [numStates - 3, numStates - 4] : []
|
|
83
|
+
].filter((s) => s >= 0);
|
|
84
|
+
let terminal = terminalCandidates[0];
|
|
85
|
+
for (const s of terminalCandidates) {
|
|
86
|
+
if (prevScores[s] > prevScores[terminal]) terminal = s;
|
|
87
|
+
}
|
|
88
|
+
if (prevScores[terminal] === -Infinity) {
|
|
89
|
+
return labels.map((label) => ({
|
|
90
|
+
label,
|
|
91
|
+
startFrame: -1,
|
|
92
|
+
endFrame: -1,
|
|
93
|
+
score: -Infinity
|
|
94
|
+
}));
|
|
95
|
+
}
|
|
96
|
+
const path = new Int32Array(numFrames);
|
|
97
|
+
path[numFrames - 1] = terminal;
|
|
98
|
+
for (let t = numFrames - 1; t > 0; t--) {
|
|
99
|
+
const s = path[t];
|
|
100
|
+
const op = backpointers[t * numStates + s];
|
|
101
|
+
path[t - 1] = s - op;
|
|
102
|
+
}
|
|
103
|
+
const firstFrames = new Int32Array(numStates).fill(-1);
|
|
104
|
+
const lastFrames = new Int32Array(numStates).fill(-1);
|
|
105
|
+
const scoreSums = new Float64Array(numStates);
|
|
106
|
+
const frameCounts = new Int32Array(numStates);
|
|
107
|
+
for (let t = 0; t < numFrames; t++) {
|
|
108
|
+
const s = path[t];
|
|
109
|
+
if (firstFrames[s] === -1) firstFrames[s] = t;
|
|
110
|
+
lastFrames[s] = t;
|
|
111
|
+
const row = emissions[t];
|
|
112
|
+
const token = tokens[s];
|
|
113
|
+
scoreSums[s] += emitScore(row, token);
|
|
114
|
+
frameCounts[s]++;
|
|
115
|
+
}
|
|
116
|
+
const alignments = [];
|
|
117
|
+
for (let l = 0; l < labels.length; l++) {
|
|
118
|
+
const state = 2 * l + 1;
|
|
119
|
+
const startFrame = firstFrames[state];
|
|
120
|
+
const endFrame = lastFrames[state];
|
|
121
|
+
const scoreSum = scoreSums[state];
|
|
122
|
+
const frameCount = frameCounts[state];
|
|
123
|
+
const meanScore = frameCount > 0 ? scoreSum / frameCount : -Infinity;
|
|
124
|
+
alignments.push({
|
|
125
|
+
label: labels[l],
|
|
126
|
+
startFrame,
|
|
127
|
+
endFrame,
|
|
128
|
+
score: meanScore
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
return alignments;
|
|
132
|
+
}
|
|
133
|
+
function detectDroppedLabels(alignments, startOffset, endOffset, minLength = 8) {
|
|
134
|
+
if (endOffset < startOffset || endOffset - startOffset <= minLength) {
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
const endFrame = alignments[endOffset]?.endFrame;
|
|
138
|
+
if (endFrame === void 0) {
|
|
139
|
+
throw new Error(`endOffset ${endOffset} out of bounds`);
|
|
140
|
+
}
|
|
141
|
+
const startFrame = alignments[startOffset]?.startFrame;
|
|
142
|
+
if (startFrame === void 0) {
|
|
143
|
+
throw new Error(`startOffset ${startOffset} out of bounds`);
|
|
144
|
+
}
|
|
145
|
+
const framesPerChar = (endFrame - startFrame) / (endOffset - startOffset);
|
|
146
|
+
return framesPerChar < 2;
|
|
147
|
+
}
|
|
148
|
+
function removeLabelRanges(input, removals) {
|
|
149
|
+
const inputIndices = [];
|
|
150
|
+
let nextRemovalIndex = 0;
|
|
151
|
+
const result = [];
|
|
152
|
+
let i = 0;
|
|
153
|
+
while (i < input.length) {
|
|
154
|
+
const l = input[i];
|
|
155
|
+
const nextRemoval = removals[nextRemovalIndex];
|
|
156
|
+
if (!nextRemoval) {
|
|
157
|
+
inputIndices.push(i);
|
|
158
|
+
result.push(l);
|
|
159
|
+
i++;
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
if (i >= nextRemoval[0] && i <= nextRemoval[1]) {
|
|
163
|
+
i++;
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
if (i > nextRemoval[1]) {
|
|
167
|
+
nextRemovalIndex++;
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
inputIndices.push(i);
|
|
171
|
+
result.push(l);
|
|
172
|
+
i++;
|
|
173
|
+
}
|
|
174
|
+
return { result, inputIndices };
|
|
175
|
+
}
|
|
176
|
+
const STAR_SCORE = -3;
|
|
177
|
+
function ctcForcedAlign(baseline, emissions, anchors, vocab, blankId, dropLabels = () => []) {
|
|
178
|
+
const star = vocab.size;
|
|
179
|
+
const segments = [];
|
|
180
|
+
for (let i = 0; i < anchors.length + 1; i++) {
|
|
181
|
+
const prevAnchor = anchors[i - 1];
|
|
182
|
+
const nextAnchor = anchors[i];
|
|
183
|
+
segments.push({
|
|
184
|
+
labels: baseline.slice(prevAnchor?.offset, nextAnchor?.offset).split("").map((c) => vocab.get(c) ?? star),
|
|
185
|
+
labelsStart: prevAnchor?.offset ?? 0,
|
|
186
|
+
emissions: emissions.slice(prevAnchor?.position, nextAnchor?.position),
|
|
187
|
+
emissionsStart: prevAnchor?.position ?? 0
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
segments[0]?.labels.unshift(star);
|
|
191
|
+
segments.at(-1)?.labels.push(star);
|
|
192
|
+
const alignmentsWithRemovals = [];
|
|
193
|
+
const inputIndices = [];
|
|
194
|
+
for (const segment of segments) {
|
|
195
|
+
let stripBoundingStars2 = function(arr) {
|
|
196
|
+
let result = arr;
|
|
197
|
+
if (segment === segments[0]) {
|
|
198
|
+
result = result.slice(1);
|
|
199
|
+
}
|
|
200
|
+
if (segment === segments.at(-1)) {
|
|
201
|
+
result = result.slice(0, -1);
|
|
202
|
+
}
|
|
203
|
+
return result;
|
|
204
|
+
};
|
|
205
|
+
var stripBoundingStars = stripBoundingStars2;
|
|
206
|
+
let indices = Array.from((0, import_itertools.range)(stripBoundingStars2(segment.labels).length));
|
|
207
|
+
let unmapped = ctcViterbiAlign(
|
|
208
|
+
segment.emissions,
|
|
209
|
+
segment.labels,
|
|
210
|
+
blankId,
|
|
211
|
+
star,
|
|
212
|
+
STAR_SCORE
|
|
213
|
+
);
|
|
214
|
+
const dropped = dropLabels(
|
|
215
|
+
segment.labelsStart,
|
|
216
|
+
stripBoundingStars2(unmapped)
|
|
217
|
+
).map(([s, e]) => [
|
|
218
|
+
s - segment.labelsStart,
|
|
219
|
+
e - segment.labelsStart
|
|
220
|
+
]);
|
|
221
|
+
if (dropped.length) {
|
|
222
|
+
const { result: adjustedLabels, inputIndices: adjustedIndices } = removeLabelRanges(stripBoundingStars2(segment.labels), dropped);
|
|
223
|
+
indices = adjustedIndices;
|
|
224
|
+
if (segment === segments[0]) {
|
|
225
|
+
adjustedLabels.unshift(star);
|
|
226
|
+
}
|
|
227
|
+
if (segment === segments.at(-1)) {
|
|
228
|
+
adjustedLabels.push(star);
|
|
229
|
+
}
|
|
230
|
+
unmapped = ctcViterbiAlign(
|
|
231
|
+
segment.emissions,
|
|
232
|
+
adjustedLabels,
|
|
233
|
+
blankId,
|
|
234
|
+
star,
|
|
235
|
+
STAR_SCORE
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
const segmentAlignments = unmapped.map((a) => ({
|
|
239
|
+
...a,
|
|
240
|
+
startFrame: a.startFrame + segment.emissionsStart,
|
|
241
|
+
endFrame: a.endFrame + segment.emissionsStart
|
|
242
|
+
}));
|
|
243
|
+
inputIndices.push(...indices.map((i) => i + segment.labelsStart));
|
|
244
|
+
alignmentsWithRemovals.push(...segmentAlignments);
|
|
245
|
+
}
|
|
246
|
+
const alignments = [];
|
|
247
|
+
for (const [k, a] of (0, import_itertools.enumerate)(alignmentsWithRemovals.slice(1, -1))) {
|
|
248
|
+
const i = inputIndices[k];
|
|
249
|
+
const lastUndroppedIndex = alignments.length - 1;
|
|
250
|
+
const lastUndropped = alignments[lastUndroppedIndex] ?? {
|
|
251
|
+
startFrame: 0,
|
|
252
|
+
endFrame: 0,
|
|
253
|
+
score: -Infinity,
|
|
254
|
+
label: star
|
|
255
|
+
};
|
|
256
|
+
for (const j of (0, import_itertools.range)(lastUndroppedIndex, i - 1)) {
|
|
257
|
+
alignments.push({
|
|
258
|
+
startFrame: lastUndropped.endFrame,
|
|
259
|
+
endFrame: lastUndropped.endFrame,
|
|
260
|
+
score: -Infinity,
|
|
261
|
+
label: vocab.get(baseline[j])
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
alignments[i] = a;
|
|
265
|
+
}
|
|
266
|
+
return alignments;
|
|
267
|
+
}
|
|
268
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
269
|
+
0 && (module.exports = {
|
|
270
|
+
ctcForcedAlign,
|
|
271
|
+
ctcViterbiAlign,
|
|
272
|
+
detectDroppedLabels
|
|
273
|
+
});
|