package info.toyonos.subtitles4j.factory;
import info.toyonos.subtitles4j.model.SubtitlesContainer;
import info.toyonos.subtitles4j.model.SubtitlesContainer.Caption;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
public class SRTFactory extends AbstractFormatFactory
{
private static final SimpleDateFormat TIMESTAMPS_SDF = new SimpleDateFormat("HH:mm:ss,SSS");
private static final String TIMESTAMPS_SEPARATOR = " --> ";
private int index;
protected SRTFactory() {}
@Override
public SubtitlesContainer fromStream(InputStream input) throws MalformedSubtitlesException, IOException
{
SubtitlesContainer container = new SubtitlesContainer();
try (LineNumberReader reader = new LineNumberReader(new InputStreamReader(input)))
{
String line = null;
int i = 1;
while ((line = reader.readLine()) != null)
{
long start, end;
line = removeUTF8BOM(line.trim());
// Empty line : ignored
if (line.isEmpty()) continue;
// Index verification
if (line.matches("[0-9]+"))
{
int foundIndex = Integer.parseInt(line);
if (foundIndex != i++) throw malformedFileException("Unexpected index %d", reader.getLineNumber(), foundIndex);
}
// Timestamps
String timestamps = reader.readLine();
if (timestamps == null) throw unexpectedEndOfFile("timestamps declaration was expected here");
String[] timestampsArray = timestamps.split(TIMESTAMPS_SEPARATOR);
start = getMilliseconds(timestampsArray[0], reader.getLineNumber());
end = getMilliseconds(timestampsArray[1], reader.getLineNumber());
// Text content
List<String> subtitlesLines = new ArrayList<String>();
String subtitlesLine = null;
while ((subtitlesLine = reader.readLine()) != null && !subtitlesLine.trim().isEmpty())
{
subtitlesLines.add(subtitlesLine.trim());
}
// Adding the caption
container.addCaption(start, end, subtitlesLines);
}
logger.trace("The subtitles source has been read with success, {} captions read", container.getCaptions().size());
return container;
}
}
private MalformedSubtitlesException unexpectedEndOfFile(String message)
{
return new MalformedSubtitlesException("Unexpected end of file : " + message);
}
@Override
public void visit(SubtitlesContainer container) throws SubtitlesGenerationException
{
super.visit(container);
// The index starts at 1
index = 1;
}
@Override
public void visit(Caption caption) throws SubtitlesGenerationException
{
super.visit(caption);
// Writing the caption
subtitlesWriter.append(String.valueOf(index++))
.append(System.getProperty("line.separator"))
.append(formatMilliseconds(caption.getStart()))
.append(TIMESTAMPS_SEPARATOR)
.append(formatMilliseconds(caption.getEnd()))
.append(System.getProperty("line.separator"));
subtitlesWriter.println(StringUtils.join(caption.getLines(), '\n'));
subtitlesWriter.println();
}
@Override
protected SimpleDateFormat getTimestampDateFormat()
{
return TIMESTAMPS_SDF;
}
}