package com.github.shell88.bddvideoannotator.annotationfile.converter;
import com.github.shell88.bddvideoannotator.annotationfile.exporter.Helper;
import com.github.shell88.bddvideoannotator.annotationfile.exporter.HtmlAnnotationExporter;
import com.github.shell88.bddvideoannotator.annotationfile.exporter.ScenarioAnnotationsDto;
import com.github.shell88.bddvideoannotator.annotationfile.parser.AnnotationFileParserFactory;
import org.apache.commons.io.FilenameUtils;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* Converts AnnotationFiles to a HTMLReport using
* {@link FfmpegCommandLineH264Encoder} and {@link HtmlAnnotationExporter}.
*
* @author Hell
*
*/
//FIXME: fix linking of steps to video in Internet Explorer (media fragments)
public class HtmlConverter {
private File scanDir;
private File targetDir;
/**
* @param scanDir
* - Directory to search for AnnoationFiles.
* @param targetDir
* - TargetDirectory where to store the HTMLReport.
*/
public HtmlConverter(String scanDir, String targetDir) {
this(new File(scanDir),new File(targetDir));
}
/**
* @param scanDir
* - Directory to search for AnnoationFiles.
* @param targetDir
* - TargetDirectory where to store the HTMLReport.
*/
public HtmlConverter(File scanDir, File targetDir) {
if (!scanDir.exists()) {
throw new IllegalArgumentException(scanDir.getAbsolutePath()
+ " not found!");
}
if (!targetDir.exists()) {
targetDir.mkdir();
}
if (!targetDir.canWrite()) {
throw new IllegalArgumentException(targetDir.getAbsolutePath()
+ " not writable!");
}
this.scanDir = scanDir;
this.targetDir = targetDir;
}
/**
* Converts the annotationFiles from {@link #scanDir} to a HTML-Report.
*
* @throws Throwable
* - IOErrors
*/
public void convert() throws Throwable {
System.out.println("----Start converting2html inputDirectory: " + scanDir.getAbsolutePath()
+ " target " + this.targetDir.getAbsolutePath());
File[] annotationFiles = Helper.getAnnotationFilesInDirectory(scanDir);
if (annotationFiles.length == 0) {
System.out.println("No annotation files found => exit");
return;
}
BlockingQueue<Runnable> encodingQueue = new ArrayBlockingQueue<Runnable>(
annotationFiles.length);
ThreadPoolExecutor encodingThreadPool = new ThreadPoolExecutor(4, 4, 30,
TimeUnit.SECONDS, encodingQueue);
HtmlAnnotationExporter annotationExporterHtml = new HtmlAnnotationExporter(
targetDir);
List<Future<Object>> encodingTasks = new ArrayList<Future<Object>>(
annotationFiles.length);
ScenarioAnnotationsDto dto;
File videoInputFile;
File videoOutputFile;
for (File annotationFile : annotationFiles) {
System.out.println("Parsing : " + annotationFile.getName());
dto = AnnotationFileParserFactory.getFileParser(annotationFile).parse();
videoInputFile = new File(annotationFile.getParentFile(),
dto.getNameVideoFile());
if (!videoInputFile.exists()) {
throw new FileNotFoundException(
"Could not find videoReferenceFile for " + annotationFile);
}
if (!dto.getSha1ChecksumVideo().equals(
Helper.calcSha1Checksum(videoInputFile))) {
throw new IllegalArgumentException("Parsed SHA-1 Checksum in "
+ annotationFile.getAbsolutePath()
+ " doesn´t match to refered VideoFile " + videoInputFile.getName());
}
System.out.println("Encoding: " + videoInputFile.getName());
videoOutputFile = new File(targetDir,
FilenameUtils.removeExtension(videoInputFile.getName()) + ".mp4");
encodingTasks.add(encodingThreadPool
.submit(new FfmpegCommandLineH264Encoder(videoInputFile,
videoOutputFile)));
dto.setNameVideoFile(videoOutputFile.getName());
annotationExporterHtml.write(dto);
}
encodingThreadPool.shutdown();
for (Future<Object> encodingTask : encodingTasks) {
encodingTask.get();
}
encodingThreadPool.awaitTermination(15, TimeUnit.MINUTES);
System.out.println("----End of converting2html");
}
/**
* Runs HtmlConverter from the command line (used in standalone_server).
* Requires ffmpeg to be installed and available on the system path.
*
* @param args 0: directory to scan for eaf/avi files
* args 1: target directory for the html report
* @throws Throwable when something with the annotationfiles is wrong
* or encoding with ffmpeg did not work
*/
public static void main(String[] args) throws Throwable {
if (args.length != 2) {
throw new IllegalArgumentException(
"Misconfiguration: <scanDirectory> <targetDirectory");
}
new HtmlConverter(
new File(args[0]),
new File(args[1])
).convert();
}
}