Shows with subtitles
If you already subtitle a show, you already have everything Signa needs: the words and when they are said.
No subtitles yet?
Make them from the programme itself with /v1/subtitles: send the file (or just its sound), get SRT or JSON cues back, check them, and carry on below.
The idea
- Read the subtitle file (SRT or VTT) into cues: a start time, an end time and the text.
- Sign each cue with /v1/sign.
- Turn each cue into a video with /v1/sign/video, and place it on a track at the cue's start time.
Signing usually runs a little longer or shorter than speech. Let a cue's signing run past its end time when the next cue starts later, and start the next one when it is due.
Example
Node.js
import { readFile, writeFile } from "node:fs/promises";
// Parse an SRT file into cues: { start, end, text } with times in seconds.
function parseSrt(srt) {
const time = (t) => {
const [h, m, s] = t.replace(",", ".").split(":");
return +h * 3600 + +m * 60 + +s;
};
return srt.trim().split(/\r?\n\r?\n/).map((block) => {
const lines = block.split(/\r?\n/);
const [start, end] = lines[1].split(" --> ").map(time);
return { start, end, text: lines.slice(2).join(" ") };
});
}
async function sign(text) {
const res = await fetch("https://api.usesigna.org/v1/sign", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.SIGNA_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ text, from: "rw", to: "rsl" }),
});
if (!res.ok) throw new Error((await res.json()).message);
return Buffer.from(await res.arrayBuffer());
}
const cues = parseSrt(await readFile("episode-12.srt", "utf8"));
for (const [i, cue] of cues.entries()) {
const sgn = await sign(cue.text);
// One signed file per cue, named by when it starts in the show.
await writeFile(`signs/${String(i).padStart(4, "0")}-${cue.start.toFixed(2)}.sgn`, sgn);
}Same words, same price
Shows repeat themselves: greetings, names, the weather. Words signed before are instant, and every cue is counted only by its own characters.