80 lines
1.9 KiB
TypeScript
80 lines
1.9 KiB
TypeScript
import fs from "fs";
|
|
|
|
type Timestamp = {
|
|
timestamp: number;
|
|
title: string;
|
|
};
|
|
|
|
export function shift_timestamps(
|
|
timestamps: Timestamp[],
|
|
duration: number = 0
|
|
) {
|
|
return timestamps.map((ts) => ({
|
|
...ts,
|
|
timestamp: Math.max(0, ts.timestamp + duration),
|
|
}));
|
|
}
|
|
|
|
export function parse_audacity(content: string): Timestamp[] {
|
|
const lines = content.split("\n");
|
|
return lines
|
|
.filter((line) => line.length > 4)
|
|
.map((line) => line.split("\t"))
|
|
.map(([start_s, _, title]) => ({
|
|
timestamp: parseFloat(start_s),
|
|
title,
|
|
}));
|
|
}
|
|
|
|
function parseTimestamp(s: string): number {
|
|
return s
|
|
.split(":")
|
|
.map((e, i, all) => Math.pow(60, all.length - i - 1) * parseInt(e))
|
|
.reduce((a, b) => a + b);
|
|
}
|
|
|
|
function toTimestamp(n: number): string {
|
|
n = Math.floor(n);
|
|
return `${Math.floor(n / 60)
|
|
.toString()
|
|
.padStart(2, "0")}:${(n % 60).toString().padStart(2, "0")}`;
|
|
}
|
|
|
|
export function parse_youtube(content: string): Timestamp[] {
|
|
console.log(
|
|
content
|
|
.split("\n")
|
|
.filter((l) => l.length > 4)
|
|
.map((l) => l.match(/(([0-9]:)?[0-9]{1,2}:[0-9]{2})\s(.*)/))
|
|
);
|
|
return (
|
|
content
|
|
.split("\n")
|
|
.filter((l) => l.length > 4)
|
|
.map((l) => l.match(/(([0-9]:)?[0-9]{1,2}:[0-9]{2})\s(.*)/))
|
|
.filter((m) => m != null) as string[][]
|
|
).map(([_, time_s, __, title]) => ({
|
|
title: title.replace(/^\s*[-:]\s+/, ""),
|
|
timestamp: parseTimestamp(time_s),
|
|
}));
|
|
}
|
|
|
|
export function to_youtube(timestamps: Timestamp[]): string {
|
|
return timestamps
|
|
.map((ts) => `${toTimestamp(ts.timestamp)} ${ts.title}\n`)
|
|
.join("\n"); // yes, double newlines
|
|
}
|
|
|
|
export function to_json(timestamps: Timestamp[]): string {
|
|
return JSON.stringify({
|
|
version: "1.2",
|
|
chapters: timestamps.map((ts) => ({
|
|
startTime: ts.timestamp,
|
|
title: ts.title,
|
|
})),
|
|
});
|
|
}
|
|
|
|
export const parsers = { youtube: parse_youtube, audacity: parse_audacity };
|
|
export const encoders = { youtube: to_youtube, json: to_json };
|