1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.opencastproject.subtitleparser.webvttparser;
22
23 import static java.util.Optional.ofNullable;
24
25 import java.io.IOException;
26 import java.io.OutputStream;
27 import java.io.UnsupportedEncodingException;
28 import java.nio.charset.Charset;
29 import java.nio.charset.StandardCharsets;
30 import java.util.List;
31
32 public class WebVTTWriter {
33 private Charset charset;
34
35 public WebVTTWriter() {
36 this.charset = StandardCharsets.UTF_8;
37 }
38
39 public WebVTTWriter(Charset charset) {
40 this.charset = charset;
41 }
42
43 public void write(WebVTTSubtitle subtitleObject, OutputStream os) throws IOException {
44 try {
45
46 List<String> headerLines = subtitleObject.getHeaderLines();
47 for (int i = 0; i < headerLines.size() ; i++) {
48
49 if (i == 0 && !headerLines.get(i).startsWith("WEBVTT")) {
50 os.write(("WEBVTT " + headerLines.get(i) + "\n").getBytes(this.charset));
51 continue;
52 }
53 os.write((headerLines.get(i) + "\n").getBytes(this.charset));
54 }
55
56 if (headerLines.size() == 0) {
57 os.write(("WEBVTT" + "\n").getBytes(this.charset));
58 }
59 os.write("\n".getBytes(this.charset));
60
61
62 for (WebVTTSubtitleRegion region : subtitleObject.getRegions()) {
63 for (String regionLine : region.getLines()) {
64 os.write((regionLine + "\n").getBytes(this.charset));
65 }
66 os.write("\n".getBytes(this.charset));
67 }
68
69
70 for (WebVTTSubtitleStyle style : subtitleObject.getStyle()) {
71 for (String styleLine : style.getLines()) {
72 os.write((styleLine + "\n").getBytes(this.charset));
73 }
74 os.write("\n".getBytes(this.charset));
75 }
76
77
78 for (WebVTTSubtitleCue cue : subtitleObject.getCues()) {
79 if (cue.getId() != null) {
80
81 String number = String.format("%s\n", cue.getId());
82 os.write(number.getBytes(this.charset));
83 }
84
85
86 String startToEnd = String.format("%s --> %s %s\n",
87 this.formatTimeCode(cue.getStartTime()),
88 this.formatTimeCode(cue.getEndTime()),
89 ofNullable(cue.getCueSettingsList()).orElse(""));
90 os.write(startToEnd.getBytes(this.charset));
91
92
93 String text = String.format("%s\n", cue.getText());
94 os.write(text.getBytes(this.charset));
95
96
97 os.write("\n".getBytes(this.charset));
98 }
99 } catch (UnsupportedEncodingException e) {
100 throw new IOException("Encoding error in input subtitle");
101 }
102 }
103
104 private String formatTimeCode(long ms) {
105 long milliseconds = ms % 1000L;
106 long seconds = ms / 1000L % 60L;
107 long minutes = ms / (1000L * 60L) % 60L;
108 long hours = ms / (1000L * 60L * 60L);
109
110 return String.format("%02d:%02d:%02d.%03d",
111 hours,
112 minutes,
113 seconds,
114 milliseconds);
115 }
116 }