diff options
Diffstat (limited to 'core/src')
-rw-r--r-- | core/src/main/java/de/danoeh/antennapod/core/util/Converter.java | 29 | ||||
-rw-r--r-- | core/src/main/java/de/danoeh/antennapod/core/util/playback/Timeline.java | 94 |
2 files changed, 87 insertions, 36 deletions
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/Converter.java b/core/src/main/java/de/danoeh/antennapod/core/util/Converter.java index 6966667bf..6ecca941a 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/Converter.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/Converter.java @@ -74,13 +74,14 @@ public final class Converter { return String.format(Locale.getDefault(), "%02d:%02d:%02d", h, m, s); } - /** Converts milliseconds to a string containing hours and minutes */ - public static String getDurationStringShort(int duration) { - int h = duration / HOURS_MIL; - int rest = duration - h * HOURS_MIL; - int m = rest / MINUTES_MIL; - - return String.format(Locale.getDefault(), "%02d:%02d", h, m); + /** Converts milliseconds to a string containing hours and minutes or minutes and seconds*/ + public static String getDurationStringShort(int duration, boolean durationIsInHours) { + int firstPartBase = durationIsInHours ? HOURS_MIL : MINUTES_MIL; + int firstPart = duration / firstPartBase; + int leftoverFromFirstPart = duration - firstPart * firstPartBase; + int secondPart = leftoverFromFirstPart / (durationIsInHours ? MINUTES_MIL : SECONDS_MIL); + + return String.format(Locale.getDefault(), "%02d:%02d", firstPart, secondPart); } /** Converts long duration string (HH:MM:SS) to milliseconds. */ @@ -94,14 +95,20 @@ public final class Converter { Integer.parseInt(parts[2]) * 1000; } - /** Converts short duration string (HH:MM) to milliseconds. */ - public static int durationStringShortToMs(String input) { + /** + * Converts short duration string (XX:YY) to milliseconds. If durationIsInHours is true then the + * format is HH:MM, otherwise it's MM:SS. + * */ + public static int durationStringShortToMs(String input, boolean durationIsInHours) { String[] parts = input.split(":"); if (parts.length != 2) { return 0; } - return Integer.parseInt(parts[0]) * 3600 * 1000 + - Integer.parseInt(parts[1]) * 1000 * 60; + + int modifier = durationIsInHours ? 60 : 1; + + return Integer.parseInt(parts[0]) * 60 * 1000 * modifier+ + Integer.parseInt(parts[1]) * 1000 * modifier; } /** Converts milliseconds to a localized string containing hours and minutes */ diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/playback/Timeline.java b/core/src/main/java/de/danoeh/antennapod/core/util/playback/Timeline.java index 34cfe6d05..56550bb06 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/playback/Timeline.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/playback/Timeline.java @@ -7,6 +7,7 @@ import android.support.annotation.ColorInt; import android.support.annotation.NonNull; import android.text.TextUtils; import android.util.Log; +import android.util.Pair; import android.util.TypedValue; import org.jsoup.Jsoup; @@ -14,6 +15,7 @@ import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; +import java.util.ArrayList; import java.util.Locale; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -68,7 +70,7 @@ public class Timeline { private static final Pattern TIMECODE_LINK_REGEX = Pattern.compile("antennapod://timecode/((\\d+))"); private static final String TIMECODE_LINK = "<a class=\"timecode\" href=\"antennapod://timecode/%d\">%s</a>"; - private static final Pattern TIMECODE_REGEX = Pattern.compile("\\b(?:(?:(([0-9][0-9])):))?(([0-9][0-9])):(([0-9][0-9]))\\b"); + private static final Pattern TIMECODE_REGEX = Pattern.compile("\\b((\\d+):)?(\\d+):(\\d{2})\\b"); private static final Pattern LINE_BREAK_REGEX = Pattern.compile("<br */?>"); @@ -127,35 +129,12 @@ public class Timeline { // apply timecode links if (addTimecodes) { - Elements elementsWithTimeCodes = document.body().getElementsMatchingOwnText(TIMECODE_REGEX); - Log.d(TAG, "Recognized " + elementsWithTimeCodes.size() + " timecodes"); - for (Element element : elementsWithTimeCodes) { - Matcher matcherLong = TIMECODE_REGEX.matcher(element.html()); - StringBuffer buffer = new StringBuffer(); - while (matcherLong.find()) { - String h = matcherLong.group(1); - String group = matcherLong.group(0); - int time = (h != null) ? Converter.durationStringLongToMs(group) : - Converter.durationStringShortToMs(group); - - String rep; - if (playable == null || playable.getDuration() > time) { - rep = String.format(Locale.getDefault(), TIMECODE_LINK, time, group); - } else { - rep = group; - } - matcherLong.appendReplacement(buffer, rep); - } - matcherLong.appendTail(buffer); - - element.html(buffer.toString()); - } + addTimecodes(document, playable); } return document.toString(); } - /** * Returns true if the given link is a timecode link. */ @@ -186,4 +165,69 @@ public class Timeline { public void setShownotesProvider(@NonNull ShownotesProvider shownotesProvider) { this.shownotesProvider = shownotesProvider; } + + private void addTimecodes(Document document, final Playable playable) { + Elements elementsWithTimeCodes = document.body().getElementsMatchingOwnText(TIMECODE_REGEX); + Log.d(TAG, "Recognized " + elementsWithTimeCodes.size() + " timecodes"); + + if (elementsWithTimeCodes.size() == 0) { + // No elements with timecodes + return; + } + + int playableDuration = playable == null ? Integer.MAX_VALUE : playable.getDuration(); + boolean useHourFormat = true; + + if (playableDuration != Integer.MAX_VALUE) { + + // We need to decide if we are going to treat short timecodes as HH:MM or MM:SS. To do + // so we will parse all the short timecodes and see if they fit in the duration. If one + // does not we will use MM:SS, otherwise all will be parsed as HH:MM. + for (Element element : elementsWithTimeCodes) { + Matcher matcherForElement = TIMECODE_REGEX.matcher(element.html()); + while (matcherForElement.find()) { + + // We only want short timecodes right now. + if (matcherForElement.group(1) == null) { + int time = Converter.durationStringShortToMs(matcherForElement.group(0), true); + + // If the parsed timecode is greater then the duration then we know we need to + // use the minute format so we are done. + if (time > playableDuration) { + useHourFormat = false; + break; + } + } + } + + if (!useHourFormat) { + break; + } + } + } + + for (Element element : elementsWithTimeCodes) { + + Matcher matcherForElement = TIMECODE_REGEX.matcher(element.html()); + StringBuffer buffer = new StringBuffer(); + + while (matcherForElement.find()) { + String group = matcherForElement.group(0); + + int time = matcherForElement.group(1) != null + ? Converter.durationStringLongToMs(group) + : Converter.durationStringShortToMs(group, useHourFormat); + + String replacementText = group; + if (time < playableDuration) { + replacementText = String.format(Locale.getDefault(), TIMECODE_LINK, time, group); + } + + matcherForElement.appendReplacement(buffer, replacementText); + } + + matcherForElement.appendTail(buffer); + element.html(buffer.toString()); + } + } } |