use of org.fagu.fmv.utils.time.Time in project fmv by f-agu.
the class Chapter method toString.
/**
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
StringBuilder buf = new StringBuilder();
String title = title().orElse(null);
if (title != null) {
buf.append(title).append('=');
}
Time startTime = startTime().orElse(null);
Time endTime = endTime().orElse(null);
if (startTime != null && endTime != null) {
buf.append(startTime).append('>').append(endTime);
} else {
OptionalLong start = start();
OptionalLong end = end();
if (start.isPresent() && end.isPresent()) {
buf.append(start.getAsLong()).append('>').append(end.getAsLong());
}
}
return buf.toString();
}
use of org.fagu.fmv.utils.time.Time in project fmv by f-agu.
the class Bootstrap method isSimilar.
private boolean isSimilar(Map<Time, File> map1, Map<Time, File> map2) throws IOException {
AtomicBoolean similar = new AtomicBoolean(false);
List<CompletableFuture<Boolean>> completableFutures = new ArrayList<>();
for (Entry<Time, File> entry : map1.entrySet()) {
completableFutures.add(CompletableFuture.supplyAsync(() -> {
try {
double diffPercent = getDiffPercent(entry.getValue(), map2.get(entry.getKey()));
similar.set(diffPercent < MAX_PERCENT_NOT_SIMILAR);
return similar.get();
} catch (IOException e) {
throw new RuntimeException(e);
}
}, executorService));
}
try {
CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[completableFutures.size()])).get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
return similar.get();
}
use of org.fagu.fmv.utils.time.Time in project fmv by f-agu.
the class Template method load.
public static Template load(File propertiesFile) throws IOException {
Properties properties = new Properties();
try (InputStream inputStream = new FileInputStream(propertiesFile)) {
properties.load(inputStream);
}
Map<Time, File> modelMap = new HashMap<>();
for (Entry<Object, Object> entry : properties.entrySet()) {
String key = (String) entry.getKey();
String value = (String) entry.getValue();
if (key.startsWith("model.")) {
Time time = Time.parse(key.substring(6));
File file = findModel(propertiesFile, value);
modelMap.put(time, file);
}
}
String name = properties.getProperty("name");
Time offsetStart = parseTime(properties.getProperty("offset-time"));
Duration endDuration = parseDuration(properties.getProperty("end-duration"));
Logo logo = loadLogo(properties);
return new Template(name, modelMap, offsetStart, endDuration, logo);
}
use of org.fagu.fmv.utils.time.Time in project fmv by f-agu.
the class ConcatFadeExecutable method applyConcatFade.
/**
* @param builder
* @param inputProcessors
* @param toFile
* @param cache
* @throws IOException
*/
protected void applyConcatFade(FFMPEGExecutorBuilder builder, List<InputProcessor> inputProcessors, File toFile, Cache cache) throws IOException {
if (inputProcessors.size() != 2) {
throw new RuntimeException("Need 2 inputs ! : " + inputProcessors);
}
InputProcessor video1InputProcessor = inputProcessors.get(0);
InputProcessor video2InputProcessor = inputProcessors.get(1);
VideoStream videoStream1 = video1InputProcessor.getMovieMetadatas().getVideoStream();
VideoStream videoStream2 = video2InputProcessor.getMovieMetadatas().getVideoStream();
Time startTimeT1 = Time.valueOf(videoStream1.duration().get().toSeconds() - duration.toSeconds());
Duration duration0T1 = Duration.valueOf(startTimeT1.toSeconds());
Time startTimeT2 = Time.valueOf(videoStream2.duration().get().toSeconds() - duration.toSeconds());
Duration durationT2END = Duration.valueOf(startTimeT2.toSeconds());
// source 1: video
NullSourceVideo nullSourceVideo1 = NullSourceVideo.build().size(videoStream1.size()).duration(durationT2END);
Concat concat1V = Concat.create(builder, video1InputProcessor, FilterComplex.create(nullSourceVideo1)).countVideo(1).countAudio(0).countInputs(2);
// source 1: audio
AudioGenerator audioGenerator1 = AudioGenerator.build().silence().duration(durationT2END);
Concat concat1A = Concat.create(builder, video1InputProcessor, FilterComplex.create(audioGenerator1)).countVideo(0).countAudio(1).countInputs(2);
FilterComplex fadeAudio1 = FilterComplex.create(FadeAudio.out().startTime(startTimeT1).duration(duration)).addInput(concat1A);
// source 2: video
NullSourceVideo nullSourceVideo2 = NullSourceVideo.build().size(videoStream2.size()).duration(duration0T1);
Concat concat2V = Concat.create(builder, FilterComplex.create(nullSourceVideo2), video2InputProcessor).countVideo(1).countAudio(0).countInputs(2);
// source 2: audio
AudioGenerator audioGenerator2 = AudioGenerator.build().silence().duration(duration0T1);
Concat concat2A = Concat.create(builder, FilterComplex.create(audioGenerator2), video2InputProcessor).countVideo(0).countAudio(1).countInputs(2);
FilterComplex fadeAudio2 = FilterComplex.create(FadeAudio.in().startTime(startTimeT1).duration(duration)).addInput(concat2A);
// blend / merge video
SetSAR setSAR = SetSAR.toRatio("1");
Format formatRGBA = Format.with(PixelFormat.RGBA);
FilterComplex vfc1 = FilterComplex.create(setSAR, formatRGBA).addInput(concat1V);
FilterComplex vfc2 = FilterComplex.create(setSAR, formatRGBA).addInput(concat2V);
Blend blend = Blend.build().mode(Mode.ADDITION).repeatLast(true).opacity(1).exprFade(startTimeT1, duration);
Format formatYUV = Format.with(PixelFormat.YUVA422P10LE);
FilterComplex vfcBlend = FilterComplex.create(blend, formatYUV).addInput(vfc1).addInput(vfc2);
builder.filter(vfcBlend);
// merge audio
FilterComplex audioMix = AudioMix.build().duration(MixAudioDuration.SHORTEST).addInput(fadeAudio1).addInput(fadeAudio2);
builder.filter(audioMix);
outputProcessor(builder, toFile, cache);
}
use of org.fagu.fmv.utils.time.Time in project fmv by f-agu.
the class FFMPEGExecutorBuilderTestCase method testInputProcessor_timeSeek.
/**
*/
@Test
public void testInputProcessor_timeSeek() {
MediaInput input = mockInput("/path/file");
InputProcessor inputProcessor = ffmpegExecutorBuilder.addMediaInput(input);
inputProcessor.timeSeek(new Time(1, 2, 3.4));
assertArgs("-ss", "01:02:03.400", "-i", "/path/file");
}
Aggregations