In my last blogging I discussed the research I’d made into forcing XML-formatted plain text to being DOM-parsed. This became an essential task for the BBB Video Player as TTXT subtitle files are just that: XML-structured documents which were coming across as plain text. This could be fixed server-side by associating extension “ttxt” with “text/xml”, but given our work with Video.js I went for the client-side approach to ensure TTXT subtitling would always be possible and extended Video.js to ensure the data will be structured into an XML DOM tree client-side. I’ve posted a demo and my implementation code below:
function XHRFormatter(request, type) {
var canForce = request.overrideMimeType;
var forceToXML = canForce && type === 'ttxt';
var isXml = forceToXML || type === 'xml';
if (forceToXML) {
request.overrideMimeType('text/xml');
}
return {
// Select elements from aRef element tree based on expression aExpr
// aExpr is a query string (delimiter to split on for text, XPath for xml)
select: function(aRef, aExpr) {
if (isXml) {
var xpe = aRef.ownerDocument || aRef;
if (xpe.createNSResolver && xpe.evaluate) {
// Thanks to https://developer.mozilla.org/en/Using_XPath
var nsResolver = xpe.createNSResolver(xpe.documentElement);
var result = xpe.evaluate(aExpr, aRef, nsResolver, 0, null);
var found = [];
var res;
while (res = result.iterateNext())
found.push(res);
return found;
} else if (xpe.selectNodes) { // IE
return xpe.selectNodes(aExpr);
}
} else if (isText) {
return aRef.split(aExpr);
}
},
getType: function() { return type; },
format: function(str) {
if (isXml) { // Return str as xml
// Mime type has been overridden as XML or is XML by default
if (canForce || !forceToXML) {
return request.responseXML;
// IE, mime type not overridden, must parse into XML
} else if (typeof ActiveXObject !== 'undefined') {
var doc = new ActiveXObject("MSXML.DomDocument");
doc.loadXML(str);
return doc;
} else {
throw new Error("Can not process as XML!");
}
} else if (isText) {
return request.responseText;
}
}
}
}
My goal was to decouple the (potentially browser-specific) code that formats and selects data from xml from the code that works with that data. In use, it could work like this:
var request = new XmlHttpRequest(); var formatter = XHRFormatter(request, 'ttxt'); ... // Further work here .. request.send(); var nodeTree = formatter.format(request.responseText); var wantedNodes = formatter.select(nodeTree, "//My/XPath/Query/"); ...
I’ve recently submitted a patch back to the Video.js team integrating this code into their player. Keep an eye out for their future releases, it may have official support for multiple subtitling formats 😉

Leave a Reply