JOGL v2.6.0-rc-20250706
JOGL, High-Performance Graphics Binding for Java™ (public API).
SubTextEvent.java
Go to the documentation of this file.
1/**
2 * Copyright 2024 JogAmp Community. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification, are
5 * permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice, this list of
8 * conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 *
24 * The views and conclusions contained in the software and documentation are those of the
25 * authors and should not be interpreted as representing official policies, either expressed
26 * or implied, of JogAmp Community.
27 */
28package com.jogamp.opengl.util.av;
29
30import java.time.format.DateTimeParseException;
31
32import com.jogamp.common.av.PTS;
33import com.jogamp.common.util.StringUtil;
34
35/**
36 * Text Event Line including ASS/SAA of {@link SubtitleEvent}
37 * <p>
38 * See http://www.tcax.org/docs/ass-specs.htm
39 * </p>
40 */
41public class SubTextEvent extends SubtitleEvent {
42 /** Text formatting */
43 public enum TextFormat {
44 /** Multiple ASS formats may be passed, see {@link ASSType}. */
46 /** Just plain text */
48 };
49 /** ASS Formatting Type */
50 public enum ASSType {
51 /**
52 * ASS dialogue-line output w/ start and end (Given by FFmpeg 4.*)
53 * <pre>
54 0 1 2 3 4 5 6 7 8 9
55 Marked, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
56
57 'Dialogue: 0,0:02:02.15,0:02:02.16,Default,,0,0,0,,trying to force him to travel to that'
58 * </pre>
59 */
61 /**
62 * FFMpeg ASS event-line output w/o start, end (Given by FFmpeg 5.*, 6.*, ..)
63 * <pre>
64 0 1 2 3 4 5 6 7 8
65 Seq, Layer, Style, Name, MarginL, MarginR, MarginV, Effect, TEXT
66 * </pre>
67 */
69 /** Just plain text */
70 TEXT
71 }
72 /** {@link TextFormat} of this text subtitle event. */
73 public final TextFormat textFormat;
74 /** {@link ASSType} sub-type */
75 public final ASSType assType;
76 /** Start time in milliseconds, or -1. */
77 public final int start;
78 /** End time in milliseconds, or -1. */
79 public final int end;
80 public final String style;
81
82 public final int seqnr;
83 public final int layer;
84
85 public final String name;
86 public final String effect;
87 /** Actual subtitle text */
88 public final String text;
89 /** Number of lines of {@link #text}, i.e. occurrence of {@code \n} + 1. */
90 public final int lines;
91
92 private static boolean DEBUG = false;
93
94 /**
95 * ASS/SAA Event Line ctor
96 * @param codec the {@link CodecID}
97 * @param lang language code, supposed to be 3-letters of `ISO 639-2 language codes`
98 * @param fmt input format of {@code ass}
99 * @param ass ASS/SAA compatible event line according to {@link ASSType}
100 * @param pts_start pts start in ms
101 * @param pts_end pts end in ms
102 */
103 public SubTextEvent(final CodecID codec, final String lang, final TextFormat fmt, final String ass, final int pts_start, final int pts_end) {
105 this.textFormat = fmt;
107 int start = -1;
108 int end = -1;
109 int seqnr = 0;
110 int layer = 0;
111 String style = "Default";
112 String name = "";
113 String effect = "";
114 String text = "";
115 boolean done = false;
116 if( TextFormat.ASS == fmt ) {
117 final int len = null != ass ? ass.length() : 0;
118 {
119 // ASSType.DIALOGUE
120 int part = 0;
121 for(int i=0; 10 > part && len > i; ) {
122 if( 9 == part ) {
123 text = ass.substring(i);
124 done = true;
126 } else {
127 final int j = ass.indexOf(',', i);
128 if( 0 > j ) {
129 break;
130 }
131 final String v = ass.substring(i, j);
132 try {
133 switch(part) {
134 case 1:
135 start = PTS.toMillis(v, true);
136 break;
137 case 2:
138 end = PTS.toMillis(v, true);
139 break;
140 case 3:
141 style = v;
142 break;
143 case 4:
144 name = v;
145 break;
146 case 8:
147 effect = v;
148 break;
149 }
150 } catch(final DateTimeParseException pe) {
151 if( DEBUG ) {
152 System.err.println("ASS.DIALG parsing error of part "+part+" '"+v+"' of '"+ass+"'");
153 }
154 break;
155 }
156 i = j + 1;
157 }
158 ++part;
159 }
160 }
161 if( !done ) {
162 // ASSType.EVENT
163 int part = 0;
164 for(int i=0; 9 > part && len > i; ) {
165 if( 8 == part ) {
166 text = ass.substring(i);
167 done = true;
169 } else {
170 final int j = ass.indexOf(',', i);
171 if( 0 > j ) {
172 break;
173 }
174 final String v = ass.substring(i, j);
175 try {
176 switch(part) {
177 case 0:
178 seqnr = Integer.valueOf(v);
179 break;
180 case 1:
181 layer = Integer.valueOf(v);
182 break;
183 case 2:
184 style = v;
185 break;
186 case 3:
187 name = v;
188 break;
189 case 7:
190 effect = v;
191 break;
192 }
193 } catch(final NumberFormatException nfe) {
194 if( DEBUG ) {
195 System.err.println("ASS.EVENT parsing error of part "+part+" '"+v+"' of '"+ass+"'");
196 }
197 break;
198 }
199 i = j + 1;
200 }
201 ++part;
202 }
203 }
204 }
205 if( !done && TextFormat.TEXT == fmt ) {
206 text = ass;
207 done = true;
209 }
210 this.assType = assType;
211 this.start = start;
212 this.end = end;
213 this.seqnr = seqnr;
214 this.layer = layer;
215 this.style = style;
216 this.name = name;
217 this.effect = effect;
218 this.text = text.replace("\\N", "\n");
219 this.lines = StringUtil.getLineCount(this.text);
220 }
221
222 @Override
223 public void release() {} // nothing to be released back to the owner
224
225 @Override
226 public String toString() {
227 final String start_s = 0 <= start ? PTS.toTimeStr(start, true) : "undef";
228 final String end_s = 0 <= end ? PTS.toTimeStr(end, true) : "undef";
229 final String fms_s = TextFormat.ASS == textFormat ? "ASS("+assType+")" : textFormat.toString();
230 return getStartString()+", "+fms_s+", #"+seqnr+", l_"+layer+
231 ", ["+start_s+".."+end_s+"], style "+style+", name '"+name+"', effect '"+effect+"': '"+text+"' ("+lines+")]";
232 }
233}
Text Event Line including ASS/SAA of SubtitleEvent.
final int end
End time in milliseconds, or -1.
final int start
Start time in milliseconds, or -1.
final TextFormat textFormat
TextFormat of this text subtitle event.
void release()
Release the resources, if any, back to the owner.
SubTextEvent(final CodecID codec, final String lang, final TextFormat fmt, final String ass, final int pts_start, final int pts_end)
ASS/SAA Event Line ctor.
final String text
Actual subtitle text.
final ASSType assType
ASSType sub-type
final int lines
Number of lines of text, i.e.
final String lang
Language code, supposed to be 3-letters of ISO 639-2 language codes
final int pts_end
PTS end time in milliseconds to end showing this subtitle event.
final int pts_start
PTS start time in milliseconds to start showing this subtitle event.
final CodecID codec
CodecID of this subtitle event.
FFmpeg/libAV analog AVCodecID.
Definition: CodecID.java:37
EVENT
FFMpeg ASS event-line output w/o start, end (Given by FFmpeg 5.
DIALOGUE
ASS dialogue-line output w/ start and end (Given by FFmpeg 4.
ASS
Multiple ASS formats may be passed, see ASSType.
SubtitleEvent Implementation Type