1 package org.readium.r2_streamer.model.publication.SMIL;
3 import org.w3c.dom.Element;
6 * Created by gautam chibde on 23/5/17.
9 public final class SMILParser {
11 //Describes the different time string format of the SMIL tags
12 private enum SMILTimeFormat {
22 * Converts a smile time string into seconds String.
24 * @param time The smile time String.
25 * @return The converted value in Seconds as String.
27 public static String smilTimeToSeconds(String time) {
28 if (time.contains("h")) {
29 return convertToSeconds(time, SMILTimeFormat.HOUR);
30 } else if (time.contains("s")) {
31 return convertToSeconds(time, SMILTimeFormat.SECOND);
33 } else if (time.contains("ms")) {
34 return convertToSeconds(time, SMILTimeFormat.MILLISECOND);
36 int count = time.split(":").length;
39 return convertToSeconds(time, SMILTimeFormat.SPLIT_MONADIC);
41 return convertToSeconds(time, SMILTimeFormat.SPLIT_DYADIC);
43 return convertToSeconds(time, SMILTimeFormat.SPLIT_TRIADIC);
45 return ""; // Should return null?
51 * Convert the smileTime to the equivalent in seconds given it's type.
53 * @param time The SMILTime String.
54 * @param type type format of smileTime
55 * @return The converted value in Seconds as String.
57 private static String convertToSeconds(String time, SMILTimeFormat type) {
61 double ms = Double.parseDouble(time.replaceAll("ms", ""));
62 return String.valueOf(ms / 1000.0);
64 return time.replaceAll("s", "");
66 String[] hourMin = time.split(time.replaceAll("h", ""));
67 double hrToSec = Double.parseDouble(hourMin[0]) * 3600.0;
68 double minToSec = Double.parseDouble(hourMin[1]) * 0.6 * 60.0;
69 return String.valueOf(hrToSec + minToSec);
73 String[] minSec = time.split(":");
74 seconds += Double.parseDouble(minSec[0]) * 60.0;
75 seconds += parseSeconds(time);
76 return String.valueOf(seconds);
78 String[] hourMinSec = time.split(":");
80 seconds += (Double.parseDouble(hourMinSec[0])) * 3600.0;
82 seconds += (Double.parseDouble(hourMinSec[1])) * 60.0;
84 seconds += parseSeconds(hourMinSec[2]);
85 return String.valueOf(seconds);
92 * Parse the <audio> XML element, children of <par> elements.
94 * @param element The audio XML element.
95 * @return The formatted string representing the data
96 * format => audio_path#t=start_time,end_time.
98 public static String parseAudio(Element element, String href) {
99 String audio, clipBegin, clipEnd;
100 if (element.hasAttribute("src")) {
101 audio = element.getAttribute("src");
105 if (element.hasAttribute("clipBegin")) {
106 clipBegin = element.getAttribute("clipBegin");
110 if (element.hasAttribute("clipEnd")) {
111 clipEnd = element.getAttribute("clipEnd");
116 return getAbsoluteUriPath(href, audio) +
118 smilTimeToSeconds(clipBegin) +
120 smilTimeToSeconds(clipEnd);
124 * function creates absolute URI path for the audio file.
125 * in ref => https://github.com/readium/readium-2/issues/38.
127 * TODO check with other Epub file. specifically with deep hierarchy
129 * @param href path of SMIL file.
130 * @param audio audio path in SMIL file to update.
131 * @return absolute URI path.
133 private static String getAbsoluteUriPath(String href, String audio) {
134 StringBuilder toAppend = new StringBuilder();
135 if (href.contains("/")) {
136 // removes file name from path
137 int startIndex = href.lastIndexOf("/");
138 String filePath = href.substring(0, startIndex);
140 int count = countSubString(audio, "../");
141 String[] items = filePath.split("/");
143 for (int i = 0; i < count; i++) {
144 if (items.length > i) {
145 if ((items.length - i - 2) >= 0) {
146 toAppend.insert(0, items[items.length - i - 2] + "/");
151 if (audio.contains("../")) {
152 audio = audio.replace("../", "");
154 return toAppend.toString() + audio;
158 * Return the seconds double value from a possible SS.MS format.
160 * @param time The seconds String.
161 * @return The translated Double value.
163 private static double parseSeconds(String time) {
164 String[] sec = time.split(":");
166 if (sec.length == 2) {
167 seconds = Double.parseDouble(sec[0]);
168 seconds += (Double.parseDouble(sec[1])) / 1000.0;
170 seconds = Double.parseDouble(time);
176 * Returns number of occurrences of string b in string a.
178 * @param a string in which to find occurrences.
179 * @param b input substring
182 private static int countSubString(String a, String b) {
185 while (lastIndex != -1) {
187 lastIndex = a.indexOf(b, lastIndex);
189 if (lastIndex != -1) {
191 lastIndex += b.length();