-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathsrt-to-vtt.py
More file actions
executable file
·89 lines (69 loc) · 1.71 KB
/
srt-to-vtt.py
File metadata and controls
executable file
·89 lines (69 loc) · 1.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#!/usr/bin/env python3
from __future__ import annotations
from collections.abc import Iterator
from dataclasses import dataclass, field
from functools import reduce
import sys
import io
import jinja2
def run() -> str:
cues = _parse(
_readfile(sys.stdin)
)
with open('srt-to-vtt.vtt.j2', 'r') as f:
template = jinja2.Template(f.read())
return template.render(
cues=cues,
classes=reduce(
lambda classes, cue: classes | {cue.cls} if cue.cls else classes,
cues,
set()
)
)
def _readfile(f: io.TextIOBase) -> Iterator[str]:
for line in f:
yield line
def _parse(lines: Iterator[str]) -> list[Cue]:
@dataclass
class _Cue:
id: str = ''
timeline: str = ''
content: list[str] = field(default_factory=list)
cls: str = ''
def _parse_content(content: list[str]) -> tuple[str, str]:
output = '\n'.join(content)
# parse classes
if output.startswith('[E]'):
return output[3:], 'exp'
return output, ''
def _to_external_cue(cue: _Cue) -> Cue:
content, cls = _parse_content(cue.content)
return Cue(timeline=cue.timeline, content=content, cls=cls)
def _lines_to_cues(lines: Iterator[str]) -> Iterator[_Cue]:
_cue = None
for line in lines:
if line == '\n' or line == '':
yield _cue
if line == '':
break
_cue = None
continue
line = line.strip()
if not _cue:
_cue = _Cue()
if not _cue.id:
_cue.id = line
continue
if not _cue.timeline:
_cue.timeline = line
continue
# else, content.
_cue.content.append(line)
return list(map(_to_external_cue, _lines_to_cues(lines)))
@dataclass(frozen=True) # needs to be frozen, to be serializable for Jinja
class Cue:
timeline: str
content: str
cls: str
if __name__ == '__main__':
print(run())