All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.dnbn.submerge.api.TimedLinesAPI Maven / Gradle / Ivy

The newest version!
package com.github.dnbn.submerge.api;

import java.time.LocalTime;
import java.time.temporal.ChronoUnit;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

import com.github.dnbn.submerge.api.subtitle.common.SubtitleLine;
import com.github.dnbn.submerge.api.subtitle.common.SubtitleTime;
import com.github.dnbn.submerge.api.subtitle.common.TimedLine;
import com.github.dnbn.submerge.api.subtitle.common.TimedObject;

public class TimedLinesAPI {

	/**
	 * Search the line that has the closest start time compared to a specified time. If
	 * the gap beetween the two start times is greater than the toleranceDelay (in ms) the
	 * line will be ignored.
	 * 
	 * @param tolerance the maximum gap in millis
	 * @param lines the lines (ascending sort)
	 * @param time the target start time
	 * @return
	 */
	public TimedLine closestByStart(List lines, final LocalTime time, int tolerance) {

		// Binary search will find the first "random" match
		int iAnyMatch = Collections.binarySearch(lines, new SubtitleLine<>(new SubtitleTime(time, null)),
				new Comparator() {

					@Override
					public int compare(TimedLine compare, TimedLine base) {

						LocalTime search = base.getTime().getStart();
						LocalTime start = compare.getTime().getStart();

						if (getDelay(search, start) < tolerance) {
							return 0;
						}

						return start.compareTo(search);
					}
				});

		if (iAnyMatch < 0) {
			return null;
		}

		// Search for other matches
		Set matches = new TreeSet<>();
		matches.add(lines.get(iAnyMatch));

		int i = iAnyMatch;
		while (i > 0) {
			TimedLine previous = lines.get(--i);
			if (getDelay(time, previous.getTime().getStart()) >= tolerance) {
				break;
			}
			matches.add(previous);
		}

		i = iAnyMatch;
		while (i < lines.size() -1) {
			TimedLine next = lines.get(++i);
			if (getDelay(time, next.getTime().getStart()) >= tolerance) {
				break;
			}
			matches.add(next);
		}

		// return the closest match
		return matches.stream()
				.sorted((m1, m2) -> getDelay(m1.getTime().getStart(), time) - getDelay(m2.getTime().getStart(), time))
				.findFirst().get();
	}

	/**
	 * Get the absolute delay beetween 2 times
	 * 
	 * @return the absolute delay beetween 2 times
	 */
	public int getDelay(LocalTime start, LocalTime end) {

		return (int) Math.abs(ChronoUnit.MILLIS.between(start, end));
	}

	/**
	 * Check if a timed object appear before or at the same time as an other timed object
	 * 
	 * @param elementToCompare
	 * @param comparedElement
	 * @return
	 */
	public boolean isEqualsOrAfter(TimedObject elementToCompare, TimedObject comparedElement) {

		return comparedElement.getStart().isAfter(elementToCompare.getEnd())
				|| comparedElement.getStart().equals(elementToCompare.getEnd());
	}

	/**
	 * Find the line displayed at targetTime
	 * 
	 * @param lines the lines (ascending sort)
	 * @param time the target time
	 * @return
	 */
	public TimedLine intersected(List lines, LocalTime time) {

		int index = Collections.binarySearch(lines, new SubtitleLine<>(new SubtitleTime(time, null)),
				new Comparator() {

					@Override
					public int compare(TimedLine compare, TimedLine base) {

						LocalTime search = base.getTime().getStart();
						LocalTime start = compare.getTime().getStart();
						LocalTime end = compare.getTime().getEnd();

						if ((start.isBefore(search) || start.equals(search))
								&& (end.isAfter(search) || start.equals(search))) {
							return 0;
						}

						return start.compareTo(search);
					}
				});

		return index < 0 ? null : lines.get(index);
	}

	/**
	 * Find a line displayed between 2 times
	 * 
	 * @param lines the lines (ascending sort)
	 * @param
	 * 
	 * @return
	 */
	public TimedLine intersected(List lines, LocalTime start, LocalTime end) {

		int index = Collections.binarySearch(lines, new SubtitleLine<>(new SubtitleTime(start, end)),
				new Comparator() {

					@Override
					public int compare(TimedLine compare, TimedLine base) {

						LocalTime searchStart = base.getTime().getStart();
						LocalTime searchEnd = base.getTime().getEnd();

						LocalTime start = compare.getTime().getStart();
						LocalTime end = compare.getTime().getEnd();

						if (searchStart.isBefore(start) && searchEnd.isAfter(end)) {
							return 0;
						}

						return compare.compareTo(base);
					}
				});

		return index < 0 ? null : lines.get(index);
	}

	/**
	 * Find a sublitle line from it's time
	 * 
	 * @param lines the subtitle lines
	 * @param time the timed object
	 * @return
	 */
	public int findByTime(List lines, TimedObject time) {

		return Collections.binarySearch(lines, new SubtitleLine<>(time), SubtitleLine.timeComparator);
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy