opencaptions 1.2.0 → 1.2.1
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/captions.js +6 -4
- package/dist/engine.js +6 -0
- package/dist/mcp.js +11 -2
- package/engine/opencaptions_engine.wasm +0 -0
- package/package.json +1 -1
- package/server.json +2 -2
package/dist/captions.js
CHANGED
|
@@ -9,7 +9,7 @@ import { basename, dirname, extname, join, resolve } from "node:path";
|
|
|
9
9
|
import { Readable } from "node:stream";
|
|
10
10
|
import { pipeline } from "node:stream/promises";
|
|
11
11
|
import { OpenCaptionsError, unwrap, } from "./client.js";
|
|
12
|
-
import { captionLines, setWord, shuffleVariants } from "./engine.js";
|
|
12
|
+
import { captionLines, mergeWords, setWord, shuffleVariants } from "./engine.js";
|
|
13
13
|
import { findLook, LOOKS } from "./looks.js";
|
|
14
14
|
/** How often a job is asked about, in milliseconds. */
|
|
15
15
|
const pollMs = () => Number(process.env.OPENCAPTIONS_POLL_MS) || 1000;
|
|
@@ -121,15 +121,17 @@ export async function readTranscript(client, projectId) {
|
|
|
121
121
|
const lines = await captionLines(project.transcript, project.style_config?.words_per_line ?? 3, project.caption_offset_ms);
|
|
122
122
|
return { lines, words };
|
|
123
123
|
}
|
|
124
|
-
/** Sets words by their index; empty text removes a word. The indices are the ones read before. */
|
|
125
124
|
export async function fixWords(client, projectId, fixes) {
|
|
126
125
|
const project = await getProject(client, projectId);
|
|
127
126
|
if (!project.transcript)
|
|
128
127
|
throw new OpenCaptionsError("This project has no captions yet.");
|
|
129
|
-
// Last first: removing
|
|
128
|
+
// Last first: removing or joining words moves the ones after them, never the ones before.
|
|
130
129
|
let transcript = project.transcript;
|
|
131
130
|
for (const fix of [...fixes].sort((a, b) => b.index - a.index)) {
|
|
132
|
-
transcript =
|
|
131
|
+
transcript =
|
|
132
|
+
(fix.count ?? 1) > 1
|
|
133
|
+
? await mergeWords(transcript, fix.index, fix.count ?? 1, fix.text)
|
|
134
|
+
: await setWord(transcript, fix.index, fix.text);
|
|
133
135
|
}
|
|
134
136
|
await update(client, projectId, { transcript });
|
|
135
137
|
return fixes.length;
|
package/dist/engine.js
CHANGED
|
@@ -36,6 +36,12 @@ export async function setWord(t, index, text) {
|
|
|
36
36
|
const x = await exports();
|
|
37
37
|
return result(x, x.oc_set_word(...json(x, t), index, ...copyIn(x, encoder.encode(text))));
|
|
38
38
|
}
|
|
39
|
+
/** `count` words from `index` replaced by one word `text`, spanning them all. */
|
|
40
|
+
export async function mergeWords(t, index, count, text) {
|
|
41
|
+
const x = await exports();
|
|
42
|
+
const words = copyIn(x, encoder.encode(text));
|
|
43
|
+
return result(x, x.oc_merge_words(...json(x, t), index, count, ...words));
|
|
44
|
+
}
|
|
39
45
|
/** Deals every word one of `count` looks, or the style's own, as picking such a look does. */
|
|
40
46
|
export async function shuffleVariants(t, count) {
|
|
41
47
|
const x = await exports();
|
package/dist/mcp.js
CHANGED
|
@@ -88,7 +88,8 @@ const TOOLS = [
|
|
|
88
88
|
{
|
|
89
89
|
name: "fix_words",
|
|
90
90
|
description: "Sets words by the index get_transcript gave them, keeping their timing; empty text removes " +
|
|
91
|
-
"a word
|
|
91
|
+
"a word, and count joins that many words into one spanning them all (two words heard for " +
|
|
92
|
+
"one). Then save_video writes the video again.",
|
|
92
93
|
inputSchema: {
|
|
93
94
|
type: "object",
|
|
94
95
|
properties: {
|
|
@@ -97,7 +98,15 @@ const TOOLS = [
|
|
|
97
98
|
type: "array",
|
|
98
99
|
items: {
|
|
99
100
|
type: "object",
|
|
100
|
-
properties: {
|
|
101
|
+
properties: {
|
|
102
|
+
index: { type: "integer", minimum: 0 },
|
|
103
|
+
text: { type: "string" },
|
|
104
|
+
count: {
|
|
105
|
+
type: "integer",
|
|
106
|
+
minimum: 1,
|
|
107
|
+
description: "How many words from index the text replaces, as one word (default 1)",
|
|
108
|
+
},
|
|
109
|
+
},
|
|
101
110
|
required: ["index", "text"],
|
|
102
111
|
},
|
|
103
112
|
},
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencaptions",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"description": "Animated word-by-word captions for your videos, from Claude, Cursor or any MCP client, or the command line. Runs on your own OpenCaptions server.",
|
|
5
5
|
"mcpName": "io.github.leogaudin/opencaptions",
|
|
6
6
|
"license": "AGPL-3.0-only",
|
package/server.json
CHANGED
|
@@ -9,13 +9,13 @@
|
|
|
9
9
|
"source": "github",
|
|
10
10
|
"subfolder": "apps/agent"
|
|
11
11
|
},
|
|
12
|
-
"version": "1.2.
|
|
12
|
+
"version": "1.2.1",
|
|
13
13
|
"packages": [
|
|
14
14
|
{
|
|
15
15
|
"registryType": "npm",
|
|
16
16
|
"registryBaseUrl": "https://registry.npmjs.org",
|
|
17
17
|
"identifier": "opencaptions",
|
|
18
|
-
"version": "1.2.
|
|
18
|
+
"version": "1.2.1",
|
|
19
19
|
"transport": { "type": "stdio" },
|
|
20
20
|
"packageArguments": [{ "type": "positional", "value": "mcp" }],
|
|
21
21
|
"environmentVariables": [
|