diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/text/ttml/TtmlNode.java b/libraries/extractor/src/main/java/androidx/media3/extractor/text/ttml/TtmlNode.java index 47f7ba4da8..3405e02228 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/text/ttml/TtmlNode.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/text/ttml/TtmlNode.java @@ -53,6 +53,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; public static final String ANONYMOUS_REGION_ID = ""; public static final String ATTR_ID = "id"; + public static final String ATTR_STYLE = "style"; public static final String ATTR_TTS_ORIGIN = "origin"; public static final String ATTR_TTS_EXTENT = "extent"; public static final String ATTR_TTS_DISPLAY_ALIGN = "displayAlign"; diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/text/ttml/TtmlParser.java b/libraries/extractor/src/main/java/androidx/media3/extractor/text/ttml/TtmlParser.java index d1d615657a..2cf87fc094 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/text/ttml/TtmlParser.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/text/ttml/TtmlParser.java @@ -315,7 +315,7 @@ public final class TtmlParser implements SubtitleParser { globalStyles.put(styleId, style); } } else if (XmlPullParserUtil.isStartTag(xmlParser, TtmlNode.TAG_REGION)) { - @Nullable TtmlRegion ttmlRegion = parseRegionAttributes(xmlParser, cellRows, ttsExtent); + @Nullable TtmlRegion ttmlRegion = parseRegionAttributes(xmlParser, cellRows, ttsExtent, globalStyles); if (ttmlRegion != null) { globalRegions.put(ttmlRegion.id, ttmlRegion); } @@ -350,7 +350,8 @@ public final class TtmlParser implements SubtitleParser { */ @Nullable private static TtmlRegion parseRegionAttributes( - XmlPullParser xmlParser, int cellRows, @Nullable TtsExtent ttsExtent) { + XmlPullParser xmlParser, int cellRows, @Nullable TtsExtent ttsExtent, + Map globalStyles) { @Nullable String regionId = XmlPullParserUtil.getAttributeValue(xmlParser, TtmlNode.ATTR_ID); if (regionId == null) { return null; @@ -361,6 +362,15 @@ public final class TtmlParser implements SubtitleParser { @Nullable String regionOrigin = XmlPullParserUtil.getAttributeValue(xmlParser, TtmlNode.ATTR_TTS_ORIGIN); + if (regionOrigin == null) { + String styleId = XmlPullParserUtil.getAttributeValue(xmlParser, TtmlNode.ATTR_STYLE); + if (styleId != null) { + TtmlStyle style = globalStyles.get(styleId); + if (style != null) { + regionOrigin = style.getOrigin(); + } + } + } if (regionOrigin != null) { Matcher originPercentageMatcher = PERCENTAGE_COORDINATES.matcher(regionOrigin); Matcher originPixelMatcher = PIXEL_COORDINATES.matcher(regionOrigin); @@ -406,6 +416,15 @@ public final class TtmlParser implements SubtitleParser { float height; @Nullable String regionExtent = XmlPullParserUtil.getAttributeValue(xmlParser, TtmlNode.ATTR_TTS_EXTENT); + if (regionExtent == null) { + String styleId = XmlPullParserUtil.getAttributeValue(xmlParser, TtmlNode.ATTR_STYLE); + if (styleId != null) { + TtmlStyle style = globalStyles.get(styleId); + if (style != null) { + regionExtent = style.getExtent(); + } + } + } if (regionExtent != null) { Matcher extentPercentageMatcher = PERCENTAGE_COORDINATES.matcher(regionExtent); Matcher extentPixelMatcher = PIXEL_COORDINATES.matcher(regionExtent); @@ -626,6 +645,12 @@ public final class TtmlParser implements SubtitleParser { case TtmlNode.ATTR_TTS_SHEAR: style = createIfNull(style).setShearPercentage(parseShear(attributeValue)); break; + case TtmlNode.ATTR_TTS_ORIGIN: + style = createIfNull(style).setOrigin(attributeValue); + break; + case TtmlNode.ATTR_TTS_EXTENT: + style = createIfNull(style).setExtent(attributeValue); + break; default: // ignore break; diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/text/ttml/TtmlStyle.java b/libraries/extractor/src/main/java/androidx/media3/extractor/text/ttml/TtmlStyle.java index 1cb59ae211..b3b29bdf24 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/text/ttml/TtmlStyle.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/text/ttml/TtmlStyle.java @@ -96,6 +96,8 @@ import java.lang.annotation.Target; private @OptionalBoolean int textCombine; @Nullable private TextEmphasis textEmphasis; private float shearPercentage; + @Nullable private String origin; + @Nullable private String extent; public TtmlStyle() { linethrough = UNSPECIFIED; @@ -277,6 +279,12 @@ import java.lang.annotation.Target; if (shearPercentage == UNSPECIFIED_SHEAR) { shearPercentage = ancestor.shearPercentage; } + if (origin == null) { + origin = ancestor.origin; + } + if (extent == null) { + extent = ancestor.extent; + } // attributes not inherited as of http://www.w3.org/TR/ttml1/ if (chaining && !hasBackgroundColor && ancestor.hasBackgroundColor) { setBackgroundColor(ancestor.backgroundColor); @@ -382,4 +390,26 @@ import java.lang.annotation.Target; public float getFontSize() { return fontSize; } + + @CanIgnoreReturnValue + public TtmlStyle setOrigin(@Nullable String origin) { + this.origin = origin; + return this; + } + + @Nullable + public String getOrigin() { + return origin; + } + + @CanIgnoreReturnValue + public TtmlStyle setExtent(@Nullable String extent) { + this.extent = extent; + return this; + } + + @Nullable + public String getExtent() { + return extent; + } }