Skip to content

Commit 11b652e

Browse files
mattgarrishrdeltour
authored andcommitted
feat: improve checking of audio clip times in Media Overlays
- Integrate code from the DAISY Consortium to parse and compare SMIL clock values - Update check: move the clipBegin/clipEnd equality test into Java code so it works even with different SMIL clock syntaxes - New check: clipBegin is not temporally after clipEnd - Add and update associated tests
1 parent 794b7ce commit 11b652e

File tree

11 files changed

+587
-11
lines changed

11 files changed

+587
-11
lines changed

src/main/java/com/adobe/epubcheck/messages/DefaultSeverities.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,8 @@ private void initialize()
144144
severities.put(MessageId.MED_005, Severity.ERROR);
145145
severities.put(MessageId.MED_006, Severity.USAGE);
146146
severities.put(MessageId.MED_007, Severity.ERROR);
147+
severities.put(MessageId.MED_008, Severity.ERROR);
148+
severities.put(MessageId.MED_009, Severity.ERROR);
147149

148150
// NAV
149151
severities.put(MessageId.NAV_001, Severity.ERROR);

src/main/java/com/adobe/epubcheck/messages/MessageId.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,8 @@ public enum MessageId implements Comparable<MessageId>
138138
MED_005("MED-005"),
139139
MED_006("MED_006"),
140140
MED_007("MED_007"),
141+
MED_008("MED-008"),
142+
MED_009("MED-009"),
141143

142144
// Epub3 based table of content errors
143145
NAV_001("NAV-001"),
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* This class was originally created by the DAISY Consortium
3+
* for another project, licensed under LGPL v2.1.
4+
* It is now integrated in EPUBCheck and relicensed under
5+
* EPUBCheck’s primary license.
6+
* See https://github.com/w3c/epubcheck/pull/1173
7+
*/
8+
package com.adobe.epubcheck.overlay;
9+
10+
public class ClipTime {
11+
12+
private final Double timeInMs;
13+
14+
public ClipTime() {
15+
timeInMs = null;
16+
}
17+
18+
public ClipTime(double timeInMs) {
19+
this.timeInMs = new Double(timeInMs);
20+
}
21+
22+
public double getTimeInMs() {
23+
if(notSet()) {
24+
return 0;
25+
} else {
26+
return timeInMs;
27+
}
28+
}
29+
30+
public ClipTime roundedToMilliSeconds() {
31+
return new ClipTime(Math.round(this.getTimeInMs()));
32+
}
33+
34+
public ClipTime floorToMilliSeconds() {
35+
return new ClipTime(Math.floor(this.getTimeInMs()));
36+
}
37+
38+
public boolean notSet() {
39+
if(this.timeInMs == null) {
40+
return true;
41+
} else {
42+
return false;
43+
}
44+
}
45+
46+
public ClipTime add(ClipTime timeToAdd) {
47+
return new ClipTime(this.getTimeInMs() + timeToAdd.getTimeInMs());
48+
}
49+
50+
public ClipTime subtract(ClipTime timeToSubtract) {
51+
return new ClipTime(this.getTimeInMs() - timeToSubtract.getTimeInMs());
52+
}
53+
}

src/main/java/com/adobe/epubcheck/overlay/OverlayHandler.java

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public class OverlayHandler implements XMLHandler
3939
private boolean checkedUnsupportedXMLVersion;
4040

4141
private Map<String, Vocab> vocabs = RESERVED_VOCABS;
42-
42+
4343
public OverlayHandler(ValidationContext context, XMLParser parser)
4444
{
4545
this.context = context;
@@ -78,12 +78,48 @@ else if (name.equals("text"))
7878
else if (name.equals("audio"))
7979
{
8080
processRef(e.getAttribute("src"), XRefChecker.Type.AUDIO);
81+
checkTime(e.getAttribute("clipBegin"), e.getAttribute("clipEnd"));
8182
}
8283
else if (name.equals("body") || name.equals("par"))
8384
{
8485
checkType(e.getAttributeNS(EpubConstants.EpubTypeNamespaceUri, "type"));
8586
}
8687
}
88+
89+
private void checkTime(String clipBegin, String clipEnd) {
90+
91+
if (clipEnd == null) {
92+
// missing clipEnd attribute means clip plays to end so no comparisons possible
93+
return;
94+
}
95+
96+
if (clipBegin == null) {
97+
// set clipBegin to 0 if the attribute isn't set to allow comparisons
98+
clipBegin = "0";
99+
}
100+
101+
SmilClock start;
102+
SmilClock end;
103+
104+
try {
105+
start = new SmilClock(clipBegin);
106+
end = new SmilClock(clipEnd);
107+
}
108+
catch (Exception ex) {
109+
// invalid clock time will be reported by the schema
110+
return;
111+
}
112+
113+
if (start.compareTo(end) == 1) {
114+
// clipEnd is chronologically before clipBegin
115+
report.message(MessageId.MED_008, EPUBLocation.create(path, parser.getLineNumber(), parser.getColumnNumber()));
116+
}
117+
118+
else if (start.equals(end)) {
119+
// clipBegin and clipEnd are equal
120+
report.message(MessageId.MED_009, EPUBLocation.create(path, parser.getLineNumber(), parser.getColumnNumber()));
121+
}
122+
}
87123

88124
private void checkType(String type)
89125
{
@@ -149,5 +185,4 @@ public void ignorableWhitespace(char[] chars, int arg1, int arg2)
149185
public void processingInstruction(String arg0, String arg1)
150186
{
151187
}
152-
153188
}

0 commit comments

Comments
 (0)