Refactor SubtitleFormat and add SAMI support (read-only)
This commit is contained in:
parent
3ac78751b6
commit
ae96a2a55c
|
@ -5,18 +5,14 @@ import static net.filebot.util.StringUtilities.*;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Scanner;
|
||||
|
||||
public class MicroDVDReader extends SubtitleReader {
|
||||
|
||||
private double fps = 23.976;
|
||||
|
||||
public MicroDVDReader(Readable source) {
|
||||
super(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFormatName() {
|
||||
return "MicroDVD";
|
||||
public MicroDVDReader(Scanner scanner) {
|
||||
super(scanner);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -13,9 +13,10 @@ import org.jsoup.Jsoup;
|
|||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Element;
|
||||
|
||||
public class SamiReader {
|
||||
public class SamiDecoder implements SubtitleDecoder {
|
||||
|
||||
public List<SubtitleElement> decode(CharSequence file) {
|
||||
@Override
|
||||
public List<SubtitleElement> decode(String file) {
|
||||
List<SubtitleElement> subtitles = new ArrayList<SubtitleElement>();
|
||||
|
||||
Matcher matcher = Pattern.compile("<SYNC(.*?)>", Pattern.CASE_INSENSITIVE).matcher(file);
|
|
@ -7,6 +7,7 @@ import java.text.SimpleDateFormat;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Scanner;
|
||||
import java.util.TimeZone;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
@ -15,8 +16,8 @@ public class SubRipReader extends SubtitleReader {
|
|||
private final DateFormat timeFormat;
|
||||
private final Pattern tag;
|
||||
|
||||
public SubRipReader(Readable source) {
|
||||
super(source);
|
||||
public SubRipReader(Scanner scanner) {
|
||||
super(scanner);
|
||||
|
||||
// format used to parse time stamps (e.g. 00:02:26,407 --> 00:02:31,356)
|
||||
timeFormat = new SimpleDateFormat("HH:mm:ss,SSS", Locale.ROOT);
|
||||
|
@ -26,11 +27,6 @@ public class SubRipReader extends SubtitleReader {
|
|||
tag = Pattern.compile("</?(b|u|i|font[^<>]*)>", Pattern.CASE_INSENSITIVE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFormatName() {
|
||||
return "SubRip";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SubtitleElement readNext() throws Exception {
|
||||
String number = scanner.nextLine();
|
||||
|
|
|
@ -6,6 +6,7 @@ import static java.util.Arrays.*;
|
|||
import java.text.DateFormat;
|
||||
import java.util.InputMismatchException;
|
||||
import java.util.List;
|
||||
import java.util.Scanner;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class SubStationAlphaReader extends SubtitleReader {
|
||||
|
@ -20,13 +21,8 @@ public class SubStationAlphaReader extends SubtitleReader {
|
|||
private int formatIndexEnd;
|
||||
private int formatIndexText;
|
||||
|
||||
public SubStationAlphaReader(Readable source) {
|
||||
super(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFormatName() {
|
||||
return "SubStationAlpha";
|
||||
public SubStationAlphaReader(Scanner scanner) {
|
||||
super(scanner);
|
||||
}
|
||||
|
||||
private void readFormat() throws Exception {
|
||||
|
|
|
@ -7,6 +7,7 @@ import static net.filebot.util.StringUtilities.*;
|
|||
import java.text.DateFormat;
|
||||
import java.text.ParseException;
|
||||
import java.util.InputMismatchException;
|
||||
import java.util.Scanner;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class SubViewerReader extends SubtitleReader {
|
||||
|
@ -14,13 +15,8 @@ public class SubViewerReader extends SubtitleReader {
|
|||
private final DateFormat timeFormat = new SubtitleTimeFormat();
|
||||
private final Pattern newline = compile(quote("[br]"), CASE_INSENSITIVE);
|
||||
|
||||
public SubViewerReader(Readable source) {
|
||||
super(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFormatName() {
|
||||
return "SubViewer";
|
||||
public SubViewerReader(Scanner scanner) {
|
||||
super(scanner);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
package net.filebot.subtitle;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface SubtitleDecoder {
|
||||
|
||||
List<SubtitleElement> decode(String file);
|
||||
|
||||
}
|
|
@ -1,6 +1,10 @@
|
|||
|
||||
package net.filebot.subtitle;
|
||||
|
||||
import static java.util.stream.Collectors.*;
|
||||
|
||||
import java.util.Scanner;
|
||||
|
||||
import net.filebot.MediaTypes;
|
||||
import net.filebot.util.FileUtilities.ExtensionFileFilter;
|
||||
|
||||
|
@ -9,8 +13,8 @@ public enum SubtitleFormat {
|
|||
SubRip {
|
||||
|
||||
@Override
|
||||
public SubtitleReader newReader(Readable readable) {
|
||||
return new SubRipReader(readable);
|
||||
public SubtitleDecoder getDecoder() {
|
||||
return content -> new SubRipReader(new Scanner(content)).stream().collect(toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -22,8 +26,8 @@ public enum SubtitleFormat {
|
|||
MicroDVD {
|
||||
|
||||
@Override
|
||||
public SubtitleReader newReader(Readable readable) {
|
||||
return new MicroDVDReader(readable);
|
||||
public SubtitleDecoder getDecoder() {
|
||||
return content -> new MicroDVDReader(new Scanner(content)).stream().collect(toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -35,8 +39,8 @@ public enum SubtitleFormat {
|
|||
SubViewer {
|
||||
|
||||
@Override
|
||||
public SubtitleReader newReader(Readable readable) {
|
||||
return new SubViewerReader(readable);
|
||||
public SubtitleDecoder getDecoder() {
|
||||
return content -> new SubViewerReader(new Scanner(content)).stream().collect(toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -48,17 +52,30 @@ public enum SubtitleFormat {
|
|||
SubStationAlpha {
|
||||
|
||||
@Override
|
||||
public SubtitleReader newReader(Readable readable) {
|
||||
return new SubStationAlphaReader(readable);
|
||||
public SubtitleDecoder getDecoder() {
|
||||
return content -> new SubStationAlphaReader(new Scanner(content)).stream().collect(toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExtensionFileFilter getFilter() {
|
||||
return MediaTypes.getTypeFilter("subtitle/SubStationAlpha");
|
||||
}
|
||||
},
|
||||
|
||||
SAMI {
|
||||
|
||||
@Override
|
||||
public SubtitleDecoder getDecoder() {
|
||||
return new SamiDecoder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExtensionFileFilter getFilter() {
|
||||
return MediaTypes.getTypeFilter("subtitle/SAMI");
|
||||
}
|
||||
};
|
||||
|
||||
public abstract SubtitleReader newReader(Readable readable);
|
||||
public abstract SubtitleDecoder getDecoder();
|
||||
|
||||
public abstract ExtensionFileFilter getFilter();
|
||||
|
||||
|
|
|
@ -7,18 +7,20 @@ import java.io.IOException;
|
|||
import java.util.Iterator;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Scanner;
|
||||
import java.util.Spliterator;
|
||||
import java.util.Spliterators;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
public abstract class SubtitleReader implements Iterator<SubtitleElement>, Closeable {
|
||||
|
||||
protected final Scanner scanner;
|
||||
protected Scanner scanner;
|
||||
protected SubtitleElement current;
|
||||
|
||||
public SubtitleReader(Readable source) {
|
||||
this.scanner = new Scanner(source);
|
||||
public SubtitleReader(Scanner scanner) {
|
||||
this.scanner = scanner;
|
||||
}
|
||||
|
||||
public abstract String getFormatName();
|
||||
|
||||
protected abstract SubtitleElement readNext() throws Exception;
|
||||
|
||||
@Override
|
||||
|
@ -28,7 +30,7 @@ public abstract class SubtitleReader implements Iterator<SubtitleElement>, Close
|
|||
try {
|
||||
current = readNext();
|
||||
} catch (Exception e) {
|
||||
debug.warning(format("%s: %s", getFormatName(), e.getMessage())); // log and ignore
|
||||
debug.warning(cause(e)); // log and ignore
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,9 +55,8 @@ public abstract class SubtitleReader implements Iterator<SubtitleElement>, Close
|
|||
scanner.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
public Stream<SubtitleElement> stream() {
|
||||
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(this, Spliterator.ORDERED), false);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -324,24 +324,16 @@ public final class SubtitleUtilities {
|
|||
likelyFormats.addLast(format);
|
||||
}
|
||||
|
||||
// decode bytes and beware of byte-order marks
|
||||
Reader reader = createTextReader(new ByteBufferInputStream(file.getData()), true, UTF_8);
|
||||
String content = IOUtils.toString(reader);
|
||||
|
||||
// decode subtitle file with the first reader that seems to work
|
||||
for (SubtitleFormat format : likelyFormats) {
|
||||
// decode bytes and beware of byte-order marks
|
||||
Reader reader = createTextReader(new ByteBufferInputStream(file.getData()), true, UTF_8);
|
||||
List<SubtitleElement> subtitles = format.getDecoder().decode(content);
|
||||
|
||||
// reset reader to position 0
|
||||
SubtitleReader parser = format.newReader(reader);
|
||||
|
||||
if (parser.hasNext()) {
|
||||
// correct format found
|
||||
List<SubtitleElement> list = new ArrayList<SubtitleElement>(500);
|
||||
|
||||
// read subtitle file
|
||||
while (parser.hasNext()) {
|
||||
list.add(parser.next());
|
||||
}
|
||||
|
||||
return list;
|
||||
if (subtitles.size() > 0) {
|
||||
return subtitles;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,19 +1,17 @@
|
|||
|
||||
package net.filebot.subtitle;
|
||||
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.StringReader;
|
||||
import java.util.Scanner;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
|
||||
public class MicroDVDReaderTest {
|
||||
|
||||
@Test
|
||||
public void parse() throws Exception {
|
||||
MicroDVDReader reader = new MicroDVDReader(new StringReader("{856}{900}what's the plan?"));
|
||||
MicroDVDReader reader = new MicroDVDReader(new Scanner("{856}{900}what's the plan?"));
|
||||
|
||||
SubtitleElement element = reader.next();
|
||||
|
||||
|
@ -22,10 +20,9 @@ public class MicroDVDReaderTest {
|
|||
assertEquals("what's the plan?", element.getText());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void fps() throws Exception {
|
||||
MicroDVDReader reader = new MicroDVDReader(new StringReader("{1}{1}100\n{300}{400} trim me "));
|
||||
MicroDVDReader reader = new MicroDVDReader(new Scanner("{1}{1}100\n{300}{400} trim me "));
|
||||
|
||||
SubtitleElement element = reader.next();
|
||||
|
||||
|
@ -34,10 +31,9 @@ public class MicroDVDReaderTest {
|
|||
assertEquals("trim me", element.getText());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void newline() throws Exception {
|
||||
MicroDVDReader reader = new MicroDVDReader(new StringReader("\n\n{300}{400} l1|l2|l3| \n\n"));
|
||||
MicroDVDReader reader = new MicroDVDReader(new Scanner("\n\n{300}{400} l1|l2|l3| \n\n"));
|
||||
|
||||
String[] lines = reader.next().getText().split("\\n");
|
||||
|
||||
|
|
Loading…
Reference in New Issue