@Override public Subtitle parse(InputStream inputStream) throws IOException { try { XmlPullParser xmlParser = xmlParserFactory.newPullParser(); Map<String, TtmlStyle> globalStyles = new HashMap<>(); xmlParser.setInput(inputStream, null); TtmlSubtitle ttmlSubtitle = null; LinkedList<TtmlNode> nodeStack = new LinkedList<>(); int unsupportedNodeDepth = 0; int eventType = xmlParser.getEventType(); while (eventType != XmlPullParser.END_DOCUMENT) { TtmlNode parent = nodeStack.peekLast(); if (unsupportedNodeDepth == 0) { String name = xmlParser.getName(); if (eventType == XmlPullParser.START_TAG) { if (!isSupportedTag(name)) { Log.i(TAG, "Ignoring unsupported tag: " + xmlParser.getName()); unsupportedNodeDepth++; } else if (TtmlNode.TAG_HEAD.equals(name)) { parseHeader(xmlParser, globalStyles); } else { try { TtmlNode node = parseNode(xmlParser, parent); nodeStack.addLast(node); if (parent != null) { parent.addChild(node); } } catch (ParserException e) { if (strictParsing) { throw e; } else { Log.w(TAG, "Suppressing parser error", e); // Treat the node (and by extension, all of its children) as unsupported. unsupportedNodeDepth++; } } } } else if (eventType == XmlPullParser.TEXT) { parent.addChild(TtmlNode.buildTextNode(xmlParser.getText())); } else if (eventType == XmlPullParser.END_TAG) { if (xmlParser.getName().equals(TtmlNode.TAG_TT)) { ttmlSubtitle = new TtmlSubtitle(nodeStack.getLast(), globalStyles); } nodeStack.removeLast(); } } else { if (eventType == XmlPullParser.START_TAG) { unsupportedNodeDepth++; } else if (eventType == XmlPullParser.END_TAG) { unsupportedNodeDepth--; } } xmlParser.next(); eventType = xmlParser.getEventType(); } return ttmlSubtitle; } catch (XmlPullParserException xppe) { throw new ParserException("Unable to parse source", xppe); } }