Skip to content

Commit bf87c70

Browse files
committed
vtt
1 parent 6a292a2 commit bf87c70

File tree

10 files changed

+490
-13
lines changed

10 files changed

+490
-13
lines changed

.DS_Store

0 Bytes
Binary file not shown.

assets/.DS_Store

0 Bytes
Binary file not shown.

assets/icons/vtt-hover.png

2.16 KB
Loading

assets/icons/vtt.png

2.08 KB
Loading

components/TitleBar.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ import coverButton from "../assets/icons/cover.png"
2525
import coverButtonHover from "../assets/icons/cover-hover.png"
2626
import renameButton from "../assets/icons/rename.png"
2727
import renameButtonHover from "../assets/icons/rename-hover.png"
28-
import mkvButton from "../assets/icons/mkv.png"
29-
import mkvButtonHover from "../assets/icons/mkv-hover.png"
28+
import vttButton from "../assets/icons/vtt.png"
29+
import vttButtonHover from "../assets/icons/vtt-hover.png"
3030
import "../styles/titlebar.less"
3131

3232
const TitleBar: React.FunctionComponent = (props) => {
@@ -41,7 +41,7 @@ const TitleBar: React.FunctionComponent = (props) => {
4141
const [hoverPDF, setHoverPDF] = useState(false)
4242
const [hoverCover, setHoverCover] = useState(false)
4343
const [hoverRename, setHoverRename] = useState(false)
44-
const [hoverMKV, setHoverMKV] = useState(false)
44+
const [hoverVTT, setHoverVTT] = useState(false)
4545
const [theme, setTheme] = useState("light")
4646

4747
useEffect(() => {
@@ -98,7 +98,7 @@ const TitleBar: React.FunctionComponent = (props) => {
9898
if (files?.[0]) ipcRenderer.invoke("rename", files)
9999
}
100100

101-
const mkv = async () => {
101+
const vtt = async () => {
102102
const files = await ipcRenderer.invoke("multi-open", "subs")
103103
if (files?.[0]) ipcRenderer.invoke("extract-subtitles", files)
104104
}
@@ -143,7 +143,7 @@ const TitleBar: React.FunctionComponent = (props) => {
143143
</div>
144144
<div className="title-bar-buttons">
145145
<img src={hoverTheme ? (theme === "light" ? darkButtonHover : lightButtonHover) : (theme === "light" ? darkButton : lightButton)} height="20" width="20" className="title-bar-button theme-button" onClick={() => changeTheme()} onMouseEnter={() => setHoverTheme(true)} onMouseLeave={() => setHoverTheme(false)}/>
146-
<img src={hoverMKV ? mkvButtonHover : mkvButton} height="20" width="20" className="title-bar-button mkv-button" onClick={mkv} onMouseEnter={() => setHoverMKV(true)} onMouseLeave={() => setHoverMKV(false)}/>
146+
<img src={hoverVTT ? vttButtonHover : vttButton} height="20" width="20" className="title-bar-button mkv-button" onClick={vtt} onMouseEnter={() => setHoverVTT(true)} onMouseLeave={() => setHoverVTT(false)}/>
147147
<img src={hoverRename ? renameButtonHover : renameButton} height="20" width="20" className="title-bar-button rename-button" onClick={rename} onMouseEnter={() => setHoverRename(true)} onMouseLeave={() => setHoverRename(false)}/>
148148
<img src={hoverCover ? coverButtonHover : coverButton} height="20" width="20" className="title-bar-button cover-button" onClick={cover} onMouseEnter={() => setHoverCover(true)} onMouseLeave={() => setHoverCover(false)}/>
149149
<img src={hoverPDF ? pdfButtonHover : pdfButton} height="20" width="20" className="title-bar-button pdf-button" onClick={pdf} onMouseEnter={() => setHoverPDF(true)} onMouseLeave={() => setHoverPDF(false)}/>

declarations.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ declare module "sharp-phash/distance"
1010
declare module "image-pixels"
1111
declare module "bing-translate-api"
1212
declare module "mkv-subtitle-extractor"
13+
declare module "srt-to-vtt"
1314

1415
type OpenImageProps = {
1516
label: string

main.ts

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import Helvetica from "pdfkit/js/data/Helvetica.afm"
2222
import PDFDocument from "pdfkit"
2323
import child_process from "child_process"
2424
import mkvExtractor from "mkv-subtitle-extractor"
25+
import srt2vtt from "srt-to-vtt"
2526

2627
import util from "util"
2728

@@ -45,6 +46,26 @@ const queue: Array<{started: boolean, info: any}> = []
4546
if (!fs.existsSync(path.join(__dirname, "data"))) fs.mkdirSync(path.join(__dirname, "data"))
4647
fs.writeFileSync(path.join(__dirname, "data/Helvetica.afm"), Helvetica)
4748

49+
const srtToVtt = async (subtitles: string[]) => {
50+
for (let i = 0; i < subtitles.length; i++) {
51+
await new Promise<void>((resolve, reject) => {
52+
const readStream = fs.createReadStream(subtitles[i]).pipe(srt2vtt())
53+
const writeStream = fs.createWriteStream(`${path.dirname(subtitles[i])}/${path.basename(subtitles[i], path.extname(subtitles[i]))}.vtt`)
54+
readStream.pipe(writeStream)
55+
.on("end", () => resolve())
56+
.on("finish", () => resolve())
57+
})
58+
}
59+
60+
const promiseArray: any[] = []
61+
for (let i = 0; i < subtitles.length; i++) {
62+
promiseArray.push(new Promise<void>((resolve) => {
63+
fs.unlink(subtitles[i], () => resolve())
64+
}))
65+
}
66+
await Promise.all(promiseArray)
67+
}
68+
4869
const extractSubtitles = async (videos: string[]) => {
4970
for (let i = 0; i < videos.length; i++) {
5071
await mkvExtractor(videos[i])
@@ -63,14 +84,24 @@ const extractSubtitles = async (videos: string[]) => {
6384
ipcMain.handle("extract-subtitles", async (event, files: string[]) => {
6485
const directories = files.filter((f) => fs.lstatSync(f).isDirectory())
6586
const videos = files.filter((f) => path.extname(f).toLowerCase() === ".mkv")
87+
const subtitles = files.filter((f) => path.extname(f).toLowerCase() === ".srt")
6688

6789
let openDir = ""
6890

6991
for (let i = 0; i < directories.length; i++) {
7092
const dir = directories[i]
71-
let videos = fs.readdirSync(dir).map((i) => path.join(dir, i))
72-
videos = videos.filter((f) => path.extname(f).toLowerCase() === ".mkv")
73-
await extractSubtitles(videos)
93+
let files = fs.readdirSync(dir).map((i) => path.join(dir, i))
94+
let videos = files.filter((f) => path.extname(f).toLowerCase() === ".mkv")
95+
let subs = files.filter((f) => path.extname(f).toLowerCase() === ".srt")
96+
if (videos.length) {
97+
await extractSubtitles(videos)
98+
let files = fs.readdirSync(dir).map((i) => path.join(dir, i))
99+
let subs = files.filter((f) => path.extname(f).toLowerCase() === ".srt")
100+
await srtToVtt(subs)
101+
}
102+
if (subs.length) {
103+
await srtToVtt(subs)
104+
}
74105
try {
75106
fs.rmdirSync(dir)
76107
} catch (e) {
@@ -81,8 +112,16 @@ ipcMain.handle("extract-subtitles", async (event, files: string[]) => {
81112

82113
if (videos.length) {
83114
await extractSubtitles(videos)
115+
let subs = fs.readdirSync(path.dirname(videos[0])).map((i) => path.join(path.dirname(videos[0]), i))
116+
subs = subs.filter((f) => path.extname(f).toLowerCase() === ".srt")
117+
await srtToVtt(subs)
84118
if (!openDir) openDir = videos[0]
85119
}
120+
121+
if (subtitles.length) {
122+
await srtToVtt(subtitles)
123+
if (!openDir) openDir = subtitles[0]
124+
}
86125
shell.openPath(path.dirname(openDir))
87126
})
88127

0 commit comments

Comments
 (0)